JavaScript 旋转动画更改速度

4
我试图制作一个旋转块,其旋转速度由 <input type="range" 控制。问题在于我找不到不会在速度更新时重新启动动画的解决方案。
我尝试了三种变体:
  • 通过JS直接设置CSS动画速度。— 重新启动动画;

  • jQuery的 animate — 无法与变换一起使用;

  • anime.js — 它有用于速度更改的方法,但它也会重新启动动画(或只是使块跳跃,不清楚)

哪种方法可以通过JS创建平滑变化的动画?

let block = anime({
   targets: '#transforms .block',
   rotateY: '360',
   easing: 'linear',
   loop: true,
   duration: 1000,
});


var el = document.querySelectorAll('#range')[0];

el.addEventListener('change', function() {  
  // console.log(value);
  // console.log(pos);
  var value = this.value;
  anime.speed = value/20;
  // console.log(block);
})
.block {
  width: 500px;
  height: 300px;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.js"></script>
<div id="transforms">
  <div class="block"></div>
</div>

<input id="range" type="range" min="0" max="20" step="1" value="10">

anime.js示例代码在Codepen上


我也在尝试做同样的事情。使用Velocity.js通过循环多次发出动画命令,我已经接近成功了。唯一的问题是改变速度和实际生效之间存在延迟。至少动画是一致的,可能是因为只有在完整的360度旋转后才调整速度。Velocity(rotor, { rotateZ: 360, }, {duration: 5000, loop: true, easing: "linear"}); Velocity(rotor, { rotateZ: 360, }, {duration: 1000, loop: true, easing: "linear"}); - partofthething
2个回答

0
使用velocity-animate库,您可以这样做一个技巧:
Velocity.animate(this.yourElement, {
  rotateZ: `${angle}deg`,
  duration: yourSpeed

})


我应该将它放在“change”回调函数中吗?从哪里获取“angle”?为什么要将其作为变量放置? - Maria Piaredryj
旋转方向和距离(您的元素应该旋转多少度)需要角度。您不需要将其作为变量放置。我之所以这样写只是举例说明。 - Oleksandr Oleksiv
我认为当循环开始时,Velocity的“值函数”不会得到更新。根据文档: 属性值可以传递函数。这些函数每个元素调用一次 - 在元素开始动画之前立即调用。因此,在循环/反转时,这些函数不会被重复调用。http://velocityjs.org/ - partofthething

0

我猜你需要在动画周期结束时触发速度变化。然而,使用这个包,我无法将transitionend事件监听器附加到任何两个div中。它不会触发。因此,深入研究这个库,我认为您可以通过向anime选项对象添加一个run属性来实现类似的任务,该属性以函数作为值,并通过传递进度参数多次调用它。一旦这个进度参数达到100,如果速度已经改变(newSpeed !== void 0),我们就可以进行速度变化操作。

不要让void 0困扰你。它只是一个完美的undefined值,我喜欢在比较未定义的值时使用它。

let block = anime({
   targets : '#transforms .block',
   rotateY : '360',
   easing  : 'linear',
   loop    : true,
   duration: 1000,
   run     : anim => anim.progress === 100 && newSpeed !== void 0 && (anime.speed = newSpeed, newSpeed = void 0)
});

var range    = document.getElementById('range'),
    newSpeed = void 0;  // perfect undefined

anime.speed = range.value/20;
range.addEventListener('change', function(e) {
                                   newSpeed = e.target.value/20;
                                 });
.block {
  width: 500px;
  height: 300px;
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.js"></script>
<div id="transforms">
  <div class="block"></div>
</div>

<input id="range" type="range" min="0" max="20" step="1" value="10">


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接