D3.js - 定时器 API
D3.js - 定时器 API
Section titled “D3.js - 定时器 API”D3 定时器 API 模块 (d3-timer) 用于管理动画和其他基于时间的任务。它利用浏览器的 requestAnimationFrame API 来实现高效、同步的动画,这些动画在页面不活跃时表现良好并节省资源。
理解 requestAnimationFrame
Section titled “理解 requestAnimationFrame”window.requestAnimationFrame() 是一个浏览器方法,它告诉浏览器你希望执行一个动画。它请求浏览器为下一个动画帧调度一次窗口重绘。浏览器会在下一次重绘之前调用你指定的 callback 函数来更新动画。D3 的定时器模块为这个机制提供了一个更高层级的接口。
如果你使用完整的 D3 包,则包含定时器 API。对于模块化使用,你需要导入 d3-timer。
<html> <head> <script src="https://d3js.org/d3.v7.min.js"></script> </head> <body> <script> // Example: A simple timer const myTimer = d3.timer(function(elapsed) { console.log("Elapsed time:", elapsed, "ms"); if (elapsed > 2000) { myTimer.stop(); // Stop the timer after 2 seconds console.log("Timer stopped."); } }); </script> </body></html>在模块化环境中使用:
import { timer, now, timeout, interval } from 'd3-timer';定时器 API 方法
Section titled “定时器 API 方法”d3-timer 模块提供了以下关键方法:
d3.now()
Section titled “d3.now()”返回当前时间,优先使用 performance.now()(如果可用),否则使用 Date.now()。这是定时器使用的高精度时间。
d3.timer(callback[, delay[, time]])
Section titled “d3.timer(callback[, delay[, time]])”调度一个新的定时器,重复调用指定的 callback 函数。callback 函数会接收一个参数,表示自定时器开始以来(或自指定的 time 以来)经过的时间。
delay(可选,数字):第一次调用前的初始延迟(毫秒)。默认为零。time(可选,数字):定时器应该开始的时间点(基于d3.now())。默认为d3.now()加上delay。 定时器会一直运行,直到调用timer.stop()方法。返回定时器对象。
timer.restart(callback[, delay[, time]])
Section titled “timer.restart(callback[, delay[, time]])”用新的 callback 函数和可选的 delay 及 time 重新启动一个现有的定时器。这对于重用定时器对象很有用。
timer.stop()
Section titled “timer.stop()”停止定时器,阻止后续调用其 callback 函数。
d3.timeout(callback[, delay[, time]])
Section titled “d3.timeout(callback[, delay[, time]])”类似于 d3.timer,但定时器在第一次调用 callback 函数后会自动停止。这是使用 requestAnimationFrame 实现 setTimeout 行为的一种方便的简写方式。callback 函数会接收经过的时间作为参数。
d3.interval(callback[, delay[, time]])
Section titled “d3.interval(callback[, delay[, time]])”调度一个定时器,以指定的 delay 间隔重复调用 callback 函数。
delay(可选,数字):两次调用之间的间隔(毫秒)。如果未指定,定时器最初的行为类似于d3.timer,在每一帧都调用。常见用法是d3.interval(callback, 1000),表示每秒运行一次。time(可选,数字):定时器应该开始的时间点。callback函数会接收经过的时间作为参数。返回定时器对象。
创建一个 HTML 文件,命名为 timer_example.html,并添加以下脚本。此示例演示了 d3.timer、d3.timeout 和 d3.interval。
<!DOCTYPE html><html> <head> <title>D3.js Timer API Example</title> <script src="https://d3js.org/d3.v7.min.js"></script> <style> body { font-family: sans-serif; } .log { margin-bottom: 10px; padding: 5px; border: 1px solid #eee; } </style> </head> <body> <h3>D3.js Timer API Demonstration</h3> <div id="output"></div>
<script> const outputDiv = d3.select("#output");
outputDiv.append("p").attr("class", "log").text("Starting d3.timer (stops after 150ms elapsed from its start)"); const continuousTimer = d3.timer(function(elapsed) { outputDiv.append("p").text(`d3.timer: ${elapsed.toFixed(2)} ms`); if (elapsed > 150) { continuousTimer.stop(); outputDiv.append("p").attr("class", "log").text("d3.timer stopped."); } }, 50); // Start after 50ms delay
outputDiv.append("p").attr("class", "log").text("Starting d3.timeout (runs once after 500ms)"); d3.timeout(function(elapsed) { outputDiv.append("p").text(`d3.timeout: Ran after ${elapsed.toFixed(2)} ms`); }, 500);
outputDiv.append("p").attr("class", "log").text("Starting d3.interval (runs every 300ms, 3 times)"); let intervalCount = 0; const repeatingInterval = d3.interval(function(elapsed) { intervalCount++; outputDiv.append("p").text(`d3.interval (call ${intervalCount}): ${elapsed.toFixed(2)} ms`); if (intervalCount >= 3) { repeatingInterval.stop(); outputDiv.append("p").attr("class", "log").text("d3.interval stopped."); } }, 300); // Run every 300ms
</script> </body></html>在浏览器中打开这个 HTML 文件。当每个定时器触发和停止时,你会在页面上看到相应的日志消息,这展示了它们的不同行为。如果遇到问题,请检查浏览器的控制台,查看是否有错误或额外的 D3 日志。