服务器之家

服务器之家 > 正文

js基于canvas实现时钟组件

时间:2022-01-19 15:12     来源/作者:豫见陈公子

canvas一直是前端开发中不可或缺的一种用来绘制图形的标签元素,比如压缩上传的图片、比如刮刮卡、比如制作海报、图表插件等,很多人在面试的过程中也会被问到有没有接触过canvas图形绘制。

定义

canvas元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成。
canvas标签只是图形容器,您必须使用脚本来绘制图形。

浏览器支持

Internet Explorer 9、Firefox、Opera、Chrome 和 Safari 支持

那么本篇文章就通过一个时钟组件来熟悉使用一下关于canvas的api。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<!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时钟用到了canvas中大部分的api,通过学习canvas时钟的代码实现,很能了解canvas的属性和方法,同时,实现时钟效果时,用到了数学中的几何模型正弦sin和余弦cos以及弧度的计算方法,又重温了一把当年学数学时的许多乐趣,可谓是一举两得。

时钟效果图如下:

js基于canvas实现时钟组件

以上就是js基于canvas实现时钟组件的详细内容,更多关于canvas实现时钟组件的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/tnnyang/p/8951804.html

标签:

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部