Skip to content

时钟简介

在本教程系列中,我们将使用 HTML5 Canvas API 和现代 JavaScript 构建一个模拟时钟。我们将涵盖设置 canvas、绘制时钟盘面、添加数字,最后绘制和动画化时钟指针。

第一部分:创建 Canvas 和基本时钟盘面

Section titled “第一部分:创建 Canvas 和基本时钟盘面”

第一步是在 HTML 页面中设置一个 <canvas> 元素。这个元素将成为我们的绘图表面。然后我们将使用 JavaScript 获取这个 canvas 的引用及其 2D 渲染上下文(提供了用于绘图的方法)。

这是一个完整的 HTML 结构,包含一个 300x300 像素的 canvas。JavaScript 代码初始化 canvas,将其原点设置在中心,并绘制一个简单的白色圆形作为时钟盘面。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Clock - Part 1: Face</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f0f0f0; /* 页面浅灰色背景 */
}
canvas {
background-color: #333; /* canvas 本身的深色背景 */
border-radius: 50%; /* 使 canvas 元素看起来是圆形的 */
}
</style>
</head>
<body>
<canvas id="canvas" width="300" height="300">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let radius = canvas.height / 2; // 根据 canvas 高度计算半径
// 将绘图上下文的原点 (0,0) 移动到 canvas 的中心
ctx.translate(radius, radius);
// 稍微减小时钟半径,确保它很好地适应 canvas 边界
radius *= 0.90;
// 绘制时钟盘面的函数
function drawFace(context, r) {
// 为主圆开始一个新的路径
context.beginPath();
// 绘制时钟盘面的外圆
context.arc(0, 0, r, 0, 2 * Math.PI); // x, y, 半径, 起始角度, 结束角度
context.fillStyle = "white";
context.fill();
// 为时钟盘面添加边框
context.strokeStyle = '#333'; // 边框颜色
context.lineWidth = r * 0.1; // 边框宽度相对于半径
context.stroke();
// 添加中心圆点(指针的枢轴)
context.beginPath(); // 为中心圆点开始一个新的路径
context.arc(0, 0, r * 0.05, 0, 2 * Math.PI);
context.fillStyle = '#333'; // 中心圆点颜色
context.fill();
}
// 绘制时钟盘面
drawFace(ctx, radius);
</script>
</body>
</html>

const canvas = document.getElementById(“canvas”); const ctx = canvas.getContext(“2d”); let radius = canvas.height / 2; ctx.translate(radius, radius); radius *= 0.90;

function drawFace(context, r) { context.beginPath(); context.arc(0, 0, r, 0, 2 * Math.PI); context.fillStyle = “white”; context.fill();

// 现代新增:时钟边框 context.strokeStyle = ‘#333’; context.lineWidth = r * 0.1; context.stroke();

// 现代新增:中心圆点 context.beginPath(); context.arc(0, 0, r * 0.05, 0, 2 * Math.PI); context.fillStyle = ‘#333’; context.fill(); }

drawFace(ctx, radius);

  1. HTML 设置:
  • <canvas id="canvas" width="300" height="300">:这会创建一个 canvas 元素,具有唯一的 ID 和指定的尺寸。标签内的文本是为旧版本浏览器提供的备用内容。
  • 在 <style> 中添加了基本的 CSS,以改善页面呈现效果,并使 canvas 具有与时钟盘面匹配的深色背景和圆形外观。
<canvas id="canvas" width="300" height="300">
Your browser does not support the HTML5 canvas tag.
</canvas>
  1. JavaScript 初始化:
  • const canvas = document.getElementById("canvas");:使用其 ID 获取 <canvas> DOM 元素的引用。
  • const ctx = canvas.getContext("2d");:获取 2D 渲染上下文,这是用于所有绘图操作的对象。
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
  1. 半径和原点平移:
  • let radius = canvas.height / 2;:根据 canvas 高度计算时钟的初始半径。使用 let 是因为 radius 将会被修改。
  • ctx.translate(radius, radius);:这是关键的一步。它将 canvas 的 (0,0) 坐标原点从左上角移动到 canvas 的中心。这简化了所有后续的绘图计算,因为我们现在可以相对于时钟的中心进行绘制。
let radius = canvas.height / 2;
ctx.translate(radius, radius);
使用 canvas 尺寸(例如 canvas.height)计算时钟半径,可以使时钟在 canvas 大小改变时进行适当缩放。
  1. 调整半径以创建内边距:
  • radius *= 0.90;:将时钟半径减小到其初始值的 90%。这创建了一个小的内边距,确保时钟盘面不会触碰到 canvas 元素的边缘,这样看起来更美观。
radius *= 0.90; // 等同于 radius = radius * 0.90;
  1. drawFace(context, r) 函数:
  • 此函数封装了绘制时钟盘面的逻辑。
  • context.beginPath():在开始绘制新的形状或路径之前调用此函数是良好的实践,可以避免与之前的绘图产生意外连接。
  • context.arc(0, 0, r, 0, 2 * Math.PI);:绘制一个完整的圆形。(0,0) 是中心(由于使用了 translate),r 是半径,0 是起始角度,2 * Math.PI 是结束角度(一个完整的圆周,以弧度为单位)。
  • context.fillStyle = "white"; context.fill();:将填充颜色设置为白色并填充圆形。
  • 增强功能:更新后的函数还绘制了时钟盘面周围的边框(使用 strokeStyle、lineWidth、stroke()),以及一个小的中心圆点,用作时钟指针的枢轴点。这些是模拟时钟的常见特征。
function drawFace(context, r) {
// 主圆
context.beginPath();
context.arc(0, 0, r, 0, 2 * Math.PI);
context.fillStyle = "white";
context.fill();
// 边框
context.strokeStyle = '#333';
context.lineWidth = r * 0.1;
context.stroke();
// 中心圆点
context.beginPath();
context.arc(0, 0, r * 0.05, 0, 2 * Math.PI);
context.fillStyle = '#333';
context.fill();
}

最后,调用 drawFace(ctx, radius); 来实际在 canvas 上绘制时钟盘面。

这为我们的时钟奠定了基础。在接下来的部分中,我们将添加数字和时钟指针。