我有一个简单的动画,它是使用 requestAnimationFrame
完成的(出于演示目的,改编自 the example on MDN )。如果在动画之前我显示一个确认对话框,则动画函数收到的时间戳是错误的。第一个和第二个时间戳之间的差异等于从显示确认消息到单击“确定”按钮的时间。此行为(bug?)在 Chrome 和 Opera(均运行 Chromium)中可见。 Firefox 和 Internet Explorer 11 按预期运行。检查the fiddle或下面的示例。
const cache = {
start: null,
target: null
};
function animate(timestamp) {
console.log(timestamp);
if (cache.start === null) {
cache.start = timestamp;
}
var progress = timestamp - cache.start;
cache.target.style.left = Math.min(progress / 10, 100) + 'px';
if (progress < 1000) {
requestAnimationFrame(animate);
} else {
cache.target.style.left = 0;
cache.start = null;
}
}
(function() {
const target = document.getElementsByTagName("div")[0];
cache.target = target;
const cb = document.getElementsByTagName("input")[0];
const btn = document.getElementsByTagName("button")[0];
btn.addEventListener("click", function() {
if (cb.checked) {
if (confirm("Just click 'OK' to start the animation, ok?")) {
requestAnimationFrame(animate);
}
} else {
requestAnimationFrame(animate);
}
})
})();
html,
body {
padding: 0;
margin: 0;
}
div {
width: 50px;
height: 50px;
border: 1px solid black;
background-color: yellowgreen;
position: absolute;
top: 50px;
}
button {
margin-top: 20px;
}
<button type="button">Start</button>
<label>
<input type="checkbox" />use "confirm"</label>
<div>
</div>
打开控制台查看收到的时间戳。动画设置为运行 2 秒。显示确认
对话框时,如果单击“确定”按钮的速度超过 2 秒,则动画将运行“剩余”时间。如果单击“确定”按钮所需的时间长于时间动画时间,则该元素将不会被动画化,并且将有 2 个值(时间戳)发送到控制台;这两个值的差值就是单击“确定”按钮所需的时间。
我认为这是 Chromium 中的一个错误。是否有解决方法(仍然使用 requestAnimationFrame
进行动画处理,而不是通过 CSS)?我在他们的追踪器中找不到任何与此相关的信息。有人有这方面的更多信息吗?
最佳答案
我不得不说,我发现这非常有趣。
在花了很多时间之后,我可能已经找到了适合您的解决方法。你可以在这里看到这一点。 https://jsfiddle.net/qtj467n0/13/
其基本要点是,我用 performance.now()
替换了 requestAnimationFrame
提供的 DOMHighResTimeStamp
,它还返回一个 DOMHighResTimeStamp
。
const cache = {
start: null,
target: null,
time: 2000
};
function animate(timestamp) {
console.log(timestamp);
if (cache.start === null) {
cache.start = timestamp;
}
var progress = timestamp - cache.start;
cache.target.style.left = Math.min(progress / 10, cache.time / 10) + 'px';
if (progress < cache.time) {
requestAnimationFrame(animate);
} else {
cache.target.style.left = 0;
cache.start = null;
}
}
const render = () => {
requestAnimationFrame((timestamp) => {
const performanceNow = performance.now();
animate(performanceNow)
});
}
(function() {
const target = document.getElementsByTagName("div")[0];
cache.target = target;
const cb = document.getElementsByTagName("input")[0];
const btn = document.getElementsByTagName("button")[0];
btn.addEventListener("click", function() {
if (cb.checked) {
const confirmed = confirm("Just click 'OK' to start the animation, ok?");
if (confirmed) {
render();
}
} else {
requestAnimationFrame(animate);
}
})
})();
html,
body {
padding: 0;
margin: 0;
}
div {
width: 50px;
height: 50px;
border: 1px solid black;
background-color: yellowgreen;
position: absolute;
top: 50px;
}
button {
margin-top: 20px;
}
<button type="button">Start</button>
<label>
<input type="checkbox" />use "confirm"</label>
<div>
</div>
关于javascript - requestAnimationFrame 在显示确认对话框时给出错误的时间戳(Chromium?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48091556/