<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>钟表效果</title>
<style>
*{
margin: 0;
padding: 0;
}
canvas{
border: 1px #f00 solid;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<canvas width="600" height="600" id="canvas"></canvas>
</body>
</html>
<script>
/** @type {HTMLCanvasElement} **/
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
//创建一个钟表类
class Clock {
//绘制表盘
drawPan() {
ctx.save();//保存默认状态
ctx.beginPath();
ctx.arc(300, 300, 280, 0, 2 * Math.PI);
ctx.shadowBlur = 20;
ctx.shadowColor = 'rgba(0,0,0,0.5)';
let line = ctx.createLinearGradient(0,0,600,600);
line.addColorStop(0,'#c850c0');
line.addColorStop(0.4,'#4158d0');
line.addColorStop(0.7,'#a1c4fd');
line.addColorStop(1,'#c2e9fb');
ctx.fillStyle = line;
ctx.fill();
ctx.closePath();
ctx.restore();//恢复默认状态
//绘制内部小圆盘
ctx.save();
ctx.beginPath();
//内阴影效果
ctx.shadowBlur = 20;
ctx.shadowColor = 'rgba(0,0,0,0.5)';
ctx.arc(300, 300, 260, 0, 2 * Math.PI);
ctx.fillStyle = '#eee';
ctx.fill();
ctx.closePath();
ctx.restore();
}
// 绘制刻度
drawScale() {
ctx.save();
ctx.translate(300, 300); // 将原点移动到表盘中心
for(let i = 0; i < 12; i++){
ctx.beginPath();
ctx.rotate(Math.PI / 6); // 每次旋转30度
ctx.moveTo(0, -260);
ctx.lineTo(0, -250);
ctx.lineWidth = 5;
ctx.strokeStyle = '#000';
ctx.stroke();
}
// 绘制数字
ctx.font = '20px Arial';
ctx.fillStyle = '#000';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
for (let i = 1; i <= 12; i++) {
ctx.fillText(i, Math.cos((i - 3) * Math.PI / 6) * 230, Math.sin((i - 3) * Math.PI / 6) * 230);
}
ctx.restore();
}
// 绘制时分秒针
drawHands() {
const now = new Date();
let hours = now.getHours() % 12;
let minutes = now.getMinutes();
let seconds = now.getSeconds();
ctx.save();
ctx.translate(300, 300); // 将原点移动到表盘中心
// 绘制时针
ctx.save();
ctx.rotate((hours * 30 + minutes * 0.5) * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(0, 20);
ctx.lineTo(0, -100);
ctx.lineWidth = 10;
ctx.strokeStyle = '#000';
ctx.stroke();
ctx.restore();
// 绘制分针
ctx.save();
ctx.rotate((minutes * 6) * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(0, 40);
ctx.lineTo(0, -150);
ctx.lineWidth = 5;
ctx.strokeStyle = '#000';
ctx.stroke();
ctx.restore();
// 绘制秒针
ctx.save();
ctx.rotate((seconds * 6) * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(0, 60);
ctx.lineTo(0, -200);
ctx.lineWidth = 2;
ctx.strokeStyle = '#f00';
ctx.stroke();
ctx.restore();
//绘制中心圆点
ctx.save();
ctx.beginPath();
ctx.arc(0, 0, 10, 0, 2 * Math.PI);
ctx.fillStyle = '#000';
ctx.fill();
ctx.restore();
ctx.restore();
}
// 绘制当前时间文本
drawCurrentTime() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const timeString = `${hours}:${minutes}:${seconds}`;
ctx.save();
ctx.font = '20px Arial';
ctx.fillStyle = '#000';
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.fillText(timeString, 10, 10);
ctx.restore();
}
// 更新钟表
update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.drawPan();
this.drawScale();
this.drawHands();
this.drawCurrentTime();
}
}
let clock = new Clock();
setInterval(() => clock.update(), 1000);
</script>
05-15
540
09-26
443
06-01