gpt4 book ai didi

javascript - 如何独立于刷新率计时 requestAnimationFrame()

转载 作者:行者123 更新时间:2023-11-30 14:58:50 30 4
gpt4 key购买 nike

我有一种情况,我想在 1 秒内将 600px 宽的 div 的宽度设置为 0px。为此,我可以使用 requestAnimationFrame()。但我真的不能 100% 确定动画是否需要 1 秒。

它看起来像这样:

let width = 600;
let animation;
function animateWidth(){
if(width <= 0){
window.cancelAnimationFrame();
}else{
width -= 10; // (600px/60fps)
}
document.getElementById('id1').setAttribute('width', width);
animation = window.requestAnimationFrame(animateWidth);
}
animation = window.requestAnimationFrame(animateWidth);

问题是,当设备具有不同的 fps 时,它会影响动画的持续时间(在 30 fps 时需要 2 秒,在 60 fps 时需要 1 秒)。我想确保动画的持续时间始终为一秒。如果 fps-rate 不同,我想根据持续时间更改宽度的新值(因此以 30 fps 设置动画我们将每步更改宽度 20 (600px/30fps))。

  • 有什么方法可以在使用 requestAnimationFrame 时实现这一点?如果我能得到帧之间的平均间隔或我认为可行的 fps。
  • 我是不是在担心一些并不是什么大问题的事情?
  • 我在不同设备(移动设备、个人电脑、平板电脑等)上预期的 fps 是多少?

文档:https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame

最佳答案

requestAnimationFrame 将页面加载后的时间传递给回调,例如

const startValue = 600;
const endValue = 0;

// return a value between start and end as l goes from 0 to 1
function lerp(start, end, l) {
return start + (end - start) * l;
}

const startTime = performance.now();
const durationInSeconds = 1;
const element = document.getElementById('id1');

function animateWidth(now) {
const timeSinceStartInSeconds = (now - startTime) * 0.001;

// l goes from 0 to 1 over durationInSeconds;
const l = Math.min(timeSinceStartInSeconds / durationInSeconds, 1);

element.setAttribute('width', lerp(startValue, endValue, l));

// if we haven't finished request another animation frame
if (l < 1) {
requestAnimationFrame(animateWidth);
}
}
requestAnimationFrame(animateWidth);
#id1 { background: red; }
<canvas id="id1"></canvas>

如果是我,我可能会尝试让它成为一个函数

// return a value between start and end as l goes from 0 to 1
function lerp(start, end, l) {
return start + (end - start) * l;
}

function animateAttribute(element, attribute, startValue, endValue, duration) {
const startTime = performance.now();

function animate(now) {
const timeSinceStart = (now - startTime) * 0.001;

// l goes from 0 to 1 over durationInSeconds;
const l = Math.min(timeSinceStart / duration, 1);

element.setAttribute(attribute, lerp(startValue, endValue, l));

// if we haven't finished request another animation frame
if (l < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}

const element = document.getElementById('id1');
const attribute = 'width';
const start = 600;
const end= 0;
const duration = 1;

animateAttribute(element, attribute, start, end, duration);
#id1 { background: red; }
<canvas id="id1"></canvas>

也可以将 l 传递给 these functions 中的任何一个并将结果传递给 lerp,您可以更改动画与 these styles of motion 中的任何一个相匹配的方式。 .

关于你的其他问题

Is there any way I can achieve this while using requestAnimationFrame? If I could get the average interval between frames or the fps that would work I think.

您可以计算帧之间的间隔。示例:

let then = performance.now();
function animate(now) {
deltaTimeInMilliseconds = (now - then);
then = now;

...
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

Am I perhaps worrying about something that isn't really a big issue?

只有你能回答这个问题

What fps can I expect on different devices (mobile, pc, tablet, etc.)?

大多数设备的帧率为 60fps,但也有以 120fps 或 240fps 运行的游戏显示器以及通常以 90fps 或更高帧率运行的 VR(和 WebVR),您可以在 VR 中使用浏览器。您是否关心其中任何一种情况取决于您。

关于javascript - 如何独立于刷新率计时 requestAnimationFrame(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46852857/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com