【问题标题】:How to run a requestAnimationFrame animation for a certain duration?如何在一定时间内运行 requestAnimationFrame 动画?
【发布时间】:2022-01-12 06:54:42
【问题描述】:

我有以下功能,通过调整每个“滴答”的样式,将某些元素“向上”滚动到视野之外:

const incr = 1;
let moved = 0;

function changeHeight( children, duration, setTop) {
  // duration = 1500
  const height = children.clientHeight; // in this case, 166px

  let moved = 0; 
  const slideUp = function (timestamp) {
    // we're done if the amount moved is larger than height
    if ( moved < height ) { 
      children.style.top = `${ setTop( moved, height ) }px`;
      moved = moved + incr // move by some amount

      requestAnimationFrame(slideUp) 

    } else {
      // reset
      moved = 0;
    }
  };

  // start sliding
  slideUp();
}

如果requestAnimationFrame 大约每 16 毫秒触发一次,我想使用duration 来指示动画将运行多长时间,所以公式似乎是height * 16.5 / duration

我对@9​​87654325@ 感到困惑 - 为什么每次滴答的时间不是恒定的?我想使用由requestAnimationFrame 生成的timestamp,但前几个周期花费的时间比平均约16.5

16.5 在不同的机器或屏幕上看起来会有所不同吗?

如何使高度变化完全按照指定的时间量进行?

【问题讨论】:

    标签: javascript animation requestanimationframe


    【解决方案1】:

    您想要的称为增量时间。 公式为Math.min((now - start) / duration, 1) * final_amount

    使用此增量时间,您无需关心间隔触发的频率,每一步都会呈现“它应该在哪里”。

    至于你的问题,

    为什么每次滴答的时间不是恒定的

    当然是因为浏览器在第一帧有很多事情要做,而不能在 16.7 毫秒的帧内完成所有事情。因此,它会将您的回调移动到稍后执行,如果压力过大,甚至可能会跳帧。

    16.5 在不同的机器或屏幕上看起来会有所不同吗?

    是的,requestAnimationFrame 基本上会尝试跟随显示器的刷新率。所以在 60Hz 的显示器上,每帧确实有 16.7ms,但在 120Hz 的显示器上,你只有一半。

    如何使高度变化完全按照指定的时间量进行?

    使用增量时间:

    const elem = document.querySelector("div");
    let moved = 0;
    changeHeight(elem, 200, 5000);
    
    function changeHeight(elem, height, duration) {
      const start = performance.now();
      const step = function () {
        const now = performance.now();
        const delta = Math.min((now - start) / duration, 1);
        elem.style.height = (delta * height) + "px";
        if (delta < 1) {
          requestAnimationFrame(step);
        }
      };
      step();
    }
    div { width: 50px; background: green; }
    &lt;div&gt;&lt;/div&gt;

    【讨论】:

    • 谢谢。 requestAnimationFrame 很混乱,感谢您抽出宝贵时间。
    • 跟进...它也会“展开”到正确的高度?
    • 您可以将其存储在 js 变量中,甚至可以存储在元素的 .dataset
    猜你喜欢
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 2020-03-02
    • 2015-03-14
    • 2016-06-12
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多