对于 A 帧(和 anime.js),如何在动画中途更改动画速度?
For A-Frame (and anime.js), how do I change the animation speed mid-animation?
我正在研究一个使用 A-Frame 的例子。
场景由一个浮动对象(在两个不可见边界之间反弹)组成。
这是使用如下所示的动画混合实现的:
<a-mixin id="bounceX"
animation__bouncex="property:object3D.position.x; to:5; dir:normal;
loop:1; dur:3600; easing:linear;
startEvents:bouncex;pauseEvents:holdx;resumeEvents:bounceOnx"
></a-mixin>
我通过监听animationcomplete事件和设置来反转方向:
mixin.data.to *= -1;
el.emit(...)
现在,对于与浮动对象的交互,当鼠标光标悬停在对象上时,它应该减速,如果用户点击它,它应该停止。如果鼠标光标没有点击就离开了对象,它应该以原来的速度恢复移动。
我能够捕获 mouseenter、click 和 mouseleave 事件并将它们简单地记录到控制台。
代码的问题部分是:如何在飞行中更新动画以减慢速度?
我尝试更新 el.components.animation__bouncex.config 和 el.components.animation__bouncex.data 中的值 (duration,dur) 但没有成功。
这不起作用,在动画完成之前速度不会改变。
AFrame>components>animation.js提到了以下内容:
* The component manually controls the tick by setting `autoplay: false` on anime.js and
* manually * calling `animation.tick()` in the tick handler. To pause or resume, we toggle a
* boolean * flag * `isAnimationPlaying`.
您可以使用我的 animation-speed component (example) 来提供速度系数:
// speed up <a-box animation="" by 2x
element.setAttribute("animation-speed", "multiplier", 2);
由于anime.js is updated with the 'time passed since last renderloop',该组件只是添加了一个乘数。
如果是简单的动画,您可以创建自定义组件。在tick(t, dt)
函数中可以写一个简单的运动方程:
// called on each render loop
tick: function(t, dt) {
// grab the underlying three.js objects position
const pos = this.el.object3D.position
// position = speed * time
pos.x = this.speed * dt; // this.speed can be set anywhere in the component
}
如果我们为对象添加一些边界 'bounce' 并改变速度,我们最终会得到这样的结果:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
// component declaration
AFRAME.registerComponent("foo", {
init: function() {
this.xMax = 4; // x upper boundary
this.xMin = -4; // x lower boundary
this.speed = 0.005; // base movement speed
this.dir = 1; // animation direction
// hovering over the sphere will change the animation speed
const sphere = document.querySelector("a-sphere")
this.speedUp = this.changeSpeed.bind(this, 0.01);
this.slowDown = this.changeSpeed.bind(this, 0.005);
sphere.addEventListener("mouseenter", this.speedUp) // hover
sphere.addEventListener("mouseleave", this.slowDown) // leave
},
changeSpeed(spd) {
this.speed = spd;
},
tick: function(t, dt) {
// grab the underlying THREE.js position
const pos = this.el.object3D.position
// check if the object has passed the boundaries - if so, change the direction
if (pos.x > this.xMax) this.dir = -1;
if (pos.x < this.xMin) this.dir = 1;
// update the position using the direction and speed
pos.x += this.dir * this.speed * dt;
}
})
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-sphere">
<a-box foo position="-2 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-text color="black" position="-1.75 2 -3" value="hover to speed up"></a-text>
<a-sphere position="-1 1.5 -3" radius="0.25" color="#EF2D5E"></a-sphere>
</a-scene>
我正在研究一个使用 A-Frame 的例子。 场景由一个浮动对象(在两个不可见边界之间反弹)组成。 这是使用如下所示的动画混合实现的:
<a-mixin id="bounceX"
animation__bouncex="property:object3D.position.x; to:5; dir:normal;
loop:1; dur:3600; easing:linear;
startEvents:bouncex;pauseEvents:holdx;resumeEvents:bounceOnx"
></a-mixin>
我通过监听animationcomplete事件和设置来反转方向:
mixin.data.to *= -1;
el.emit(...)
现在,对于与浮动对象的交互,当鼠标光标悬停在对象上时,它应该减速,如果用户点击它,它应该停止。如果鼠标光标没有点击就离开了对象,它应该以原来的速度恢复移动。 我能够捕获 mouseenter、click 和 mouseleave 事件并将它们简单地记录到控制台。
代码的问题部分是:如何在飞行中更新动画以减慢速度? 我尝试更新 el.components.animation__bouncex.config 和 el.components.animation__bouncex.data 中的值 (duration,dur) 但没有成功。 这不起作用,在动画完成之前速度不会改变。
AFrame>components>animation.js提到了以下内容:
* The component manually controls the tick by setting `autoplay: false` on anime.js and
* manually * calling `animation.tick()` in the tick handler. To pause or resume, we toggle a
* boolean * flag * `isAnimationPlaying`.
您可以使用我的 animation-speed component (example) 来提供速度系数:
// speed up <a-box animation="" by 2x
element.setAttribute("animation-speed", "multiplier", 2);
由于anime.js is updated with the 'time passed since last renderloop',该组件只是添加了一个乘数。
如果是简单的动画,您可以创建自定义组件。在tick(t, dt)
函数中可以写一个简单的运动方程:
// called on each render loop
tick: function(t, dt) {
// grab the underlying three.js objects position
const pos = this.el.object3D.position
// position = speed * time
pos.x = this.speed * dt; // this.speed can be set anywhere in the component
}
如果我们为对象添加一些边界 'bounce' 并改变速度,我们最终会得到这样的结果:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
// component declaration
AFRAME.registerComponent("foo", {
init: function() {
this.xMax = 4; // x upper boundary
this.xMin = -4; // x lower boundary
this.speed = 0.005; // base movement speed
this.dir = 1; // animation direction
// hovering over the sphere will change the animation speed
const sphere = document.querySelector("a-sphere")
this.speedUp = this.changeSpeed.bind(this, 0.01);
this.slowDown = this.changeSpeed.bind(this, 0.005);
sphere.addEventListener("mouseenter", this.speedUp) // hover
sphere.addEventListener("mouseleave", this.slowDown) // leave
},
changeSpeed(spd) {
this.speed = spd;
},
tick: function(t, dt) {
// grab the underlying THREE.js position
const pos = this.el.object3D.position
// check if the object has passed the boundaries - if so, change the direction
if (pos.x > this.xMax) this.dir = -1;
if (pos.x < this.xMin) this.dir = 1;
// update the position using the direction and speed
pos.x += this.dir * this.speed * dt;
}
})
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-sphere">
<a-box foo position="-2 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-text color="black" position="-1.75 2 -3" value="hover to speed up"></a-text>
<a-sphere position="-1 1.5 -3" radius="0.25" color="#EF2D5E"></a-sphere>
</a-scene>