canvas详解实战–时间表盘
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas--时间表盘</title>
</head>
<style>
*{
margin: 0;padding: 0;
}
#demo1{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
</style>
<body>
<canvas id="demo1" width="500" height="500"></canvas>
<script>
var pi = Math.PI // 半个圆,还可以理解为180°,但不等于,== Πr == 1/2Πd
// 获取画布对象
function init() {
var demo1 = document.getElementById('demo1')
var ctx = demo1.getContext('2d')
draw(ctx)
}
init()
// 重绘整个画布内容
// requestAnimationFrame--类似于定时器,不需要设置时间,按系统重绘时间执行
function draw(ctx) {
requestAnimationFrame(function step() {
clockDial(ctx)
times(ctx)
requestAnimationFrame(step)
})
}
// 绘制表盘
function clockDial(ctx) {
ctx.clearRect(0, 0, 500, 500); //清除所有内容,如没有这一步,之前绘制的图片会留下来,造成污染
ctx.save() // 将之前的画布状态设置等保存一下
ctx.translate(250,250) // 将画布的起点位置调整到 250,250 (原起点位置是0,0)
ctx.beginPath() // 开始绘制路径
ctx.arc(0,0,240,0,2*pi) // 画圆,在起点绘制半径为240的整圆,0和2pi是绘制圆的开始和结束角度
ctx.lineWidth= 2 // 设置绘制线条宽度
ctx.stroke() // 轮廓线显示--相当于边框 ,fill()是实心圆,颜色会填满整个区域
ctx.closePath() // 关闭路径 stroke()不会关闭路径--需要在调用closePath() ,fill()会关闭路径--不需要在调用closePath()
marks(ctx)
}
// 绘制刻度
function marks(ctx) {
for (let index = 0; index < 60; index++) {
ctx.save()
ctx.rotate(-pi/2 + index*pi/30) // 旋转x,y轴位置
ctx.beginPath()
ctx.moveTo(200,0) // 移动到该点,并以此为起点,开始绘制
ctx.lineTo(235,0) // 连接到该点
ctx.lineWidth = index % 5 ? 2 : 5 // 设置绘制线条宽度
ctx.strokeStyle=index % 5 ? '#ccc' : '#000' // 设置绘制线条颜色
ctx.stroke()
ctx.closePath()
ctx.restore() // 恢复到上一个save()保存的画布状态,设置等
}
ctx.restore()
}
// 计算时分秒绘制角度
function times(ctx) {
let seconds = new Date().getSeconds()
let minutes = new Date().getUTCMinutes()
let hours = new Date().getHours()
let initAngel = -pi/2
let sAngel = initAngel + pi/30*seconds
let mAngel = initAngel + pi/30*seconds/60 + pi/30*minutes
let hAngel = initAngel + hours *pi/6 + (pi/30*seconds/60 + pi/30*minutes)/12
drawTime(ctx,sAngel,200,2,'#ccc')
drawTime(ctx,mAngel,180,4,'#bbb')
drawTime(ctx,hAngel,160,6,'#aaa')
}
/**
* 根据当前时间调整角度绘制时分秒针
* ctx:画布对象
* angel:角度
* end:终点
* lineWidth:线宽
* lineWidth:线色
*/
function drawTime(ctx,angel,end,lineWidth,lineWidth) {
ctx.save()
ctx.translate(250,250)
ctx.rotate(angel)
ctx.beginPath()
ctx.moveTo(0,0)
ctx.lineTo(end,0)
ctx.lineWidth= lineWidth
ctx.strokeStyle = lineColor
ctx.stroke()
ctx.closePath()
ctx.restore()
}
</script>
</body>
</html>