d3-timer
此模块提供了一个高效的队列,能够管理数千个并发动画,同时保证并发或分阶段动画的一致、同步时间。在内部,它使用 requestAnimationFrame 实现流畅的动画(如果可用),当延迟超过 24 毫秒时切换到 setTimeout。
¥This module provides an efficient queue capable of managing thousands of concurrent animations, while guaranteeing consistent, synchronized timing with concurrent or staged animations. Internally, it uses requestAnimationFrame for fluid animation (if available), switching to setTimeout for delays longer than 24ms.
now()
源代码 · 返回当前时间(如果可用,则返回 performance.now 定义的时间);如果不可用,则返回 Date.now 定义的时间。
¥Source · Returns the current time as defined by performance.now if available, and Date.now if not.
d3.now() // 1236.3000000715256
当前时间在帧开始时更新;因此,它在帧期间保持一致,并且在同一帧期间安排的任何计时器都将同步。如果在帧外调用此方法(例如响应用户事件),则会计算当前时间,然后将其固定到下一帧,再次确保事件处理期间的时间一致性。
¥The current time is updated at the start of a frame; it is thus consistent during the frame, and any timers scheduled during the same frame will be synchronized. If this method is called outside of a frame, such as in response to a user event, the current time is calculated and then fixed until the next frame, again ensuring consistent timing during event handling.
timer(callback, delay, time)
源代码 · 安排一个新的计时器,重复调用指定的回调,直到计时器到达 stopped。可以指定一个可选的延迟时间(以毫秒为单位),用于在延迟后调用给定的回调;如果未指定延迟,则默认为零。延迟相对于指定的时间(以毫秒为单位);如果未指定 time,则默认为 now。
¥Source · Schedules a new timer, invoking the specified callback repeatedly until the timer is stopped. An optional numeric delay in milliseconds may be specified to invoke the given callback after a delay; if delay is not specified, it defaults to zero. The delay is relative to the specified time in milliseconds; if time is not specified, it defaults to now.
回调函数会传递自计时器激活以来(表观)经过的时间。例如:
¥The callback is passed the (apparent) elapsed time since the timer became active. For example:
const t = d3.timer((elapsed) => {
console.log(elapsed);
if (elapsed > 200) t.stop();
}, 150);
这将大致产生以下控制台输出:
¥This produces roughly the following console output:
3
25
48
65
85
106
125
146
167
189
209
(确切的值可能因你的 JavaScript 运行时以及计算机的其他操作而异。)请注意,第一个耗时为 3 毫秒:这是自计时器启动以来经过的时间,而不是自计时器被安排以来经过的时间。由于指定的延迟,计时器在预定时间后 150 毫秒启动。如果页面处于后台运行状态且 requestAnimationFrame 暂停,则表观运行时间可能小于实际运行时间;在后台,表观时间会被冻结。
¥(The exact values may vary depending on your JavaScript runtime and what else your computer is doing.) Note that the first elapsed time is 3ms: this is the elapsed time since the timer started, not since the timer was scheduled. Here the timer started 150ms after it was scheduled due to the specified delay. The apparent elapsed time may be less than the true elapsed time if the page is backgrounded and requestAnimationFrame is paused; in the background, apparent time is frozen.
如果在另一个计时器的回调中调用 timer,则新的计时器回调(如果根据指定的延迟和时间确定符合条件)将在当前帧结束时立即调用,而不是等到下一帧。在一帧内,计时器回调保证按照其调度的顺序调用,无论其开始时间如何。
¥If timer is called within the callback of another timer, the new timer callback (if eligible as determined by the specified delay and time) will be invoked immediately at the end of the current frame, rather than waiting until the next frame. Within a frame, timer callbacks are guaranteed to be invoked in the order they were scheduled, regardless of their start time.
timer.restart(callback, delay, time) {#timer_restart}
源代码 · 使用指定的回调函数以及可选的延迟和时间重启计时器。这相当于停止此计时器并使用指定参数创建一个新的计时器,但此计时器保留原始调用优先级。
¥Source · Restart a timer with the specified callback and optional delay and time. This is equivalent to stopping this timer and creating a new timer with the specified arguments, although this timer retains the original invocation priority.
timer.stop() {#timer_stop}
源代码 · 停止此计时器,阻止后续回调。如果计时器已停止,则此方法无效。
¥Source · Stops this timer, preventing subsequent callbacks. This method has no effect if the timer has already stopped.
timerFlush()
源代码 · 立即调用任何符合条件的计时器回调。请注意,零延迟计时器通常在一帧(约 17 毫秒)后首次执行。这可能会导致短暂闪烁,因为浏览器渲染页面两次:在第一个事件循环结束时执行一次,然后在第一个计时器回调时立即执行一次。通过在第一个事件循环结束时刷新计时器队列,你可以立即运行任何零延迟计时器并避免闪烁。
¥Source · Immediately invoke any eligible timer callbacks. Note that zero-delay timers are normally first executed after one frame (~17ms). This can cause a brief flicker because the browser renders the page twice: once at the end of the first event loop, then again immediately on the first timer callback. By flushing the timer queue at the end of the first event loop, you can run any zero-delay timers immediately and avoid the flicker.
timeout(callback, delay, time)
源代码 · 与 timer 类似,但计时器会在第一次回调时自动执行 stops 操作。setTimeout 的合适替代品,保证不在后台运行。回调函数会传递已用时间。
¥Source · Like timer, except the timer automatically stops on its first callback. A suitable replacement for setTimeout that is guaranteed to not run in the background. The callback is passed the elapsed time.
interval(callback, delay, time)
源代码 · 与 timer 类似,但回调函数每延迟毫秒调用一次;如果未指定延迟,则相当于 timer。setInterval 的合适替代品,保证不在后台运行。回调函数会传递已用时间。
¥Source · Like timer, except the callback is invoked only every delay milliseconds; if delay is not specified, this is equivalent to timer. A suitable replacement for setInterval that is guaranteed to not run in the background. The callback is passed the elapsed time.