使用h5 canvas-绘制时钟
学习完canvas之后,突发奇想,使用canvas api 绘制一个时钟。
话不多说,先上图:
为了突出各个元素,使用不同的颜色表示,虽然有点花花绿绿,但我觉得还挺ok。
画图之前,首先我们需要分析一下时钟的构造:表盘(刻度,圆盘)+指针(时针,分针,秒针)
首先准备好画布
<canvas id="mycanvas" width="500" height="500px"></canvas>
然后初始化画布
//获取画布元素
var canvas = document.getElementById("mycanvas");
//画布尺寸
var W = canvas.clientWidth;
var H = canvas.clientHeight;
//半径
var r = 200;
canvas.style.background = "#ccc";
//获取上下文
var ctx = canvas.getContext("2d");
第一步,绘制表盘
我们利用 arc(x,y.radius,起始弧度,结束弧度,旋转方向) 绘制圆弧
x,y --- 圆心坐标
radius --- 半径
弧度和角度的关系 --- 弧度 = 角度*Math.PI/180
旋转方向 --- true:逆时针;false:顺时针(默认)
//表盘外径
ctx.beginPath();
ctx.lineWidth = 10;
ctx.arc(W / 2, H / 2, r, 0, 2 * Math.PI);
ctx.stroke();
ctx.fillStyle="#fff";
ctx.closePath();
ctx.fill();
如图:
通过封装函数剔除重复代码
//刻度封装函数
function getScaleMark(rad, lineWidth) {
ctx.save();
ctx.beginPath();
for (var i = 0; i < 60; i++) {
ctx.lineWidth = lineWidth;
ctx.moveTo(W / 2, H / 2);
ctx.arc(W / 2,H / 2,r,(rad * i * Math.PI) / 180,(rad * (i + 1) * Math.PI) / 180
);
}
ctx.closePath();
ctx.stroke();
}
//小刻度
getScaleMark(6,2);
如图:
//大刻度
getScaleMark(30,5);
如图:
为了显示出所需刻度,需要绘制两个圆覆盖掉中间区域
//圆盘小刻度截断
ctx.save();
ctx.beginPath();
ctx.arc(W/2,H/2,0.95*r,0,2*Math.PI);
ctx.fillStyle='#ffffff'
ctx.closePath();
ctx.fill();
如图:
//圆盘大刻度截断
ctx.beginPath();
ctx.arc(W/2,H/2,0.9*r,0,2*Math.PI);
ctx.fillStyle='#ffffff'
ctx.closePath();
ctx.fill();
如图:
第二步,绘制指针
首先,指针是绕着圆心旋转,利用moveTo以圆心为起点,绘制指针
//秒
ctx.save();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle='#f0f'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.85 * r, 0, 0);
ctx.closePath();
ctx.stroke();
//分
ctx.save();
ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle='#fc0'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.7 * r, -90*Math.PI/180, -90*Math.PI/180);
ctx.closePath();
ctx.stroke();
//时针
ctx.save();
ctx.beginPath();
ctx.lineWidth = 7
ctx.strokeStyle='#f00'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.5 * r, -70*Math.PI/180, -70*Math.PI/180);
ctx.closePath();
ctx.stroke();
//圆心
ctx.save();
ctx.beginPath();
ctx.arc(W/2,H/2,0.03*r,0,2*Math.PI);
ctx.fillStyle="#000"
ctx.closePath();
ctx.fill();
如图:
最后,我们需要燃时钟动起来,运用setInterval();
...
//获取当前系统时间
var nowDate = new Date();
//小时
var hh = nowDate.getHours()>12?nowDate.getHours()-12:nowDate.getHours();
var mm = nowDate.getMinutes();
var ss = nowDate.getSeconds();
//相应刻度
var hhVal = (-90+hh*30+mm/2)*Math.PI/180;
var mmVal = (-90+mm*6)*Math.PI/180;
var ssVal = (-90+ss*6)*Math.PI/180;
//秒
ctx.save();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle='#f0f'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.85 * r, ssVal, ssVal);
ctx.closePath();
ctx.stroke();
//分
ctx.save();
ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle='#fc0'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.7 * r, mmVal, mmVal);
ctx.closePath();
ctx.stroke();
//时针
ctx.save();
ctx.beginPath();
ctx.lineWidth = 7
ctx.strokeStyle='#f00'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.5 * r, hhVal, hhVal);
ctx.closePath();
ctx.stroke();
...
setInterval(toDraw,1000);
完成之后,时钟就能动起来了。
完整代码如下:
HTML:
<canvas id="mycanvas" width="500" height="500px"></canvas>
Javascript:
//获取画布元素
var canvas = document.getElementById("mycanvas");
//画布尺寸
var W = canvas.clientWidth;
var H = canvas.clientHeight;
//半径
var r = 200;
canvas.style.background = "#ccc";
//创建2d画笔
var ctx = canvas.getContext("2d");
function toDraw(){
ctx.save();
ctx.clearRect(0,0,W,H);
//表盘外径
ctx.beginPath();
ctx.strokeStyle = "#00ffff";
ctx.lineWidth = 10;
ctx.arc(W / 2, H / 2, r, 0, 2 * Math.PI);
ctx.stroke();
ctx.fillStyle="#fff";
ctx.closePath();
ctx.fill();
//小刻度
getScaleMark(6,2);
//圆盘刻度截断
ctx.save();
ctx.beginPath();
ctx.arc(W/2,H/2,0.95*r,0,2*Math.PI);
ctx.fillStyle='#ffffff'
ctx.closePath();
ctx.fill();
//时钟刻度
getScaleMark(30,5);
//圆盘刻度截断
ctx.beginPath();
ctx.arc(W/2,H/2,0.9*r,0,2*Math.PI);
ctx.fillStyle='#ffffff'
ctx.closePath();
ctx.fill();
ctx.save();
//获取当前系统时间
var nowDate = new Date();
//小时
var hh = nowDate.getHours()>12?nowDate.getHours()-12:nowDate.getHours();
var mm = nowDate.getMinutes();
var ss = nowDate.getSeconds();
//相应刻度
var hhVal = (-90+hh*30+mm/2)*Math.PI/180;
var mmVal = (-90+mm*6)*Math.PI/180;
var ssVal = (-90+ss*6)*Math.PI/180;
//秒
ctx.save();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle='#f0f'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.85 * r, ssVal, ssVal);
ctx.closePath();
ctx.stroke();
//分
ctx.save();
ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle='#fc0'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.7 * r, mmVal, mmVal);
ctx.closePath();
ctx.stroke();
//时针
ctx.save();
ctx.beginPath();
ctx.lineWidth = 7
ctx.strokeStyle='#f00'
ctx.moveTo(W/2, H/2);
ctx.arc(W/2, H/2, 0.5 * r, hhVal, hhVal);
ctx.closePath();
ctx.stroke();
//圆心
ctx.save();
ctx.beginPath();
ctx.arc(W/2,H/2,0.03*r,0,2*Math.PI);
ctx.fillStyle="#000"
ctx.closePath();
ctx.fill();
}
setInterval(toDraw,1000)
//刻度封装函数
function getScaleMark(rad, lineWidth) {
ctx.save();
ctx.beginPath();
for (var i = 0; i < 60; i++) {
ctx.lineWidth = lineWidth;
ctx.moveTo(W / 2, H / 2);
ctx.arc(W / 2,H / 2,r,(rad * i * Math.PI) / 180,(rad * (i + 1) * Math.PI) / 180);
}
ctx.closePath();
ctx.stroke();
}
- 点赞
- 收藏
- 关注作者
评论(0)