如何调用requestAnimationFrame()独立于refreshrates
我有一种情况,我想在1秒内将600px宽的div的宽度设置为0px。我可以使用requestAnimationFrame()
。但如果动画需要1秒钟,我不会100%确定。如何调用requestAnimationFrame()独立于refreshrates
这将是这个样子:
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会影响动画的持续时间(在30fps的有可能需要2秒和60帧它将采取一个)。我想确保这个动画的持续时间总是一秒钟。如果fps率不同,我想根据持续时间更改宽度的新值(所以在30 fps下动画我们会将宽度每改变20(600px/30fps))。
- 有没有什么办法可以在使用时达到这个目的?如果我能得到帧之间的平均间隔或我认为可行的fps。
- 我是否担心这件事不是一个大问题?
- 在不同的设备(手机,电脑,平板电脑等)上我可以期待什么样的fps?
文档:https://developer.mozilla.org/en-US/docs/Web/API/Window/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并传递结果线性插值可以更改动画是如何发生的,以匹配任何these styles of motion。
至于你的其他问题
有什么办法,而使用requestAnimationFrame我能做到这一点?如果我能得到帧之间的平均间隔或我认为可行的fps。
您可以计算帧之间的间隔。例如:
let then = performance.now();
function animate(now) {
deltaTimeInMilliseconds = (now - then);
then = now;
...
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
上午我也许担心的东西是不是一个真正的大问题?
只有你能回答这个问题
我可以期待在不同的设备(手机,PC,平板电脑等)FPS什么?
大多数设备都是60fps的,但也有在120fps的或240fps的运行以及玩家显示器VR(和WebVR)通常运行在达到90fps以上,可以使用内部VR浏览器。你是否在乎这些情况取决于你。
测量时间,因为动画的开始和使用它作为在宽度计算的参考。将这里的普遍做法。
使用此代码无论设备具有哪种FPS,动画都会持续一秒。
const el = document.getElementById('id1');
const start = Date.now();
function animateWidth() {
const t = (Date.now() - start)/1000; // 1000 - one second
if(t >= 1) {
el.setAttribute('width', 0);
}
else {
el.setAttribute('width', 600 * (1 - t));
window.requestAnimationFrame(animateWidth);
}
}
animateWidth();
你可以通过使用['performance.now()'](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)来做到这一点。 – Xufox