欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-11 09:50:05
...

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

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

分解 

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

附完整代码

<!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>