有详细注释, 直接copy可看到效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小小八毛钟表</title>
<style>
.box {
width: 450px;
height: 450px;
margin: 50px auto;
}
</style>
</head>
<body>
<div class="box">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
<script>
//初始化
let canvas = document.getElementById('canvas')
let ctx = canvas.getContext('2d');
canvas.width = 420
canvas.height = 420
setInterval(() => {
// 画表盘
// 一分钟刻度,每6度一分钟,即一个刻度
ctx.beginPath();
for (var i = 0; i < 60; i++) {
ctx.moveTo(200, 200);
ctx.arc(210, 210, 200, 6 * i * Math.PI / 180, 6 * (i + 1) * Math.PI / 180);
}
ctx.strokeStyle = 'black';
ctx.stroke()
// 一分钟刻度中间多余的用圆盖住,只留最外一圈的刻度
ctx.beginPath();
ctx.arc(210, 210, 180, 0 / 180 * Math.PI, 360 / 180 * Math.PI, false)
ctx.strokeStyle = 'white';
ctx.fillStyle = 'white';
ctx.fill();
ctx.stroke()
// 五分钟刻度,每30度一分钟,即五个刻度
ctx.beginPath();
for (var i = 0; i < 12; i++) {
ctx.moveTo(210, 210);
ctx.arc(210, 210, 200, 30 * i * Math.PI / 180, 30 * (i + 1) * Math.PI / 180);
}
ctx.strokeStyle = 'black';
ctx.lineWidth = 3; //相比于一分钟的加粗一点
ctx.stroke()
// 五分钟刻度中间多余的用圆盖住,只留最外一圈的刻度
ctx.beginPath();
ctx.arc(210, 210, 170, 0 / 180 * Math.PI, 360 / 180 * Math.PI, false)
ctx.strokeStyle = 'white'; //边框
ctx.fillStyle = 'white'; //填充
ctx.fill();
ctx.stroke()
// 画指针圆心
ctx.beginPath();
ctx.arc(210, 210, 2, 0 / 180 * Math.PI, 360 / 180 * Math.PI, false)
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
ctx.lineWidth = 2;
ctx.fill();
ctx.stroke()
// 绘制logo文本
ctx.beginPath()
ctx.font = "20px 楷体"
ctx.textAlign = "center"
ctx.fillStyle = 'black';
ctx.fillText("Canvas", 210, 110, 200)
ctx.closePath()
ctx.stroke()
// 画一圈数字
var clockRadius = 210; //定义一个变量,是数字圆半径
ctx.font = '16px Arial'; //字体大小和字体
ctx.fillStyle = '#000'; //字体填充
ctx.textAlign = 'center'; //让数字左右居中对齐
ctx.textBaseline = 'middle'; //让数字上下居中对齐
for (var n = 1; n <= 12; n++) { //循环12次,做12个数字,利用正弦余弦,计算每个数字的坐标
var theta = (n - 3) * (Math.PI * 2) / 12; //角度,从-60°开始,
var x = clockRadius * Math.cos(theta) * 0.75 + clockRadius; //x坐标, 半径*正弦*0.7+圆心位置 0.75是为了让半径相比于表盘小一点
var y = clockRadius * Math.sin(theta) * 0.75 + clockRadius; //y坐标, 半径*正弦*0.7+圆心位置
ctx.fillText(n, x, y);
// console.log(n, x, y, theta)
}
//tips: Math.cos(a)正弦,对边比斜边 Math.sin(a)余弦,临边比斜边 里面的a表示度数,返回的是正弦或者余弦的值
// 画时分秒针, 用圆画,让起点和终点度数一样,就重合在一起为一根线
let cx = 210, cy = 210, r = 210
//获取当前时间
let h = new Date().getHours() //时
let m = new Date().getMinutes() //分
let s = new Date().getSeconds() //秒
h = (h * 30 - 90) / 180 * Math.PI //时针的度数
m = (m * 6 - 90) / 180 * Math.PI //分针的度数
s = (s * 6 - 90) / 180 * Math.PI //秒针的度数
//秒针
ctx.beginPath()
ctx.moveTo(cx, cy)
ctx.arc(cx, cy, r - 30, s, s)
ctx.stroke()
// 分针
ctx.beginPath()
ctx.moveTo(cx, cy)
ctx.arc(cx, cy, r - 60, m, m)
ctx.stroke()
// 时针
ctx.beginPath()
ctx.moveTo(cx, cy)
ctx.arc(cx, cy, r - 90, h, h)
ctx.lineWidth = "2"
ctx.stroke()
}, 1000)
</script>