Canvas实战:使用Canvas绘制时钟
钟类
class Clock {
private ctx
// 中心点
private center: { x: number; y: number }
constructor(private canvas: HTMLCanvasElement, private radius: number) {
this.canvas = canvas
this.ctx = canvas.getContext('2d')!
// 钟的半径
this.radius = radius
this.center = { x: this.canvas.width / 2, y: this.canvas.height / 2 }
}
draw() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
}
}
绘制时钟边框和圆心
// 绘制时钟边框和圆心
drawClockCircle() {
// 绘制时钟边框,即一个圆
this.ctx.beginPath()
this.ctx.arc(this.center.x, this.center.y, this.radius, 0, 2 * Math.PI)
this.ctx.closePath()
this.ctx.strokeStyle = '#000'
this.ctx.stroke()
// 绘制圆心
this.ctx.beginPath()
this.ctx.arc(this.canvas.width / 2, this.canvas.height / 2, 6, 0, 2 * Math.PI)
this.ctx.closePath()
this.ctx.fillStyle = '#000'
this.ctx.fill()
}
绘制1~12的数字
// 绘制1~12的数字
drawClockDial() {
this.ctx.save()
// 将原点移动到中心点
this.ctx.translate(this.center.x, this.center.y)
// 设置一些文字的基础样式
this.ctx.textBaseline = 'middle'
this.ctx.font = '20px'
this.ctx.textAlign = 'center'
// 偏移量,不然会与后续数字重叠
const offset = 24
const r = this.radius - offset
for (let i = 1; i <= 12; i++) {
const angel = (360 / 12) * i
// 转弧度
const radian = (angel / 180) * Math.PI
const x = r * Math.sin(radian)
const y = -r * Math.cos(radian)
this.ctx.fillText(`${i}`, x, y)
}
this.ctx.restore()
}
绘制刻度线
包括绘制小时线(共12根)和分钟线(共60根)
// 绘制刻度线
drawClockMark() {
// 画小时线
this.ctx.save()
// 将原点移动到中心点
this.ctx.translate(this.center.x, this.center.y)
this.ctx.lineWidth = 4
for (let i = 1; i <= 12; i++) {
this.ctx.beginPath()
this.ctx.moveTo(this.radius, 0)
this.ctx.lineTo(this.radius - 10, 0)
this.ctx.rotate((30 * Math.PI) / 180)
this.ctx.stroke()
}
this.ctx.restore()
// 画分钟线
this.ctx.save()
// 将原点移动到中心点
this.ctx.translate(this.center.x, this.center.y)
this.ctx.lineWidth = 2
for (let i = 0; i < 60; i++) {
this.ctx.beginPath()
this.ctx.moveTo(this.radius, 0)
this.ctx.lineTo(this.radius - 6, 0)
this.ctx.rotate((6 * Math.PI) / 180)
this.ctx.stroke()
}
this.ctx.restore()
}
绘制时针、分针和秒针
绘制时针
// 绘制时针
drawHour() {
this.ctx.save()
// 将原点移动到中心点
this.ctx.translate(this.center.x, this.center.y)
this.ctx.lineWidth = 5
const r = this.radius - 60
const now = new Date()
const hours = now.getHours()
const minutes = now.getMinutes()
const angel = (360 / 12) * (hours % 12) + 30 * (minutes / 60)
// 转弧度
const radian = (angel / 180) * Math.PI
const x = r * Math.sin(radian)
const y = -r * Math.cos(radian)
this.ctx.beginPath()
this.ctx.moveTo(0, 0)
this.ctx.lineTo(x, y)
this.ctx.closePath()
this.ctx.stroke()
this.ctx.restore()
}
绘制分针和秒针 绘制分钟和秒针的方法是很类似的,只分针和秒针的角度和宽度长度的参数不同,我们通过上面绘制时针的方法封装为通用方法。
// 绘制时针分针和秒针的通用方法
drawClockHand(angel: number, lineWidth: number, length: number) {
this.ctx.save()
// 将原点移动到中心点
this.ctx.translate(this.center.x, this.center.y)
this.ctx.lineWidth = lineWidth
// 转弧度
const radian = (angel / 180) * Math.PI
const x = length * Math.sin(radian)
const y = -length * Math.cos(radian)
this.ctx.beginPath()
this.ctx.moveTo(0, 0)
this.ctx.lineTo(x, y)
this.ctx.closePath()
this.ctx.stroke()
this.ctx.restore()
}
// 绘制时针
drawHour() {
const now = new Date()
const hours = now.getHours()
const minutes = now.getMinutes()
const angel = (360 / 12) * (hours % 12) + 30 * (minutes / 60)
this.drawClockHand(angel, 5, this.radius - 60)
}
// 绘制分针
drawMinute() {
const now = new Date()
const minutes = now.getMinutes()
const seconds = now.getSeconds()
const angel = 360 * (minutes / 60) + 6 * (seconds / 60)
this.drawClockHand(angel, 4, this.radius - 40)
}
// 绘制分针
drawSecond() {
const now = new Date()
const seconds = now.getSeconds()
const angel = 360 * (seconds / 60)
this.drawClockHand(angel, 2, this.radius - 20)
}
让时针动起来
转载自:https://juejin.cn/post/7244466524559573053