跳至内容

d3-timer

此模块提供了一个高效的队列,能够管理数千个并发动画,同时保证并发或分阶段动画的计时一致、同步。在内部,它使用 requestAnimationFrame 来实现流畅动画(如果可用),在延迟超过 24 毫秒时切换到 setTimeout

now()

源代码 · 如果可用,返回由 performance.now 定义的当前时间,否则返回 Date.now

js
d3.now() // 1236.3000000715256

当前时间在帧开始时更新;因此在帧期间它是保持一致的,并且在同一帧期间调度的任何计时器将同步。如果此方法在帧外部调用,例如响应用户事件,则会计算当前时间,然后一直保持到下一帧,同样确保事件处理期间的计时一致。

timer(callback, delay, time)

源代码 · 调度一个新的计时器,反复调用指定的 callback,直到计时器被 停止。可以指定一个可选的以毫秒为单位的数字 delay,以便在延迟后调用给定的 callback;如果未指定 delay,则默认为零。延迟相对于以毫秒为单位指定的 time;如果未指定 time,则默认为 now

callback 传递计时器激活后(显式)elapsed 时间。例如

js
const t = d3.timer((elapsed) => {
  console.log(elapsed);
  if (elapsed > 200) t.stop();
}, 150);

这将产生大致以下控制台输出

3
25
48
65
85
106
125
146
167
189
209

(确切的值可能会因 JavaScript 运行时以及计算机正在执行的操作而异。)请注意,第一个 elapsed 时间为 3 毫秒:这是计时器启动以来的经过时间,而不是计时器调度以来的经过时间。这里计时器在调度后 150 毫秒启动,因为指定了延迟。如果页面处于后台且 requestAnimationFrame 暂停,则显式 elapsed 时间可能小于真实 elapsed 时间;在后台,显式时间是冻结的。

如果在另一个计时器的回调内调用 timer,则新的计时器回调(如果根据指定的 delaytime 确定为符合条件)将在当前帧结束时立即调用,而不是等到下一帧。在帧内,保证计时器回调按其调度的顺序调用,无论其开始时间如何。

timer.restart(callback, delay, time)

源代码 · 使用指定的 callback 和可选的 delaytime 重新启动计时器。这等效于停止此计时器并使用指定的参数创建一个新的计时器,尽管此计时器保留原始调用优先级。

timer.stop()

源代码 · 停止此计时器,阻止后续回调。如果计时器已经停止,则此方法无效。

timerFlush()

源代码 · 立即调用任何符合条件的计时器回调。请注意,零延迟计时器通常在第一帧(~17 毫秒)后首次执行。这会导致短暂的闪烁,因为浏览器会渲染页面两次:一次在第一个事件循环结束时,然后在第一个计时器回调上立即再次渲染。通过在第一个事件循环结束时刷新计时器队列,您可以在第一时间立即运行任何零延迟计时器,并避免闪烁。

timeout(callback, delay, time)

源代码 · 与 timer 类似,除了计时器在其第一个回调上自动 停止。一个适合 setTimeout 的替代方案,保证不会在后台运行。callback 传递经过时间。

interval(callback, delay, time)

源代码 · 与 timer 类似,除了 callback 仅每 delay 毫秒调用一次;如果未指定 delay,则这等效于 timer。一个适合 setInterval 的替代方案,保证不会在后台运行。callback 传递经过时间。