• H5之canvas-绘制动态时钟


    使用<canvas>元素不是非常难,但需要一些基本的HTML和JavaScript知识。

    今天我们来利用canvas API绘制一个时钟,先上图:

    画图之前,先把思路捋一遍:首先分解一下这个时钟的图形,它是由表盘(圆形)和指针(直线)组成。

    canvas中圆形与矩形差距很大,canvas并没有提供专门绘制圆形的方法,但可以绘制圆弧,将圆弧首尾相连得到圆形

    arc( x , y , radius , 起始弧度 , 结束弧度 , 旋转方向)
    x,y --- 圆心坐标
    radius --- 半径
    弧度和角度的关系 --- 弧度 = 角度*Math.PI/180
    例:2π是360°(完整的圆形)
    旋转方向 --- true:逆时针;false:顺时针(默认)

    掌握画圆大法后,就可以着手施工了:

    首先准备好画布

    <canvas id="myClock" width="500" height="500"></canvas>

    接着获取上下文对象

    var canvas = document.getElementById('myClock');
    var con = canvas.getContext('2d');

    分解功能:

    1.表盘上的刻度(60个表示秒的刻度,12个表示小时的刻度)

    1.1 60个秒刻度-->360°/60-->6°一个小格

    //定义原点和半径
    var x = 250;
    var y = 250;
    var r = 150;
    con.moveTo(x,y);       
    con.arc(x,y,r,0,6*Math.PI/180);
    con.moveTo(x,y);
    con.arc(x,y,r,6*Math.PI/180,12*Math.PI/180);
    con.stroke();
    ……

    先来做个小实验,以上代码片段将会得到这个图形

    利用循环,将以上代码完善

    //定义原点和半径
    var x = 250;
    var y = 250;
    var r = 150;
    //绘制秒刻度开始
    con.beginPath();//为了不影响其他绘图,加上起始路径
    for (var i = 0; i < 60; i++) {
        con.moveTo(x, y); //以圆心为起点
        con.arc(x, y, r, 6 * i * Math.PI / 180, 6 * (i + 1) * Math.PI / 180);//绘制一段6°的圆弧
    }
    con.closePath(); //为了不影响其他绘图,加上起始路径
    con.stroke(); 

    此刻,得到如下图形

    怎么看怎么不像表盘咧?!为了达到秒刻度的效果,只需在上面覆盖一个较小的白色实心圆形即可

    //较小的白色圆盘
    con.beginPath();
    con.moveTo(x,y);
    con.arc(x,y,0.95*r,0,2*Math.PI);
    con.closePath();
    con.fillStyle = '#fff';//填充图形背景色
    con.fill(); //实心圆

    现在看上去,表盘的雏形算是出来了。

    同样的步骤,将小时刻度也画出来,为了区分小时刻度和秒刻度,可以加粗小时刻度的线条

    1.2 12个小时刻度-->360°/12-->30°一个大格

    con.beginPath();//为了不影响其他绘图,加上起始路径
    con.lineWidth = 4; //加粗小时刻度
    for(var i = 0;i<12;i++){
        con.moveTo(x,y);
        con.arc(x,y,r,30*i*Math.PI/180,30*(i+1)*Math.PI/180);
    }
    con.closePath(); //为了不影响其他绘图,加上起始路径
    con.stroke();

    最后,再叠加一个较小的白色实心圆心,表盘就画完了(最难的部分也搞定了)

    con.fillStyle = '#fff';
    con.beginPath();
    con.moveTo(x, y);
    con.arc(x, y, 0.85 * r, 0, 2 * Math.PI);
    con.closePath();
    con.fill();

     总得来说,画表盘就和化妆一样,需要层层叠加

    2.时、分、秒针

    //注意:考虑到针要以圆心为中心旋转
    con.lineWidth = 5; //定义时针线条的宽度
    con.beginPath();
    con.moveTo(x,y); //还是以圆心为起点
    con.arc(x,y,0.5*r,0,0);//此处半径即时针的长度
    con.closePath();
    con.stroke();

    分针和秒针就不做赘述,修改lineWidth的值和圆弧的半径即可

    3.让时钟走起来

    如何让秒针隔一秒动一下呢?是不是很快想到这个方法--->setInterval()

    ……
    //获取当前系统时间
    var today = new Date();
    var hh = today.getHours();
    var mm = today.getMinutes();
    var ss = today.getSeconds();
    //时针对应的弧度
    var hhVal = (-90 + hh * 30 + mm / 2)*Math.PI/180;
    //-90:canvas画圆的起始点在表盘的3个字,而时钟的起始点应在12个字。+mm/2:时针不会一直只在整点的位置,分针走30分钟,时针多走15°
    var mmVal = (-90 + mm * 6) * Math.PI / 180;
    var ssVal = (-90 + ss * 6) * Math.PI / 180;
    ……
    con.arc(x, y, 0.5 * r, hhVal, hhVal);
    ……
    //调用函数
    setInterval(toDraw, 1000);

    组合好代码后,时钟就能走起来了:(^-^)V

    奉上完整代码:

    HTML部分

    <canvas id="myClock" width="500" height="500"></canvas>
    <p id="showDate"></p>

    JavaScript部分

            window.onload = function () {
                //获取上下文对象
                var canvas = document.getElementById('myClock');
                var con = canvas.getContext('2d');
                //自定义函数---画表盘,针
                function toDraw() {
                    //定义原点和半径
                    var x = 250;
                    var y = 250;
                    var r = 150;
                    //绘制秒刻度开始
                    con.beginPath();
                    for (var i = 0; i < 60; i++) {
                        con.moveTo(x, y);//以圆心为起点
                        con.arc(x, y, r, 6 * i * Math.PI / 180, 6 * (i + 1) * Math.PI / 180);//绘制一段6°的圆弧
                    }
                    con.closePath(); //为了不影响其他绘图,加上起始路径
                    con.stroke();
                    //较小的白色圆盘
                    con.fillStyle = '#fff';
                    con.beginPath();
                    con.moveTo(x, y);
                    con.arc(x, y, 0.95 * r, 0, 2 * Math.PI);
                    con.closePath();
                    con.fill(); //实心圆
                    //绘制秒刻度结束
                    //同理绘制小时刻度
                    con.beginPath();
                    con.lineWidth = 4; //加粗小时刻度
                    for (var i = 0; i < 12; i++) {
                        con.moveTo(x, y);
                        con.arc(x, y, r, 30 * i * Math.PI / 180, 30 * (i + 1) * Math.PI / 180);
                    }
                    con.closePath(); //为了不影响其他绘图,加上起始路径
                    con.stroke();
                    //较小的白色圆盘
                    con.fillStyle = '#fff';
                    con.beginPath();
                    con.moveTo(x, y);
                    con.arc(x, y, 0.85 * r, 0, 2 * Math.PI);
                    con.closePath();
                    con.fill();
                    //绘制小时刻度结束
    
                    //获取当前系统时间
                    var today = new Date();
                    var hh = today.getHours();
                    var mm = today.getMinutes();
                    var ss = today.getSeconds();
                    document.getElementById('showDate').innerHTML = hh+':'+mm+':'+ss;
                    //时针对应的弧度
                    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;
                    //开始绘制时、分、秒针(注意:考虑到针要以原点为中心旋转)
                    con.lineWidth = 5; //时针
                    con.beginPath();
                    con.moveTo(x, y);
                    con.arc(x, y, 0.5 * r, hhVal, hhVal);
                    con.closePath();
                    con.stroke();
                    con.lineWidth = 3; //分针
                    con.beginPath();
                    con.moveTo(x, y);
                    con.arc(x, y, 0.65 * r, mmVal, mmVal);
                    con.closePath();
                    con.stroke();
                    con.lineWidth = 1; //秒针
                    con.beginPath();
                    con.moveTo(x, y);
                    con.arc(x, y, 0.8 * r, ssVal, ssVal);
                    con.closePath();
                    con.stroke();
                }
                //每隔1秒调用一次函数
                setInterval(toDraw, 1000);
            }    
  • 相关阅读:
    <trim>: prefix+prefixOverrides+suffix+suffixOverrides
    时间js
    form表单中name和id区别
    SQL 递归
    表单中Readonly和Disabled的区别
    jquery select取值,赋值操作
    ie11
    mongodb 学习资料
    H5 限制input只能输入数字
    http头部解释
  • 原文地址:https://www.cnblogs.com/laoli-note/p/11330332.html
Copyright © 2020-2023  润新知