效果展示:

源码展示:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>canvas绘制时钟</title>
    <style>
        * {
            margin:0;
            padding:0;
        }
        canvas {
            display:block;
            margin:200px auto;
        }
    </style>
</head>
<body>
<canvas id="clock" width="200px" height="200px"></canvas>
 
<script>
    var dom = document.getElementById('clock');
    var ctx = dom.getContext('2d');
    var width = ctx.canvas.width;
    var height = ctx.canvas.height;
    var r = width / 2;
    var rem = width / 200;
    //无论canvas画布多大 时钟都会随着比例变化
 
    function drawBackground() {
 
        ctx.save();
        //保存当前画布 以便使用clearRect()
 
        /*****************绘制背景圆****************************/
 
        ctx.translate(r, r);
        //把绘图的中心移动到坐标为(r,r)的位置
 
        ctx.beginPath();
        //开始绘图
 
        ctx.lineWidth = 10 * rem;
        //线条宽度
 
 
        ctx.arc(0, 0, r - ctx.lineWidth / 2, 0, 2 * Math.PI, false);
        //绘制一个圆坐标为刚刚移动到的位置  因为半径为canvas正方形的一半所以半径要减去线条宽度的一半
 
        ctx.stroke();
        //绘制
 
        /****************绘制小时点********************************/
        var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
        //定义一个小时点数组  因为圆的起点是90度那个位置开始的
 
        ctx.font = 18 * rem + 'px Arial';
        //设置字体大小
 
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        //设置文本的对齐方式 文本对齐居中 文本基线居中对齐
 
        hourNumber.forEach(function(number, i) { //遍历并获取该数组 传入参数 一个为数字 一个是索引
 
            var rad = 2 * Math.PI / 12 * i;
            //定义弧度 12个数字 相差就是 2*Math.PI / 12 这就是每个小时数的弧度  再乘以索引以对应弧度的计算
 
            var x = Math.cos(rad) * (r - 30 * rem);
            //求x坐标 用cos方法 在乘以半径 因为小时点的半径肯定会小一些所以就半径也要小一点
 
            var y = Math.sin(rad) * (r - 30 * rem);
            //求y坐标 方法同上
 
            ctx.fillText(number, x, y);
            //填充文本 第一个参数是 文本 第二,三个为坐标
        });
 
        /************绘制分钟点**********************/
        for (var i = 0; i < 60; i++) {
            //利用for循环遍历60个点
 
            var rad = 2 * Math.PI / 60 * i;
            //定义弧度60个点
 
            var x = Math.cos(rad) * (r - 18 * rem);
            //定义x坐标的位置 方法同上
 
            var y = Math.sin(rad) * (r - 18 * rem);
            //定义y坐标的位置 方法同上
 
            ctx.beginPath();
            //因为上面有过beginPath所以需要重新绘制
 
            if (i % 5 === 0) {
                //因为小时点是每隔5个就有一个所以 如果i取余等于0 就是小时数 小时点的样式带啊如下
                ctx.fillStyle = "black"
                ctx.arc(x, y, 2 * rem, 0, 2 * Math.PI, false);
                //绘制圆 半径为2像素
            } else {
                //反过来就是这样
                ctx.fillStyle = "#ccc";
                ctx.arc(x, y, 2 * rem, 0, 2 * Math.PI, false);
                //绘制圆 半径为2像素
            }
            ctx.fill();
            //因为需要实心圆 所以需要填充
 
        }
 
    }
    /****************绘制时针*************/
 
    function drawHour(hour, minute) {
        //绘制时针
 
        ctx.save();
        //save()和restore连用 表示先将其绘图环境保存起来 restore返回之前保存的状态
 
        ctx.beginPath();
 
        var rad = 2 * Math.PI / 12 * hour;
        //设置时针的位置 定义弧度
 
        var mrad = 2 * Math.PI / 12 / 60 * minute;
        //因为时间在4:30的时候时针应该会在4-5之间 所以我们需要计算其当时的弧度
 
        ctx.rotate(rad + mrad);
        //旋转至该弧度  加上分针中间的弧度 所以时针的弧度等于 时针的弧度加上分针的弧度
 
        ctx.lineCap = 'round';
        //绘制线条为圆头
 
        ctx.lineWidth = 5 * rem;
 
        ctx.moveTo(0, 10 * rem);
        //移动圆点 因为时针需要多点尾巴出来所以定义到10;
 
        ctx.lineTo(0, -r / 2);
        //添一个点,将其链接到这个位置
 
        ctx.stroke();
 
        ctx.restore();
 
 
    }
 
    /*************绘制分针******************/
    function drawMinute(minute) {
        //绘制分针方法与时针方法类似
 
        ctx.save();
 
        ctx.beginPath();
 
        var rad = 2 * Math.PI / 60 * minute;
 
        ctx.rotate(rad);
 
        ctx.lineWidth = 3 * rem;
 
        ctx.lineCap = 'round';
 
        ctx.moveTo(0, 10 * rem);
 
        ctx.lineTo(0, -r + 30 * rem);
 
        ctx.stroke();
 
        ctx.restore();
 
    }
 
    /*******绘制秒针****************/
    function drawSecond(second) {
 
        ctx.save();
 
        ctx.beginPath();
 
        ctx.fillStyle = '#f00';
 
        var rad = 2 * Math.PI / 60 * second;
 
        ctx.rotate(rad);
 
        ctx.moveTo(-2 * rem, 20 * rem);
        //绘制秒针的线条 一头大 一头小
        ctx.lineTo(2 * rem, 20 * rem);
 
        ctx.lineTo(1, -r + 18 * rem);
 
        ctx.lineTo(-1, -r + 18 * rem);
 
        ctx.fill();
        //绘制线条颜色
 
        ctx.restore();
    }
 
    /************绘制中心圆点*************/
    function drawDot() {
 
        ctx.beginPath();
 
        ctx.fillStyle = "#fff";
 
        ctx.arc(0, 0, 3 * rem, 0, 2 * Math.PI, false);
 
        ctx.fill();
    }
 
 
 
 
    function draw() {
 
        ctx.clearRect(0, 0, width, height);
        //设置计时器每秒调用一次 但是因为调用后 之前的还会存在所以需要每秒清除画布
 
        var now = new Date();
 
        var hour = now.getHours();
 
        var minute = now.getMinutes();
 
        var second = now.getSeconds();
 
 
        drawBackground();
        drawHour(hour, minute);
        drawMinute(minute);
        drawSecond(second);
        drawDot();
        ctx.restore();
    }
 
    setInterval(draw, 1000);
</script>
 
</body>
</html>

与御风痕博客园,程序员博客园地的首选!
御风痕博客园 » canvas绘制时钟

发表评论