使用canvas繪製時鐘並經過class面向對象

使用canvas繪製時鐘並經過class面向對象

一、思路分析

鐘錶可分爲靜止的刻度和動態的指針兩大部分
因爲指針具備動態性,必然須要定時器實時刷新清空並重繪
但刻度部分若是一塊兒清空並重繪會下降性能
所以可使用兩個重疊在一塊兒的canvas畫板來分別繪製兩個部分canvas

二、繪製錶盤步驟

2.一、首先獲取第一個面板的上下文:ide

var canvas1=document.getElementById("canvas1"); var ctx1=canvas1.getContext("2d");

2.二、因爲錶盤是由多個圓盤和兩種不一樣粗細的刻度組成的,所以先定義兩個函數
定義一個畫實心圓的函數函數

function drawDisk(radius,fillStyle){ ctx1.beginPath() ctx1.arc(150,150,radius,0,2*Math.PI) ctx1.fillStyle=fillStyle ctx1.fill() ctx1.closePath() }

定義一個畫刻度的函數性能

function drawScale(count){   ctx1.beginPath()   for(var i=0; i<count; i++){     ctx1.moveTo(150,150)     ctx1.arc(150,150,100,i*2*Math.PI/count,(i+1)*2*Math.PI/count)   }   ctx1.stroke()   ctx1.closePath() }

2.四、畫一個灰色的底盤
  drawDisk(100,"#ccc")
2.五、畫60個細的刻度
  drawScale(60)
2.六、畫一個白色的圓盤蓋住細刻度的多餘部分
  drawDisk(90,"white")
  
2.七、畫12個粗的刻度
  drawScale(12)
2.八、畫一個白色的圓盤蓋住粗刻度的多餘部分
  drawDisk(80,"white")
2.九、畫一個黑色的小圓點做爲鐘錶的中心
  drawDisk(5,"black")this

 

三、繪製錶針步驟

3.一、首先獲取第二個面板的上下文:
var canvas2=document.getElementById("canvas2");
var ctx2=canvas2.getContext("2d");
3.二、定義一個畫針的函數
function drawHand(radius,deg,lineWidth){
ctx2.beginPath()
ctx2.moveTo(150,150)
ctx2.arc(150,150,radius,deg,deg)
ctx2.lineWidth=lineWidth
ctx2.lineCap= "round"
ctx2.stroke()
ctx2.closePath()
}
3.三、開啓定時器實時刷新鐘錶指針
setInterval(function(){
var d=new Date();
var h=d.getHours();
var m=d.getMinutes();
var s=d.getSeconds();
//console.log(h,m,s)
ctx2.clearRect(0,0,300,300)
drawHand(50,h*30*Math.PI/180+m*0.5*Math.PI/180-0.5*Math.PI,5) //時針
drawHand(68,m*6*Math.PI/180-0.5*Math.PI,3) //分針
drawHand(80,s*6*Math.PI/180-0.5*Math.PI,2) //秒針
},1000)

四、面向對象封裝思路

a.整個鐘錶可視爲一個對象
b.鐘錶有4個實心圓、2種刻度和3根指針做爲鐘錶的9個屬性
c.鐘錶有一個繪製的方法
d.實心圓、刻度、指針又可視爲一個對象,它們也應該有一個繪製方法

五、封裝對象

5.一、封裝實心圓對象
class Disk {
/**
* 實心圓構造器
* @param [Object] ctx 畫布上下文對象
* @param [Number] radius 實心圓半徑
* @param [String] fillStyle 實心圓顏色樣式
*/
constructor(ctx = null, radius = 10, fillStyle = "red") {
this.ctx = ctx
this.radius = radius
this.fillStyle = fillStyle
}
/**
* 實心圓繪製方法
* @param [Number] cX 圓心X座標
* @param [Number] cY 圓心Y座標
*/
drawDisk(cX, cY) {
this.ctx.beginPath()
this.ctx.arc(cX, cY, this.radius, 0, 2 * Math.PI)
this.ctx.fillStyle = this.fillStyle
this.ctx.fill()
this.ctx.closePath()
}
}
5.二、封裝刻度對象
class Scale {
/**
* 刻度構造器
* @param [Object] ctx 畫布上下文對象
* @param [Number] count 刻度的個數
*/
constructor(ctx = null, count = 600) {
this.ctx = ctx
this.count = count
}
/**
* 刻度繪製方法
* @param [Number] cX 刻度所在圓的圓心X座標
* @param [Number] cY 刻度所在圓的圓心Y座標
* @param [Number] radius 刻度所在圓的半徑
*/
drawScale(cX, cY, radius) {
this.ctx.beginPath()
for (var i = 0; i < this.count; i++) {
this.ctx.moveTo(cX, cY)
this.ctx.arc(cX, cY, radius, i * 2 * Math.PI / this.count, (i + 1) * 2 * Math.PI / this.count)
}
this.ctx.stroke()
this.ctx.closePath()
}
}
5.三、封裝錶盤指針對象
class Hand {
/**
* 鐘錶指針類構造器
* @param [Object] ctx 畫布上下文對象
* @param [Number] length 指針長度
* @param [Number] lineWidth 指針寬度
* @param [String] strokeStyle 指針顏色樣式
*/
constructor(ctx = null, length = 20, lineWidth = 2, strokeStyle = "black") {
this.ctx = ctx
this.length = length
this.lineWidth = lineWidth
this.strokeStyle = strokeStyle
}
/**
* 指針繪製方法
* @param cX
* @param cY
* @param deg
*/
drawHand(cX, cY, deg) {
this.ctx.beginPath()
this.ctx.moveTo(cX, cY)
this.ctx.arc(cX, cY, this.length, deg, deg)
this.ctx.lineWidth = this.lineWidth
this.ctx.strokeStyle = this.strokeStyle
this.ctx.lineCap = "round"
this.ctx.stroke()
this.ctx.closePath()
}
}
5.四、封裝鐘錶對象
class Clock {
/**
* 鐘錶類構造器
* @param [Object] ctx1 指針畫布上下文對象
* @param [Object] ctx2 錶盤畫布上下文對象
* @param [Number] cX 鐘錶圓心X左標
* @param [Number] cY 鐘錶圓心Y左標
* @param [Number] radius 鐘錶半徑
*/
constructor(ctx1 = null, ctx2 = null, cX = 100, cY = 100, radius = 100) {
this.ctx1 = ctx1
this.ctx2 = ctx2
this.cX = cX
this.cY = cY
this.radius = radius
this.bigDisk = new Disk(this.ctx1, this.radius, "#ccc")
this.midDisk = new Disk(this.ctx1, this.radius * 0.9, "white")
this.smallDisk = new Disk(this.ctx1, this.radius * 0.8, "white")
this.dotDisk = new Disk(this.ctx2, 5, "red")
this.thinScale = new Scale(this.ctx1, 60) /*60個細刻度*/
this.wideScale = new Scale(this.ctx1, 12) /*12個粗刻度*/
this.hHand = new Hand(this.ctx2, this.radius * 0.5, 6)
this.mHand = new Hand(this.ctx2, this.radius * 0.68, 4)
this.sHand = new Hand(this.ctx2, this.radius * 0.8, 2, 'red')
}
/**
* 鐘錶繪製方法
*/
drawClock() {
this.bigDisk.drawDisk(this.cX, this.cY) /*畫底盤*/
this.thinScale.drawScale(this.cX, this.cY, this.radius) /*畫60個細的刻度*/
this.midDisk.drawDisk(this.cX, this.cY) /*畫一個圓盤蓋住細刻度的多餘部分*/
this.wideScale.drawScale(this.cX, this.cY, this.radius) /*畫12個粗的刻度*/
this.smallDisk.drawDisk(this.cX, this.cY) /*畫一個圓盤蓋住粗刻度的多餘部分*/
/**
* 鐘錶指針重繪函數
*/
let renewHand=()=> {
var d = new Date()
var h = d.getHours()
var m = d.getMinutes()
var s = d.getSeconds()
//console.log(h,m,s)
this.ctx2.clearRect(this.cX - this.radius, this.cY - this.radius, this.radius * 2, this.radius * 2)
this.hHand.drawHand(this.cX, this.cY, h * 30 * Math.PI / 180 + m * 0.5 * Math.PI / 180 - 0.5 * Math.PI) //時針
this.mHand.drawHand(this.cX, this.cY, m * 6 * Math.PI / 180 - 0.5 * Math.PI) //分針
this.sHand.drawHand(this.cX, this.cY, s * 6 * Math.PI / 180 - 0.5 * Math.PI) //秒針
this.dotDisk.drawDisk(this.cX, this.cY) //畫一個小圓點做爲鐘錶的中心
}
renewHand()
setInterval(renewHand, 1000)
}
}

六、實例化鐘錶對象

var canvas3=document.getElementById("canvas3");var ctx3=canvas3.getContext("2d");var canvas4=document.getElementById("canvas4");var ctx4=canvas4.getContext("2d");var clock = new Clock(ctx3,ctx4,150,150,100);clock.drawClock();這種繪製鐘錶的方法能夠根據需求定製鐘錶的一些屬性而後再調用繪製方法   clock.bigDisk.fillStyle="yellow"   clock.smallDisk.fillStyle="#3f3"   clock.sHand.strokeStyle="pink"   clock.mHand.strokeStyle="#a0aea0"   clock.hHand.strokeStyle="red"
相關文章
相關標籤/搜索