zoukankan      html  css  js  c++  java
  • 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);
            }    
  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/laoli-note/p/11330332.html
Copyright © 2011-2022 走看看