时钟启动
Canvas 时钟:开始动画
Section titled “Canvas 时钟:开始动画”本节解释如何使用 HTML Canvas 对我们一直在构建的模拟时钟进行动画处理。
第五部分 - 使时钟走动
Section titled “第五部分 - 使时钟走动”为了让时钟指针移动并实时更新,我们需要以固定的时间间隔重复调用主绘图函数 (drawClock)。setInterval() 方法适用于此任务,特别是对于每秒更新一次的时钟。
以下是如何集成 setInterval():
// 假设 'canvas', 'ctx', 和 'radius' 已经定义并初始化// 也假设 drawClock(), drawFace(), drawNumbers(), 和 drawTime() 函数已存在。
// const canvas = document.getElementById('myClockCanvas');// const ctx = canvas.getContext('2d');// let radius = canvas.height / 2;// ctx.translate(radius, radius); // 将原点移动到 canvas 中心// radius = radius * 0.90; // 实际时钟半径
// 协调时钟所有部分的 главная функция рисования// function drawClock() {// drawFace(ctx, radius); // 绘制时钟表盘// drawNumbers(ctx, radius); // 绘制小时刻度// drawTime(ctx, radius); // 根据当前时间绘制指针// }
// 不再只调用一次 drawClock():// drawClock();
// 每 1000 毫秒 (1 秒) 调用一次 drawClocksetInterval(drawClock, 1000);
// --- 完整的概念设置 ---// (这些函数应该在脚本的其他地方定义)// function drawFace(ctx, radius) { /* ... 绘制时钟表盘 ... */ }// function drawNumbers(ctx, radius) { /* ... 绘制刻度 ... */ }// function drawTime(ctx, radius) { /* ... 获取当前时间并绘制指针 ... */ }
// function setupClock() {// const canvas = document.getElementById('myClockCanvas');// const ctx = canvas.getContext('2d');// let radius = canvas.height / 2;// ctx.translate(radius, radius);// radius = radius * 0.90;
// function drawClock() {// // 清除并重新绘制指针很重要,// // 但表盘和刻度可能只需要绘制一次,// // 如果它们不改变的话。为简单起见,这个示例重绘了所有。// // 更优化的方法是只清除指针所在的区域。// // 或者,为简单起见,在重绘表盘、刻度和时间之前清除整个时钟区域:// // ctx.clearRect(-radius, -radius, radius * 2, radius * 2);
// drawFace(ctx, radius);// drawNumbers(ctx, radius);// drawTime(ctx, radius);// }
// setInterval(drawClock, 1000);// }
// document.addEventListener('DOMContentLoaded', setupClock);实现时钟动画的核心改变是将一次性的 drawClock(); 调用替换为 setInterval(drawClock, 1000);。
setInterval(callbackFunction, delayInMilliseconds): 这个浏览器 API 会每隔delayInMilliseconds毫秒重复调用callbackFunction(在本例中是drawClock)。1000: 这个值意味着drawClock函数每 1000 毫秒(等于 1 秒)执行一次。这对于模拟时钟(秒针每秒移动)是合适的。
动画的重要注意事项:
Section titled “动画的重要注意事项:”- 清除 Canvas: 在每次调用
drawClock时,特别是在绘制移动元素(如指针)之前,通常需要清除上一帧。否则,新的绘图将叠加在旧的绘图之上,产生凌乱的残影。你可以清除整个 canvas:ctx.clearRect(0, 0, canvas.width, canvas.height);,或者如果已经平移了上下文,则使用ctx.clearRect(-radius, -radius, radius*2, radius*2);。更优化的方法是只清除 canvas 中发生变化的区域(例如,指针所在的区域)。为简单起见,在时钟示例中,通常会重绘整个表盘区域。 - 性能: 对于复杂的动画,通常推荐使用
requestAnimationFrame()而非setInterval()。requestAnimationFrame()与浏览器的重绘周期同步,可以带来更流畅的动画效果和更好的性能,尤其是在具有不同刷新率的设备上。然而,对于每秒更新一次的简单时钟,setInterval()已经足够并且对初学者来说更容易理解。 - 资源管理: 如果时钟从页面中移除或不再需要,你应该使用
clearInterval()清除定时器,以防止不必要的处理。存储setInterval()返回的 ID:const intervalID = setInterval(drawClock, 1000);,然后在需要时调用clearInterval(intervalID);。
drawClock 函数本身(它调用 drawFace、drawNumbers 和 drawTime)现在将每秒执行一次,确保 drawTime 获取当前时间并将指针绘制到新的位置。