html:
<body onload="draw()">
<canvas id="c" width="150" height="150"></canvas>
</body>
js:
const pi = Math.PI;
function draw() {
const now = new Date();
const ctx = document.getElementById('c').getContext('2d');
ctx.save();
ctx.clearRect(0, 0, 150, 150);
ctx.translate(75, 75); // 左上角居中
ctx.scale(0.4, 0.4);
ctx.rotate(-pi / 2); // 逆时针转90°
ctx.strokeStyle = 'black'; // 黑边
ctx.fillStyle = 'white'; // 白底
ctx.lineWidth = 8;
ctx.lineCap = 'round'; // 线条末端圆角
ctx.save();
/* 小时刻度线 */
for (let i = 0; i < 12; i++) {
ctx.beginPath();
ctx.rotate(pi / 6); // 30°一个刻度
ctx.moveTo(100, 0);
ctx.lineTo(120, 0); // 从里向外画,刻度线长度为20
ctx.stroke();
}
ctx.restore();
/* 分钟刻度线 */
ctx.save();
ctx.lineWidth = 5;
for (let i = 0; i < 60; i++) {
if (i % 5 != 0) {
/* 跳过时针刻度线 */
ctx.beginPath();
ctx.moveTo(117, 0);
ctx.lineTo(120, 0); // 分钟刻度线长度为3
ctx.stroke();
}
ctx.rotate(pi / 30);
}
ctx.restore();
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr >= 12 ? hr - 12 : hr; // 24时制的时间改成12h
ctx.fillStyle = 'black';
/* 画小时指针 */
ctx.save();
// 小时的刻度是小时数+分钟数+秒数
// 30°为一小时;(pi/6)/60为一分钟;类推一秒是((pi/6)/3600)
ctx.rotate(hr * (pi / 6) + (pi / 360) * min + (pi / 21600) * sec);
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20, 0);
ctx.lineTo(80, 0);
ctx.stroke();
ctx.restore();
/* 画分钟指针 */
ctx.save();
// 分钟的刻度是一圈是60个分钟刻度,一个刻度就是360/60 = 6°。6°的1/60就是一秒在分钟上的体现
ctx.rotate((pi / 30) * min + (pi / 1800) * sec);
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-18, 0);
ctx.lineTo(112, 0);
ctx.stroke();
ctx.restore();
/* 画秒针 */
ctx.save();
// 秒针一圈就是1分钟,360/60 = 6°就是一秒。即180/30
ctx.rotate((pi / 30) * sec);
ctx.strokeStyle = '#f00';
ctx.fillStyle = ' #f00';
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30, 0);
ctx.lineTo(90, 0);
ctx.stroke();
/* 秒针中心的圆 */
ctx.beginPath();
ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
ctx.fill();
ctx.restore();
/* 时钟最外圈的绿圈 */
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#325fa2';
ctx.arc(0, 0, 142, 0, pi * 2, true);
ctx.stroke();
ctx.restore();
requestAnimationFrame(draw);
}
效果: