我可以用一个动画设置多个实体的不透明度并为其设置动画吗?
Can I set and animate the opacity of multiple entities with one animation?
我有一个实体,我想像这样设置它:
<a-entity id="ui" opacity="0" position="0 -10 0">
<a-plane class="menu-pane" position="0 0 -60" opacity="0" color="blue" rotation="0 0 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="50 0 -40" opacity="0" color="blue" rotation="0 -50 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="-50 0 -40" opacity="0" color="blue" rotation="0 50 0" height="50" width="30"></a-plane>
<a-animation begin="mobileMenuOpen" attribute="position" dur="550" fill="both" to="0 0 0"></a-animation>
<a-animation begin="mobileMenuOpen" attribute="opacity" dur="550" fill="both" to="1"></a-animation>
</a-entity>
所以我可以在 #ui
上发出 mobileMenuOpen
事件并让实体及其所有平面淡入并向上移动。但是,#ui
上的 opacity="0"
不会影响子元素,我不确定动画是否会影响。我怎样才能达到我想要的效果?
内置动画框架不能应用于多个实体,并且(afaik)设置父级的不透明度不会级联到它的子级。我要做的是制作您自己的 opacity
组件版本,它确实适用于儿童。我们称它为 group-opacity
。这是一个原始版本(可能不适用于从建模工具导出的模型),但是 –
AFRAME.registerComponent('group-opacity', {
schema: {opacity: {default: 1.0}},
update: function () {
var opacity = this.data.opacity;
var children = [].slice.call(this.el.children);
children
.filter(function (child) { return child.hasAttribute('opacity'); })
.forEach(function (child) {
child.setAttribute('opacity', opacity);
});
}
});
HTML:
<a-entity id="ui" group-opacity="opacity: 0" position="0 -10 0">
<a-plane class="menu-pane" position="0 0 -60" opacity="0" color="blue" rotation="0 0 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="50 0 -40" opacity="0" color="blue" rotation="0 -50 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="-50 0 -40" opacity="0" color="blue" rotation="0 50 0" height="50" width="30"></a-plane>
<a-animation begin="mobileMenuOpen" attribute="position" dur="550" fill="both" to="0 0 0"></a-animation>
<a-animation begin="mobileMenuOpen" attribute="group-opacity.opacity" dur="550" fill="both" to="1"></a-animation>
</a-entity>
位置 确实 从父级级联到子级,因此不需要解决方法 属性。
编辑:好的,我认为以上应该可行,但出现了一些没有多大意义的错误。可能是我的代码,或者关于动画布线的东西。无论如何,正如@ngokevin 所说,对动画进行硬编码可能是目前最好的选择。快速入门示例:
AFRAME.registerComponent('group-opacity', {
tick: function (t) {
var opacity = (Math.sin(t / 1000) + 1) / 2;
this.el.object3D.traverse(function (o) {
if (o.material) {
o.material.opacity = opacity;
}
});
}
});
请注意,在这种情况下您根本不需要 <a-animation/>
。
我打算制作一个可以混合到实体中的动画组件。
但是现在,您需要手动执行更多操作。这意味着要么直接将 tween.js (https://github.com/tweenjs/) 与 AFRAME.TWEEN 一起使用,要么复制并粘贴动画并进行处理以在所有实体上触发事件。
菜单窗格的位置是相对于父实体的,因此移动父实体也会移动所有子实体。这部分很简单。
所有菜单窗格的不透明度都可以使用 D3 的 "selectAll":
进行简洁的动画处理
// Increase opacity for all menu-panes individually
var menuPanes = d3.selectAll('.menu-pane');
menuPanes.transition()
.duration(1000)
.attr('opacity', '1');
查看上面的 link 以获得完整示例。它展示了如何 select 父 UI 元素、附加自定义 'mobileMenuOpen' 事件、设置转换函数以及触发自定义事件。
我有一个实体,我想像这样设置它:
<a-entity id="ui" opacity="0" position="0 -10 0">
<a-plane class="menu-pane" position="0 0 -60" opacity="0" color="blue" rotation="0 0 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="50 0 -40" opacity="0" color="blue" rotation="0 -50 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="-50 0 -40" opacity="0" color="blue" rotation="0 50 0" height="50" width="30"></a-plane>
<a-animation begin="mobileMenuOpen" attribute="position" dur="550" fill="both" to="0 0 0"></a-animation>
<a-animation begin="mobileMenuOpen" attribute="opacity" dur="550" fill="both" to="1"></a-animation>
</a-entity>
所以我可以在 #ui
上发出 mobileMenuOpen
事件并让实体及其所有平面淡入并向上移动。但是,#ui
上的 opacity="0"
不会影响子元素,我不确定动画是否会影响。我怎样才能达到我想要的效果?
内置动画框架不能应用于多个实体,并且(afaik)设置父级的不透明度不会级联到它的子级。我要做的是制作您自己的 opacity
组件版本,它确实适用于儿童。我们称它为 group-opacity
。这是一个原始版本(可能不适用于从建模工具导出的模型),但是 –
AFRAME.registerComponent('group-opacity', {
schema: {opacity: {default: 1.0}},
update: function () {
var opacity = this.data.opacity;
var children = [].slice.call(this.el.children);
children
.filter(function (child) { return child.hasAttribute('opacity'); })
.forEach(function (child) {
child.setAttribute('opacity', opacity);
});
}
});
HTML:
<a-entity id="ui" group-opacity="opacity: 0" position="0 -10 0">
<a-plane class="menu-pane" position="0 0 -60" opacity="0" color="blue" rotation="0 0 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="50 0 -40" opacity="0" color="blue" rotation="0 -50 0" height="50" width="30"></a-plane>
<a-plane class="menu-pane" position="-50 0 -40" opacity="0" color="blue" rotation="0 50 0" height="50" width="30"></a-plane>
<a-animation begin="mobileMenuOpen" attribute="position" dur="550" fill="both" to="0 0 0"></a-animation>
<a-animation begin="mobileMenuOpen" attribute="group-opacity.opacity" dur="550" fill="both" to="1"></a-animation>
</a-entity>
位置 确实 从父级级联到子级,因此不需要解决方法 属性。
编辑:好的,我认为以上应该可行,但出现了一些没有多大意义的错误。可能是我的代码,或者关于动画布线的东西。无论如何,正如@ngokevin 所说,对动画进行硬编码可能是目前最好的选择。快速入门示例:
AFRAME.registerComponent('group-opacity', {
tick: function (t) {
var opacity = (Math.sin(t / 1000) + 1) / 2;
this.el.object3D.traverse(function (o) {
if (o.material) {
o.material.opacity = opacity;
}
});
}
});
请注意,在这种情况下您根本不需要 <a-animation/>
。
我打算制作一个可以混合到实体中的动画组件。
但是现在,您需要手动执行更多操作。这意味着要么直接将 tween.js (https://github.com/tweenjs/) 与 AFRAME.TWEEN 一起使用,要么复制并粘贴动画并进行处理以在所有实体上触发事件。
菜单窗格的位置是相对于父实体的,因此移动父实体也会移动所有子实体。这部分很简单。
所有菜单窗格的不透明度都可以使用 D3 的 "selectAll":
进行简洁的动画处理 // Increase opacity for all menu-panes individually
var menuPanes = d3.selectAll('.menu-pane');
menuPanes.transition()
.duration(1000)
.attr('opacity', '1');
查看上面的 link 以获得完整示例。它展示了如何 select 父 UI 元素、附加自定义 'mobileMenuOpen' 事件、设置转换函数以及触发自定义事件。