canvas一直是前端開發(fā)中不可或缺的一種用來繪制圖形的標簽元素,比如壓縮上傳的圖片、比如刮刮卡、比如制作海報、圖表插件等,很多人在面試的過程中也會被問到有沒有接觸過canvas圖形繪制。
定義
canvas元素用于圖形的繪制,通過腳本 (通常是JavaScript)來完成。
canvas標簽只是圖形容器,您必須使用腳本來繪制圖形。
瀏覽器支持
Internet Explorer 9、Firefox、Opera、Chrome 和 Safari 支持
那么本篇文章就通過一個時鐘組件來熟悉使用一下關(guān)于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');//方法返回一個用于在畫布上繪圖的環(huán)境 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); //在給定的矩形內(nèi)清除指定的像素 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); //創(chuàng)建弧/曲線(用于創(chuàng)建圓形或部分圓) ctx.stroke(); ctx.font = 16 * this.rem + "px Arial";//設(shè)置或返回文本內(nèi)容的當(dāng)前字體屬性 ctx.textAlign = "center"; //設(shè)置或返回文本內(nèi)容的當(dāng)前對齊方式 ctx.textBaseline = "middle"; //設(shè)置或返回在繪制文本時使用的當(dāng)前文本基線 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); //在畫布上繪制"被填充的"文本 }); //分鐘的刻度,每分鐘轉(zhuǎn)6deg for (var i = 0; i < 60 ; i++){ ctx.save(); //保存當(dāng)前環(huán)境的狀態(tài) ctx.rotate(6 * i * Math.PI / 180); //旋轉(zhuǎn)當(dāng)前繪圖 ctx.beginPath(); //起始一條路徑,或重置當(dāng)前路徑 ctx.moveTo(0, -82 * this.rem); //把路徑移動到畫布中的指定點,不創(chuàng)建線條 ctx.lineTo(0, -87 * this.rem); //添加一個新點,然后在畫布中創(chuàng)建從該點到最后指定點的線條 ctx.closePath(); //創(chuàng)建從當(dāng)前點回到起始點的路徑 ctx.strokeStyle = '#000' ; //設(shè)置或返回用于筆觸的顏色、漸變或模式 ctx.lineWidth = 1 * this.rem; //設(shè)置或返回當(dāng)前的線條寬度 ctx.stroke(); //繪制已定義的路徑 ctx.restore(); //返回之前保存過的路徑狀態(tài)和屬性 } //小時的刻度,每小時轉(zhuǎn)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" ; //設(shè)置或返回線條的結(jié)束端點樣式 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(); //填充當(dāng)前繪圖(路徑) 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,通過學(xué)習(xí)canvas時鐘的代碼實現(xiàn),很能了解canvas的屬性和方法,同時,實現(xiàn)時鐘效果時,用到了數(shù)學(xué)中的幾何模型正弦sin和余弦cos以及弧度的計算方法,又重溫了一把當(dāng)年學(xué)數(shù)學(xué)時的許多樂趣,可謂是一舉兩得。
時鐘效果圖如下:
以上就是js基于canvas實現(xiàn)時鐘組件的詳細內(nèi)容,更多關(guān)于canvas實現(xiàn)時鐘組件的資料請關(guān)注服務(wù)器之家其它相關(guān)文章!
原文鏈接:https://www.cnblogs.com/tnnyang/p/8951804.html