JavaScript基于Canvas实现时钟组件
本文通过一个完整的时钟组件示例,详细讲解HTML5 Canvas绘图API的使用。内容涵盖Canvas基础定义、浏览器兼容性以及核心绘图方法,并结合正弦、余弦及弧度计算实现动态时钟效果,帮助开发者深入理解Canvas属性与数学模型在前端图形绘制中的应用。
Canvas是前端开发中用于绘制图形的重要标签,广泛应用于压缩上传图片、制作刮刮卡、生成海报及图表插件等场景。在技术面试中,Canvas图形绘制能力也是常见的考察点。
定义
Canvas元素主要用于图形绘制,具体实现需依赖脚本(通常为JavaScript)。该标签本身仅作为图形容器,实际的绘图工作必须通过脚本来完成。
浏览器支持
Internet Explorer 9及以上版本、Firefox、Opera、Chrome和Safari浏览器均支持该功能。
本文旨在通过开发一个时钟组件,帮助读者熟悉Canvas相关API的使用。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>canvas时钟</title>
<style>
*{margin:0;padding:0;}
body{text-align:center;padding-top:100px;}
</style>
</head>
<body>
<canvas id="clock" width="200px" height="200px"></canvas>
<script>
(function(win){
function DrawClock(options){
this.canvas = options.el;
this.ctx = this.canvas.getContext('2d');//方法返回一个用于在画布上绘图的环境
this.width = this.ctx.canvas.width;
this.height = this.ctx.canvas.height;
this.r = this.width / 2;
this.rem = this.width / 200;
this.digits = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
var self = this;
self.init();
setInterval(function(){
self.init();
}, 1000);
}
DrawClock.prototype = {
init: function(){
var ctx = this.ctx;
ctx.clearRect(0, 0, this.width, this.height); //在给定的矩形内清除指定的像素
var now = new Date();
var hours = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();
var hour = hours >= 12 ? hours - 12 : hours;
var minute = minutes + seconds / 60;
this.drawBackground();
this.drawHour(hour, minute);
this.drawMinute(minute);
this.drawSecond(seconds);
this.drawDot();
ctx.restore();
},
drawBackground: function(){
var ctx = this.ctx;
var self = this;
ctx.save();
ctx.translate(this.r, this.r); //重新映射画布上的 (0,0) 位置
ctx.beginPath();
ctx.lineWidth = 8 * this.rem;
ctx.arc(0, 0, this.r - ctx.lineWidth / 2, 0, 2 * Math.PI, false); //创建弧/曲线(用于创建圆形或部分圆)
ctx.stroke();
ctx.font = 16 * this.rem + "px Arial";//设置或返回文本内容的当前字体属性
ctx.textAlign = "center"; //设置或返回文本内容的当前对齐方式
ctx.textBaseline = "middle"; //设置或返回在绘制文本时使用的当前文本基线
this.digits.forEach(function(number, i){
var rad = 2 * Math.PI / 12 * i;
var x = Math.cos(rad) * (self.r - 33 * self.rem);
var y = Math.sin(rad) * (self.r - 33 * self.rem);
ctx.fillText(number, x, y); //在画布上绘制"被填充的"文本
});
//分钟的刻度,每分钟转6deg
for (var i = 0; i < 60; i++){
ctx.save(); //保存当前环境的状态
ctx.rotate(6 * i * Math.PI / 180); //旋转当前绘图
ctx.beginPath(); //起始一条路径,或重置当前路径
ctx.moveTo(0, -82 * this.rem); //把路径移动到画布中的指定点,不创建线条
ctx.lineTo(0, -87 * this.rem); //添加一个新点,然后在画布中创建从该点到最后指定点的线条
ctx.closePath(); //创建从当前点回到起始点的路径
ctx.strokeStyle = '#000'; //设置或返回用于笔触的颜色、渐变或模式
ctx.lineWidth = 1 * this.rem; //设置或返回当前的线条宽度
ctx.stroke(); //绘制已定义的路径
ctx.restore(); //返回之前保存过的路径状态和属性
}
//小时的刻度,每小时转30deg
for (var i = 0; i < 12; i++){
ctx.save();
ctx.rotate(30 * i * Math.PI / 180);
ctx.beginPath();
ctx.moveTo(0, -79 * this.rem);
ctx.lineTo(0, -87 * this.rem);
ctx.closePath();
ctx.strokeStyle = '#000';
ctx.lineWidth = 2 * this.rem;
ctx.stroke();
ctx.restore();
}
},
drawHour: function(hour, minute){
var ctx = this.ctx;
ctx.save();
ctx.beginPath();
var hRad = 2 * Math.PI / 12 * hour;
var mRad = 2 * Math.PI / 12 / 60 * minute;
ctx.rotate(hRad + mRad);
ctx.lineWidth = 6 * this.rem;
ctx.lineCap = "round"; //设置或返回线条的结束端点样式
ctx.moveTo(0, 10 * this.rem);
ctx.lineTo(0, -this.r / 2);
ctx.stroke();
ctx.restore();
},
drawMinute: function(minute){
var ctx = this.ctx;
ctx.save();
ctx.beginPath();
var rad = 2 * Math.PI / 60 * minute;
ctx.rotate(rad);
ctx.lineWidth = 3 * this.rem;
ctx.lineCap = "round";
ctx.moveTo(0, 10 * this.rem);
ctx.lineTo(0, -this.r + 26 * this.rem);
ctx.stroke();
ctx.restore();
},
drawSecond: function(second){
var ctx = this.ctx;
ctx.save();
ctx.beginPath();
ctx.fillStyle = "#c14543";
var rad = 2 * Math.PI / 60 * second;
ctx.rotate(rad);
ctx.moveTo(-3 * this.rem, 20 * this.rem);
ctx.lineTo(3 * this.rem, 20 * this.rem);
ctx.lineTo(1, -this.r + 26 * this.rem);
ctx.lineTo(-1, -this.r + 26 * this.rem);
ctx.fill(); //填充当前绘图(路径)
ctx.restore();
},
drawDot: function(minute){
var ctx = this.ctx;
ctx.beginPath();
ctx.fillStyle = "#fff";
ctx.arc(0, 0, 3 * this.rem, 0, 2 * Math.PI, false);
ctx.fill();
}
};
win.DrawClock = DrawClock;
})(window);
new DrawClock({el: document.getElementById("clock")});
</script>
</body>
</html>
实现时钟组件需要运用Canvas中大部分API。通过研究其代码实现,可以深入理解Canvas的属性和方法。此外,在生成时钟效果时,涉及数学中的几何模型,包括正弦(sin)、余弦(cos)函数及弧度计算,这有助于重温数学知识并提升编程乐趣。
时钟组件的运行效果如下图所示:

以上为JavaScript基于Canvas实现时钟组件的详细内容,更多关于Canvas实现时钟组件的资料,请关注本站其他相关文章。
AOS.js 动画不触发怎么办?排查 DOM 加载与移动端兼容问题
2026-11-05 17:02:26
sigma.js 怎么实现节点点击、拖拽与悬停提示交互
2026-11-05 15:03:27
Matter.js 与 PixiJS/Three.js 集成:分离物理计算与渲染
2026-11-05 13:43:48
主流JS弹幕库选型指南:Danmaku.js等库的功能与体积对比
2026-11-05 09:28:19
JavaScript点击事件监听与交互效果实例
2026-11-05 09:10:19
