【问题标题】:JS rotate animation change speedJS旋转动画变化速度
【发布时间】:2018-04-24 14:32:05
【问题描述】:

我尝试制作一个旋转块,其旋转速度由<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 示例代码On Codepen

【问题讨论】:

  • 我也在尝试这样做。通过循环多次发出 animate 命令,我与 Velocity.js 非常接近。唯一的问题是在更改速度和实际生效之间存在延迟。动画至少是一致的,可能是因为它只是在完成 360 度旋转后才调整速度。 Velocity(rotor, { rotateZ: 360, }, {duration: 5000, loop: true, easing: "linear"});Velocity(rotor, { rotateZ: 360, }, {duration: 1000, loop: true, easing: "linear"});

标签: javascript css anime.js


【解决方案1】:

使用velocity-animate 库,您可以这样做:

Velocity.animate(this.yourElement, {
  rotateZ: `${angle}deg`,
  duration: yourSpeed

})

【讨论】:

  • 我应该把它放到change回调吗?去哪儿angle?为什么我要把它作为一个变量?
  • 旋转方向和距离需要角度(你的元素应该旋转多少度)。你不需要把 is 作为变量。我这样写只是为了举例
  • 我不认为 Velocity“价值函数”得到更新,循环开始了。来自文档:Property values can be passed functions. These functions are called once per element — immediately before the element begins animating. Therefore, when looping/reversing, the functions are not repeatedly re-called. velocityjs.org
【解决方案2】:

我想在动画循环结束时触发速度变化是你需要的。然而,有了这个包,我无法将transitionend 事件侦听器附加到两个 div 中的任何一个。它不会触发。因此,深入研究这个库,我想您可以通过将run 属性附加到anime 选项对象来实现类似的任务,该对象将函数作为值并通过传递进度参数多次调用它。一旦这个进度参数为 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">

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2017-11-07
    • 1970-01-01
    • 2012-10-30
    • 2015-10-07
    相关资源
    最近更新 更多