canvas 时钟

在慕课上看到有老师讲解canvas画时钟;本身也来研究一下;html

canvas clockcanvas

首先建立一个canvas浏览器

<canvas id='canvas' width="400" height="400">
    你的浏览器不支持canvas,请升级你的浏览器
</canvas>

设置画布大小为400*400,能够在标签中输入不支持canvas的提示,提示浏览者;spa

而后开始操做canvas,先获取canvas对象,而后获取canvas的操做环境getContextrest

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d')

这里知识前置一下,由于canvas绘画只有一个进程(即上下文),要开始一个新的绘画,必须把当前的绘画结束了;因此 save 和 restore方法一般都成对出现;由于每次画新的路径时,都要把以前的绘画给保存下来,结束后再把以前保存的状态返回;code

每次新路径须要调beginpath方法;htm

代码中出现每次须要画新的路径时,能够用save保存,画好了,再restore;这样的作法可让canvas保持每次绘画都是以初始化为标准去绘画;对象

由于是画时钟,为了方便定位,先把canvas的原点设置为画布的中心;blog

ctx.translate(canvasW/2,canvasW/2);

在设置好原点后,能够进行背景的描绘,在写的过程当中,能够查阅canvas参考手册进程

传送门:canvas参考手册

//绘制背景
ctx.save();
        ctx.rotate(Math.PI/2);
        //背景颜色块
        ctx.fillStyle = '#f2f2f0';
        ctx.fillRect(-200,-200,110,400);
        ctx.beginPath();
        ctx.fillStyle = '#b0b2b9';
        ctx.fillRect(-90,-200,180,400);
        ctx.beginPath();
        ctx.fillStyle = '#f2f2f0';
        ctx.fillRect(90,-200,110,400);
        //时钟外框
        ctx.beginPath();
        ctx.arc(0,0,R,0,2*Math.PI);
        ctx.lineWidth = 7;    //设置线条宽
        ctx.strokeStyle = '#9b9ca3';
        ctx.stroke();
        //时钟背景
        ctx.beginPath();
        var myGradient = ctx.createRadialGradient(0, 0, 0, 0,0,75);
        myGradient.addColorStop(0, "#fff");
        myGradient.addColorStop(1, "#eceef0");
        ctx.fillStyle = myGradient;
        ctx.arc(0,0,R,0,2*Math.PI);
        ctx.fill();
        ctx.restore();

因为canvas画圆是以X轴的正方向为起始点,即三点钟方向,因此为了方便画图,能够把canvas一开始就旋转90度,旋转到12点方向;

//将坐标轴逆时针旋转90度,x轴正方向对准12点方向
ctx.rotate(-Math.PI/2);

在画背景的时候方即可以把canvas还原以便画图

ctx.rotate(Math.PI/2);

描绘好背景以后能够描绘大时钟的刻度,大刻度每90度就是一个大的时刻,这个时钟有大小两个刻度,其实同理;

//刻度

for (var i = 0; i < 60; i++) {
    ctx.save();
    ctx.beginPath();
    //设置线条的宽度
    ctx.lineWidth = 1;
    //设置线条的颜色
    ctx.strokeStyle = "#999";
    ctx.moveTo(countX(clockR,i), countY(clockR,i));
    if (i % 15 != 0){
        ctx.lineTo(countX(clockR + 5,i), countY(clockR+5,i));
    } else {
        ctx.lineTo(countX(clockR + 17,i), countY(clockR+17,i));
    }
    ctx.stroke();
    ctx.restore();
}

这里countX和countY两个函用来求每一个刻度的起始点,即X坐标和Y坐标;

//计算X轴坐标
    function countX(radii, angle, percent){
        if (!radii || (typeof angle == 'undefined')){
            return;
        }
        var _width = radii * Math.cos(Math.PI / (percent || 30) * angle);
        return _width;
    }
    
    //计算Y轴坐标
    function countY(radii, angle, percent){
        if (!radii || (typeof angle == 'undefined')){
            return;
        }
        var _height = radii * Math.sin(Math.PI / (percent || 30) * angle);
        return _height;
    }

祭个图好明白一些

clipboard.png

B点的y坐标为 y = 半径 * Math.sin(角度);(邻边对斜边)
B点的x坐标为 x = 半径 * Math.cos(角度);(对边对斜边)

画好刻度,就能够画分针,秒针和时针了,其实都是同一个原理,在这里讲解一下分针;

//分针
        ctx.save();
        ctx.beginPath();
        ctx.lineWidth = 3;
        ctx.strokeStyle = '#0a1227';
        //"round" 和 "square" 会使线条略微变长。
        //设置canvas末端样式
        ctx.lineCap = 'round';
        ctx.moveTo(countX(MinR,opt.min + opt.sec/60), countY(MinR,opt.min + opt.sec/60));
        ctx.lineTo(countX(MinR + 55,opt.min + opt.sec/60), countY(MinR + 55,opt.min + opt.sec/60));
        ctx.stroke();
        ctx.restore();

分针这里会跟着秒针的滚动而滚动,所加上了sec/60,秒针值向的百分比;

相关文章
相关标签/搜索