javascript - requestAnimationFrame 在显示确认对话框时给出错误的时间戳(Chromium?)

标签 javascript animation chromium

我有一个简单的动画,它是使用 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/

相关文章:

javascript - 使用 ext js 4.1 在网格中突出显示一行

php - 禁止用户按后退或刷新

css - 在屏幕外循环播放 SVG 幻灯片动画而不会溢出

javascript - 覆盖 javascript 全局变量的可靠方法

c++ - Chromium mini 安装程序大小达到 1.19GB?

javascript - 禁用的操作按钮 - 更改格式

javascript - 如何使用一些运算符组合两个数组?

JQuery UI(效果核心)在具有多个选择器的一个元素上 addClass/removeClass...但有一个问题

android - 为 Lollipop 之前的设备创建圆形显示 (Android)

java - 浏览器关闭时关闭程序