aframe.io:实体在父级更改时的动画位置
aframe.io: Animate position of entity on parent change
当将实体附加到场景中的另一个父项时,我正在尝试为实体的平滑移动设置动画。
有一些插件可以为位置本身的变化设置动画,但当位置保持不变但父级正在改变时则不会。
我需要这个,因为我有不同的 "spots" 定义,实体可以在哪里。现在我想将实体放入这些位置之一,这样我就不必计算实体的新位置。没有动画,这个概念就完美了。
我当前的动画分辨率如下:
- 遍历实体的所有当前父代并对这些元素的位置向量求和
- 遍历所有父元素和新父元素本身并对这些元素的位置向量求和
- 将两个计算出的向量相减
- 将实体附加到新的父级并添加一个动画
from
= 生成的偏移向量和 to="0 0 0"
有效,但在某些帧中元素会闪烁,因为它首先附加到新的父级(position="0 0 0"
,所以在新的父级上),它被绘制,然后动画以from
将其置于旧位置并将其移回 "0 0 0"
。
我构建了一个jsfiddle,它显示了问题:https://jsfiddle.net/fshqghxt/
有人可以帮我解决这个问题吗?我也对完全不同的概念持开放态度。提前致谢!
这有帮助吗? (基于组件的方法)
HTML:
<a-scene>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-box position="-1 0.5 -3" width="1" height="1" depth="1" color="#4CC3D9" animation="property: position; dir: alternate; loop: true; dur: 1000; to: -1 3 -3; startEvents: moveBox"></a-box>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
JS:
document.querySelector('a-box').emit('moveBox');
我今天想出了两个解决方案,效果不错的是:
住在aframe.io
停留在 aframe.io 时,这个新概念工作正常:
* 克隆当前位置的元素
* 隐藏原始元素
* 将其追加到新的父元素,并将其位置设置为偏移位置以匹配克隆的元素
* 显示原始元素
* 隐藏克隆的元素
* 开始动画
这样,在克隆的帮助下就不会出现闪烁了。
function animateParentChange(element, newParent) {
var newParentParents = newParent.add(newParent.parentsUntil('a-scene'));
var elementParents = element.parentsUntil('a-scene');
var oldVector = sumVectors(elementParents);
var newVector = sumVectors(newParentParents);
var diff = oldVector.sub(newVector)
var newPosition = vectorToPosition(diff);
console.log("newPosition", newPosition);
$(element).find('a-animate').remove();
var tempElement = $(element).clone().appendTo(element.parent());
$(element).attr('visible', 'false').appendTo(newParent).attr('position', diff.toArray().join(' '));
$(element).append('<a-animation attribute="position" dur="1000" fill="forwards" from="' + diff.toArray().join(' ') + '" to="0 0 0"></a-animation>');
$(element).attr('visible', true);
tempElement.remove();
}
Fiddle: https://jsfiddle.net/5uc1hn63/
切换到纯three.js
但我最终真正做的是切换到纯 three.js,用 javascript 生成的对象替换所有 aframe.io 东西。
这样我就可以完全控制渲染的时间。在使用 aframe.io 时,我发现它非常容易使用(与 three.js 相比),但不如我需要的那么灵活。
我接受必须编写更多行代码,但为了灵活性我认为没关系。
最后大家自己考虑一下,什么对自己更重要
当将实体附加到场景中的另一个父项时,我正在尝试为实体的平滑移动设置动画。
有一些插件可以为位置本身的变化设置动画,但当位置保持不变但父级正在改变时则不会。
我需要这个,因为我有不同的 "spots" 定义,实体可以在哪里。现在我想将实体放入这些位置之一,这样我就不必计算实体的新位置。没有动画,这个概念就完美了。
我当前的动画分辨率如下:
- 遍历实体的所有当前父代并对这些元素的位置向量求和
- 遍历所有父元素和新父元素本身并对这些元素的位置向量求和
- 将两个计算出的向量相减
- 将实体附加到新的父级并添加一个动画
from
= 生成的偏移向量和to="0 0 0"
有效,但在某些帧中元素会闪烁,因为它首先附加到新的父级(position="0 0 0"
,所以在新的父级上),它被绘制,然后动画以from
将其置于旧位置并将其移回 "0 0 0"
。
我构建了一个jsfiddle,它显示了问题:https://jsfiddle.net/fshqghxt/
有人可以帮我解决这个问题吗?我也对完全不同的概念持开放态度。提前致谢!
这有帮助吗? (基于组件的方法)
HTML:
<a-scene>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-box position="-1 0.5 -3" width="1" height="1" depth="1" color="#4CC3D9" animation="property: position; dir: alternate; loop: true; dur: 1000; to: -1 3 -3; startEvents: moveBox"></a-box>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
JS:
document.querySelector('a-box').emit('moveBox');
我今天想出了两个解决方案,效果不错的是:
住在aframe.io
停留在 aframe.io 时,这个新概念工作正常: * 克隆当前位置的元素 * 隐藏原始元素 * 将其追加到新的父元素,并将其位置设置为偏移位置以匹配克隆的元素 * 显示原始元素 * 隐藏克隆的元素 * 开始动画
这样,在克隆的帮助下就不会出现闪烁了。
function animateParentChange(element, newParent) {
var newParentParents = newParent.add(newParent.parentsUntil('a-scene'));
var elementParents = element.parentsUntil('a-scene');
var oldVector = sumVectors(elementParents);
var newVector = sumVectors(newParentParents);
var diff = oldVector.sub(newVector)
var newPosition = vectorToPosition(diff);
console.log("newPosition", newPosition);
$(element).find('a-animate').remove();
var tempElement = $(element).clone().appendTo(element.parent());
$(element).attr('visible', 'false').appendTo(newParent).attr('position', diff.toArray().join(' '));
$(element).append('<a-animation attribute="position" dur="1000" fill="forwards" from="' + diff.toArray().join(' ') + '" to="0 0 0"></a-animation>');
$(element).attr('visible', true);
tempElement.remove();
}
Fiddle: https://jsfiddle.net/5uc1hn63/
切换到纯three.js
但我最终真正做的是切换到纯 three.js,用 javascript 生成的对象替换所有 aframe.io 东西。
这样我就可以完全控制渲染的时间。在使用 aframe.io 时,我发现它非常容易使用(与 three.js 相比),但不如我需要的那么灵活。
我接受必须编写更多行代码,但为了灵活性我认为没关系。
最后大家自己考虑一下,什么对自己更重要