canvas学习(十六):绘制时钟
昨天在慕课网学着用canvas绘制时钟(去看看),避免以后忘记就在这里做个记录。
先上个效果图吧:
这张图是静态的,实际上它是一个动态的时钟, 像平常看到的时钟一样,会一格一格走。
然后是需要掌握的数学知识:
知识点1:边与角的关系
这个是直角三角形中边与角的关系,比较好理解。不多说。
知识点2:弧度与角度的关系
通过以上两个知识点计算(x,y)的坐标:
那个角为什么是30度?一个圆总共是360度,一个表盘有12个小时也就是将360度平分为12分,那么每一份即为30度。
x = Math.cos(rad)*r
y = Math.sin(rad)*r
其中r为圆的半径,rad=2*Math.PI/360*30=2*Math.PI/12,即30度角对应的弧度数
知识点3:使用canvas绘制圆的开始角与结束角
这个知识点知道就好,因为后面的代码中有根据canvas的这个特性专门设置的代码顺序。
好啦,难的知识点就这些啦,其他有不懂的,可以去这个链接查看:HTML 5 Canvas 参考手册
具体代码如下:
页面结构:
<body> <div class="canvasDiv"> <canvas id="clock" width="300" height="300"> 您的浏览器不支持canvas,请换个浏览器试试 <!--这句话在支持canvas的浏览器中会被忽略,不支持的则会显示出来--> </canvas> </div> </body>
JS代码(直接写在body中):
var clockCanvas = document.getElementById("clock");
var cxt = clockCanvas.getContext("2d");//获取canvas的上下文环境
var width = cxt.canvas.width;//canvas的宽度
var height = cxt.canvas.height;//canvas的高度
var radius = width / 2;//圆的半径
var rem = width/300;//以canvas的宽度为300,外圆位10作为标准,计算比例
var lineWidth = 10*rem;//外圆的边线宽度
var r = radius - 30*rem;//小圆半径(各个小时数所在的圆)
var r2 = radius - 18*rem;//小圆半径(秒针跳动时对应的60个点所在的圆)
var r3 = 3*rem;//秒针跳动时对应的60个点的圆半径
var r4 = -radius+20*rem;
var fontSize = 20*rem;
console.log(clockCanvas+"\t"+cxt+"\t"+width+"\t"+height+"\t"+radius);
//小时数(因为画圆时起始角是从表盘中3点的位置开始画的,所以将开始位置设置成3)
var hourNumbers = [3,4,5,6,7,8,9,10,11,12,1,2];
window.onload=function(){
draw();
window.setInterval(draw,1000);//一秒钟绘制一次
}
//该方法用来绘制表盘
function drawBackground(){
cxt.save();
cxt.translate(radius,radius); //重新定位圆点坐标,定位到画布的中心
cxt.beginPath();
//1、画外圆
cxt.lineWidth = lineWidth;
cxt.arc(0,0,radius-lineWidth/2,0,2*Math.PI,false);///(radius-lineWidth/2)???
cxt.stroke();//绘制
//2、绘制小时数
hourNumbers.forEach(function (number,i){
//计算弧度
var rad = 2*Math.PI/12*i;//(2*Math.PI/12):每一度的弧度数
//计算每个数字的位置
var x = Math.cos(rad)*r;//cos30%=b/c ===>b=cos30%*c
var y = Math.sin(rad)*r;//sin30%=a/c ===>a=sin30%*c
//绘制数字
cxt.font=fontSize+"px Arial";//设置字体
cxt.textAlign="center";//设置文本内容的当前对齐方式:垂直居中(详解链接 :http://www.w3school.com.cn/tags/canvas_textalign.asp)
cxt.textBaseline="middle";//设置在绘制文本时使用的当前文本基线:这里设置为水平居中(详解链接:http://www.w3school.com.cn/tags/canvas_textbaseline.asp)
cxt.fillText(number,x,y);//绘制数字
});
//3、绘制秒针跳动时对应的60个点
for(var i=0;i<60;i++){
var rad = 2*Math.PI/60*i;//计算弧度
var x = Math.cos(rad)*r2;
var y = Math.sin(rad)*r2;
cxt.beginPath();
//当是小时数时小圆点为黑色,其他点为灰色
if(i%5==0){
cxt.fillStyle="#000";
}else{
cxt.fillStyle="#ccc";
}
cxt.arc(x,y,r3,2*Math.PI,false);
cxt.fill();
}
cxt.closePath();
}
/**
*该方法用来绘制时针
*@param hour:几点
*@param minute:分钟
*/
function drawHour(hour,minutes){
cxt.save();
cxt.beginPath();
var rad = 2*Math.PI/12*hour;//计算需要旋转的弧度
var mrad = 2*Math.PI/12/60*minutes;//2*Math.PI/12:标识一个时针点的弧度数,2*Math.PI/12/60:一个小时包括60分钟,也就是这一个弧度数被60个点平分
cxt.rotate(rad+mrad);
cxt.lineWidth = 6*rem;
cxt.lineCap = "round";//时针顶端的样式
cxt.moveTo(0,10);
cxt.lineTo(0,-radius/2);
cxt.stroke();
cxt.restore();
cxt.closePath();
}
/**
*该方法用来绘制分针
*@param minute:几分
*/
function drawMinute(minute){
cxt.save();
cxt.beginPath();
var rad = 2*Math.PI/60*minute;//计算需要旋转的弧度
cxt.rotate(rad);
cxt.lineWidth = 5*rem;
cxt.lineCap = "round";//时针顶端的样式
cxt.moveTo(0,10);
cxt.lineTo(0,-radius+42*rem);
cxt.stroke();
cxt.restore();
cxt.closePath();
}
/**
*该方法用来绘制秒针
*@param second:几秒
*/
function drawSecond(second){
cxt.save();
cxt.beginPath();
cxt.fillStyle="#c14543";
var rad = 2*Math.PI/60*second;//计算需要旋转的弧度
cxt.rotate(rad);
//秒针慢慢变小
cxt.moveTo(-2,20*rem);
cxt.lineTo(2,20*rem);
cxt.lineTo(1,r4);
cxt.lineTo(-1,r4);
cxt.fill();
cxt.restore();
cxt.closePath();
}
/**
*该方法用来绘制固定时针、分针和秒针的中心圆点
**/
function drawDot(){
cxt.beginPath();
cxt.fillStyle="#fff";
cxt.arc(0,0,4*rem,2*Math.PI,false);
cxt.fill();
cxt.closePath();
}
//该方法用来动态的绘制时钟
function draw(){
cxt.clearRect(0,0,width,height);//避免时针、分针、秒针每次跳动时前一帧依旧存在
var date = new Date();
var hour = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
drawBackground();
drawHour(hour,minute);
drawMinute(minute);
drawSecond(second);
drawDot();
cxt.restore();
}最后感谢老师的分享!
相关推荐
大地飞鸿 2020-11-12
星星有所不知 2020-10-12
jinxiutong 2020-07-26
MIKUScallion 2020-07-05
songfens 2020-07-05
songfens 2020-06-11
songfens 2020-06-08
northwindx 2020-05-31
northwindx 2020-05-31
northwindx 2020-05-27
northwindx 2020-05-25
MIKUScallion 2020-05-25
jinxiutong 2020-05-10
xdyangxiaoromg 2020-05-10
大地飞鸿 2020-05-06
northwindx 2020-04-25