H5新增canvas标签+js绘制动态时钟效果-代码

画图之前,先把思路捋一遍:首先分解一下这个时钟的图形,它是由表盘(圆形)和指针(直线)组成 罗马数字。
canvas中圆形与矩形差距很大,canvas并没有提供专门绘制圆形的方法,但可以绘制圆弧,将圆弧首尾相连得到圆形

分解 

附完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        #canvas {
            border: 1px solid red;
        }
    </style>
</head>

<body>
    <canvas id="canvas">您的浏览器不支持canvas,请升级dyh</canvas>
    <script>
        let canvas = document.getElementById('canvas');
        let ctx = canvas.getContext('2d');//获取画笔对象

        function drawClock() {
            // 初始化变量
            let x, y, r, width, height;
            width = 600;//画布大小
            height = 600;
            canvas.width = width;
            canvas.height = height;
            x = width / 2;//圆心
            y = height / 2;
            r = 200; //半径

            let t = new Date();//获取时间 dyh
            let oHour = t.getHours();
            let oMin = t.getMinutes();
            let oSec = t.getSeconds();

            //3 时针,分针,秒针的弧度和时间的关系换算 dyh
            // 30 分 +15°  30/2 = 15
            // 30 秒 +3°    30/10 =3
            let hourAngle = (-90 + oHour * 30 + oMin / 2) / 180 * Math.PI;//0度是水平方向
            let minAngle = (-90 + oMin * 6 + oSec / 10) / 180 * Math.PI;
            let secAngle = (-90 + oSec * 6) / 180 * Math.PI;
            // 清除画布
            ctx.clearRect(x, y, width, height);

            // 1 画 分针/[秒针]刻度 60
            ctx.beginPath();//开启路径
            for (let i = 0; i <= 60; i++) {//360度  一个刻度6度  6*60 = 360
                ctx.moveTo(x, y);
                ctx.arc(x, y, r, i * 6 / 180 * Math.PI, (i + 1) * 6 / 180 * Math.PI, false);
                // ctx.closePath()
            }
            ctx.stroke();//描边

            // 2 以x,y为圆心。绘制360度的饼图,白色填充  dyh
            ctx.beginPath();
            ctx.fillStyle = 'white';
            ctx.arc(x, y, r * 19 / 20, 0, 2 * Math.PI, false);
            ctx.fill();

            // 3 画12个时针可达
            ctx.beginPath();
            ctx.lineWidth = 3;
            for (let i = 0; i <= 12; i++) {// 1刻种 30°
                ctx.moveTo(x, y);
                ctx.arc(x, y, r, i * 30 / 180 * Math.PI, (i + 1) * 30 / 180 * Math.PI, false);
            }
            ctx.stroke();

            // 4 以x,y为圆心。绘制360度的饼图,白色填充 处理时针 dyh
            ctx.beginPath();
            ctx.fillStyle = 'white';
            ctx.arc(x, y, r * 18 / 20, 0, 2 * Math.PI, false);
            ctx.fill();

            // 5 画时针、分针、秒针
            // 参考画扇形的方法绘制时针、分针和秒针( 起始角度和结束角度重合正好是一个线 )
            // 5.1 秒针
            ctx.beginPath();
            ctx.lineWidth = 2;
            ctx.moveTo(x, y);
            ctx.arc(x, y, r * 18 / 20, secAngle, secAngle, false);
            ctx.stroke();

            // 5.2 分针
            ctx.beginPath();
            ctx.lineWidth = 3;
            ctx.moveTo(x, y);
            ctx.arc(x, y, r * 16 / 20, minAngle, minAngle, false);
            ctx.stroke();

            // 5.3 时针
            ctx.beginPath();
            ctx.lineWidth = 4;
            ctx.moveTo(x, y);
            ctx.arc(x, y, r * 13 / 20, hourAngle, hourAngle, false);
            ctx.stroke();

            // 6 画中心圆点
            ctx.beginPath();
            ctx.strokeStyle = 'red';
            ctx.lineWidth = 3;
            ctx.arc(x, y, 8, 0, 2 * Math.PI, false);
            ctx.fillStyle = 'white';
            ctx.fill();
            ctx.stroke();

            // 7 绘制数字 
            ctx.save();//保存操作之前的状态 dyh
 
            let hourNums = ['Ⅲ', 'Ⅳ', 'Ⅴ', 'Ⅵ', 'Ⅶ', 'Ⅷ', 'Ⅸ', 'X', 'Ⅺ', 'Ⅻ', 'Ⅰ', 'Ⅱ'];
            ctx.translate(x, y);//改变原点位置为圆心 dyh

            ctx.fillStyle = '#999';
            ctx.font = '20px 楷体';
            ctx.textAlign = 'center';//水平对齐方式
            ctx.textBaseline = 'middle';//垂直对齐方式
            hourNums.forEach((number, i) => {
                let rad = i * 30 / 180 * Math.PI;
                let tX = Math.cos(rad) * r * 17 / 20;
                let tY = Math.sin(rad) * r * 17 / 20;
                ctx.fillText(number, tX, tY);
            })
            ctx.restore();

            // 8 绘制品牌文字
            ctx.beginPath();
            ctx.fillStyle = '#000';
            ctx.textAlign = 'center';//默认对齐方式start dyh
            ctx.font = '30px 楷体';
            ctx.fillStyle = 'red';
            ctx.fillText("Jackie Hao", x, r * 20 / 20);

        }
        drawClock();//调用
        setInterval(drawClock, 1000);//设置定时器
    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/JackieDYH/article/details/107696695