web前端-Canvas时钟

作者: LiYajie | 来源:发表于2017-04-27 08:59 被阅读41次

    技术点:

    • 状态保存 context.save()
    • 状态恢复 context.restore()
    • 旋转 context.rotate(弧度)
    • 平移 context.translate(x,y) x,y 是需要移动到的目标位置坐标
    • 缩放 context.scale(1.5,1.5) 1.5,1.5 是缩放比例, 将原来的画布放大1.5倍
    • 画圆弧 context.arc(x,y,r,初始弧度, 最终弧度)
    • 清空矩形内容context.clearRect(x,y,width,height)
    • 时间(时,分,秒)的角度换算

    点击此处查看Demo

    效果图如下


    CanvasClock

    上代码

    <canvas id="clock" width="400" height="400"></canvas>
    
    canvas {
            border: 1px solid #000;
            display: block;
            margin: 100px auto;
        }
    
    function Clock(options) {
        this._init(options);
    }
    Clock.prototype = {
        constructor: Clock,
        _init: function(options) {
            options = options || {};
            this.width = options.width || 400;
            this.height = options.height || 400;
            this.r = options.r || 180;
            this.clockR = options.r - 20 || 160;
            this.ctx = options.ctx || document.getElementById('clock').getContext('2d');
        },
        // 渲染表盘
        renderClock: function() {
    
            // 保存状态
            this.ctx.save();
    
            // 绘制外面的圈
            this.ctx.arc(0, 0, this.r, 0, 2 * Math.PI);
            this.ctx.strokeStyle = '#408000';
            this.ctx.lineWidth = 10;
            this.ctx.stroke();
    
            // 恢复状态
            this.ctx.restore();
        },
        renderPoint: function() {
            this.ctx.save();
            this.ctx.beginPath();
            this.ctx.fillStyle = '#FF6666';
            this.ctx.arc(0, 0, 8, 0, 2 * Math.PI);
            this.ctx.fill();
            this.ctx.restore();
        },
        // 渲染刻度
        renderScale: function() {
            // 保存状态
            this.ctx.save();
            // 绘制刻度
            this.ctx.beginPath();
            for (var i = 0; i < 60; i++) {
                var x = Math.cos(i * 6 * Math.PI / 180) * this.clockR;
                var y = Math.sin(i * 6 * Math.PI / 180) * this.clockR;
                this.ctx.beginPath();
                var r = 3;
                var text = 1;
                if (i % 5 == 0) {
                    r = 5;
                    this.ctx.save();
                    var v = parseInt(i / 5);
                    text = v == 0 ? 12 : v;
                    this.ctx.textAlign = 'center';
                    this.ctx.textBaseline = 'middle';
                    this.ctx.font = '18px Monaco';
                    this.ctx.fillStyle = '#000';
                    var xx = Math.cos(i * 6 * Math.PI / 180) * (this.clockR + 15);
                    var yy = Math.sin(i * 6 * Math.PI / 180) * (this.clockR + 15);
                    this.ctx.translate(xx, yy);
                    this.ctx.rotate(90 * Math.PI / 180);
                    this.ctx.fillText(text, 0, 0);
                    this.ctx.restore();
                }
                this.ctx.beginPath();
                this.ctx.arc(x, y, r, 0, 2 * Math.PI);
                this.ctx.fillStyle = '#FF8000';
                this.ctx.fill();
            }
            // 恢复状态
            this.ctx.restore();
        },
        // 渲染时针
        renderHour: function(dateTime) {
            this.ctx.save();
            var hour = dateTime.getHours();
            var minute = dateTime.getMinutes();
            var second = dateTime.getSeconds();
            // 每秒6度
            var deg = ((hour % 12) * 30 * Math.PI / 180);
            
            // 计算分针和秒针旋转过的角度对应的时针旋转过的角度
            var otherDeg = ((minute * 6 + 6 / 60 * second) / 60 * 5) * Math.PI / 180;
            deg += otherDeg;
            this.ctx.rotate(deg);
            this.ctx.beginPath();
            this.ctx.moveTo(-15, 0);
            this.ctx.lineTo(90, 0);
            this.ctx.strokeStyle = '#0094ff';
            this.ctx.lineWidth = 8;
            this.ctx.stroke();
            this.ctx.restore();
        },
        // 渲染分针
        renderMiute: function(dateTime) {
            this.ctx.save();
            var minute = dateTime.getMinutes();
            var second = dateTime.getSeconds();
            // 每秒6度
            var deg = (minute * 6 * Math.PI / 180) + (6 / 60 * second * Math.PI / 180);
    
            this.ctx.rotate(deg);
            this.ctx.beginPath();
            this.ctx.moveTo(-20, 0);
            this.ctx.lineTo(120, 0);
            this.ctx.strokeStyle = '#333333';
            this.ctx.lineWidth = 5;
            this.ctx.stroke();
            this.ctx.restore();
        },
        // 渲染秒针
        renderSecond: function(dateTime) {
            this.ctx.save();
            var second = dateTime.getSeconds();
            // 每秒6度
            var deg = second * 6 * Math.PI / 180;
    
            this.ctx.rotate(deg);
            this.ctx.beginPath();
            this.ctx.moveTo(-30, 0);
            this.ctx.lineTo(150, 0);
            this.ctx.lineWidth = 2;
            this.ctx.strokeStyle = '#FF6666'
            this.ctx.stroke();
            this.ctx.restore();
        },
        render: function(dateTime) {
            this.ctx.save();
            this.ctx.lineCap = 'round';
            this.ctx.clearRect(0, 0, this.width, this.height);
            this.ctx.beginPath();
            this.ctx.translate(this.width / 2, this.width / 2);
            this.ctx.rotate(-Math.PI / 2);
            this.renderClock();
            this.renderScale();
            this.renderHour(dateTime);
            this.renderMiute(dateTime);
            this.renderSecond(dateTime);
            this.renderPoint();
            this.ctx.restore();
        }
    }
    
    var clock = new Clock();
    clock.render(new Date());
    setInterval(function() {
        clock.render(new Date());
    }, 1000)
    

    相关文章

      网友评论

        本文标题:web前端-Canvas时钟

        本文链接:https://www.haomeiwen.com/subject/owkgzttx.html