zoukankan      html  css  js  c++  java
  • 利用canvas绘制绚丽的电子钟

    在慕课网上看到一位老师的电子钟,效果蛮酷,就自己模仿写了下来。这个程序有两个难点,第一是数字的坐标确定,第二个是彩色圆点的动画控制。

    总结一下思路,确定点的坐标是利用一个三维数组,根据小圆点的半径计算出来的,要想每个彩色小球有不同的速度方向和颜色,我们需要每个小球都是一个对象,为此我们写一个类来生成许多个彩色小球。在绘制蓝色字体的时候,我们判断是否需要绘制彩色小球,如果需要,则拿出相应的坐标,传给小球的类,生成对象后保存在数组里面,游戏循环的时候遍历存放小球对象的数据并且调用小球的draw()方法即可,同时注意对小球生命周器的检测,如果已经消失在视野,小球就应该结束他的生命周期了。、

    另外一个难点,看代码式子了,很好理解。

    数字绘制的数据:digit.js

    digit =
        [
            [
                [0,0,1,1,1,0,0],
                [0,1,1,0,1,1,0],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,0,1,1,0],
                [0,0,1,1,1,0,0]
            ],//0
            [
                [0,0,0,1,1,0,0],
                [0,1,1,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [1,1,1,1,1,1,1]
            ],//1
            [
                [0,1,1,1,1,1,0],
                [1,1,0,0,0,1,1],
                [0,0,0,0,0,1,1],
                [0,0,0,0,1,1,0],
                [0,0,0,1,1,0,0],
                [0,0,1,1,0,0,0],
                [0,1,1,0,0,0,0],
                [1,1,0,0,0,0,0],
                [1,1,0,0,0,1,1],
                [1,1,1,1,1,1,1]
            ],//2
            [
                [1,1,1,1,1,1,1],
                [0,0,0,0,0,1,1],
                [0,0,0,0,1,1,0],
                [0,0,0,1,1,0,0],
                [0,0,1,1,1,0,0],
                [0,0,0,0,1,1,0],
                [0,0,0,0,0,1,1],
                [0,0,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,1,1,1,0]
            ],//3
            [
                [0,0,0,0,1,1,0],
                [0,0,0,1,1,1,0],
                [0,0,1,1,1,1,0],
                [0,1,1,0,1,1,0],
                [1,1,0,0,1,1,0],
                [1,1,1,1,1,1,1],
                [0,0,0,0,1,1,0],
                [0,0,0,0,1,1,0],
                [0,0,0,0,1,1,0],
                [0,0,0,1,1,1,1]
            ],//4
            [
                [1,1,1,1,1,1,1],
                [1,1,0,0,0,0,0],
                [1,1,0,0,0,0,0],
                [1,1,1,1,1,1,0],
                [0,0,0,0,0,1,1],
                [0,0,0,0,0,1,1],
                [0,0,0,0,0,1,1],
                [0,0,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,1,1,1,0]
            ],//5
            [
                [0,0,0,0,1,1,0],
                [0,0,1,1,0,0,0],
                [0,1,1,0,0,0,0],
                [1,1,0,0,0,0,0],
                [1,1,0,1,1,1,0],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,1,1,1,0]
            ],//6
            [
                [1,1,1,1,1,1,1],
                [1,1,0,0,0,1,1],
                [0,0,0,0,1,1,0],
                [0,0,0,0,1,1,0],
                [0,0,0,1,1,0,0],
                [0,0,0,1,1,0,0],
                [0,0,1,1,0,0,0],
                [0,0,1,1,0,0,0],
                [0,0,1,1,0,0,0],
                [0,0,1,1,0,0,0]
            ],//7
            [
                [0,1,1,1,1,1,0],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,1,1,1,0],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,1,1,1,0]
            ],//8
            [
                [0,1,1,1,1,1,0],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [1,1,0,0,0,1,1],
                [0,1,1,1,0,1,1],
                [0,0,0,0,0,1,1],
                [0,0,0,0,0,1,1],
                [0,0,0,0,1,1,0],
                [0,0,0,1,1,0,0],
                [0,1,1,0,0,0,0]
            ],//9
            [
                [0,0,0,0],
                [0,0,0,0],
                [0,1,1,0],
                [0,1,1,0],
                [0,0,0,0],
                [0,0,0,0],
                [0,1,1,0],
                [0,1,1,0],
                [0,0,0,0],
                [0,0,0,0]
            ]//:
        ];

    彩色小球类:ball.js

    var ballObj = function (x,y) {
        this.x = x;
        this.y = y;
    
        this.alive = false;
    
        this.vy = 0;//y方向的速度
        this.vx = 0;//x方向的速度
        this.g = .2;//纵向加速度
        this.xg = 0;//横向加速度
    
        this.color = '';
    };
    
    ballObj.prototype.init = function () {
        var k = Math.random() < .5 ? 1 : -1;
        var R = Math.ceil(Math.random() * 255);
        var G = Math.ceil(Math.random() * 255);
        var B = Math.ceil(Math.random() * 255);
    
        this.alive = false;
        this.vy = Math.random();
        this.xg = Math.random() * 2;
        this.vx = 5 * k * this.xg;
        this.r = radius;
        this.color = R + ',' + G + ',' + B;
    };
    
    ballObj.prototype.born = function () {
        this.alive = true;
    };
    
    
    //go out canvas
    ballObj.prototype.kill = function () {
    
        if (this.x + radius < 0 || this.x - radius > canWidth) {
            this.alive = false;
        }
    
        //碰到地板反弹
        if (this.y + radius > canHeight) {
            this.y = canHeight - radius;
            this.vy = -this.vy * .6;
        }
    };
    
    ballObj.prototype.draw = function () {
        if (this.alive) {
            ctx.save();
            ctx.beginPath();
            ctx.fillStyle = 'rgb(' + this.color + ')';
            ctx.arc(this.x,this.y,this.r,0,2 * Math.PI);
            ctx.closePath();
            ctx.fill();
            ctx.restore();
            this.vy += this.g;
            this.y += this.vy;
    
            this.x += this.vx;
        }
    
        //改变速度
        this.y += this.vy;
        this.vy += this.g;
    };

    核心程序文件:main.js

    var canWidth = 1024;
    var canHeight = 768;
    var radius = 8;
    var marLeft = 30;
    var marTop = 30;
    
    var canvas;
    var ctx;
    
    var ball = [];
    var posX = [];
    
    var hour;
    var minute;
    var second;
    var oldTime = []; //old time
    
    window.onload = gameInit;
    
    function gameInit() {
        canvas = document.getElementById('canvas');
        ctx = canvas.getContext('2d');
    
        canvas.width = canWidth;
        canvas.height = canHeight;
    
        //start position
        posX = [
            marLeft,
            marLeft + 15 * (radius + 1),
            marLeft + 30 * (radius + 1),
            marLeft + 39 * (radius + 1),
            marLeft + 54 * (radius + 1),
            marLeft + 69 * (radius + 1),
            marLeft + 78 * (radius + 1),
            marLeft + 93 * (radius + 1)
        ];
    
        //time
        hour = new Date().getHours();
        minute = new Date().getMinutes();
        second = new Date().getSeconds();
    
        oldTime = [
            parseInt(hour / 10),
            hour % 10,
            10,
            parseInt(minute / 10),
            minute % 10,
            10,
            parseInt(second / 10),
            second % 10
        ];
    
    
        gameLoop();
    }
    
    function gameLoop() {
    
        //清空画布
        ctx.clearRect(0,0,canWidth,canHeight);
    
        hour = new Date().getHours();
        minute = new Date().getMinutes();
        second = new Date().getSeconds();
    
        var num = [
            parseInt(hour / 10),
            hour % 10,
            10,
            parseInt(minute / 10),
            minute % 10,
            10,
            parseInt(second / 10),
            second % 10
        ];
    
        //draw time
        for (var i = 0; i < num.length; i++) {
            renderDigit(posX[i],num[i],ctx,oldTime[i] == num[i]);
        }
    
        oldTime = num;
    
        //draw color ball
        for (var k = 0; k < ball.length; k++) {
            ball[k].kill();
            ball[k].draw();
    
            if (ball[i].alive == false) {
                ball.splice(i,1);
            }
        }
    
        requestAnimationFrame(gameLoop);
    }
    
    function renderDigit(x,num,ctx,equ) {
        ctx.fillStyle = 'rgb(0,102,153)';
    
        for (var i = 0; i < digit[num].length; i++) {
            for (var j = 0; j < digit[num][i].length; j++) {
                if (digit[num][i][j] == 1) {
                    var aX = x + j * 2 * (radius + 1) + radius + 1;
                    var aY = marTop + i * 2 * (radius + 1) + radius + 1;
    
                    ctx.beginPath();
                    ctx.arc(aX,aY,radius,0,2 * Math.PI);
                    ctx.closePath();
                    ctx.fill();
    
                    //拿到需要的彩色小球的坐标
                    if (!equ) {
                        bornBall(aX,aY);
                    }
                }
            }
        }
    }
    
    //创建小球对象并且放到数组
    function bornBall(x,y) {
        var obj = new ballObj(x,y);
        obj.init();
        obj.born();
        ball.push(obj);
    }
  • 相关阅读:
    Redis 数据结构之dict
    分布式一致性算法——paxos
    分布式事务、两阶段提交协议、三阶提交协议
    MySQL主从数据同步延时分析
    MySQL数据丢失情况分析
    INSERT ... ON DUPLICATE KEY UPDATE Syntax
    分布式系统的数据一致性
    分布式系统的BASE理论
    分布式系统的CAP理论
    性能指标体系构建
  • 原文地址:https://www.cnblogs.com/zhangbob/p/7127158.html
Copyright © 2011-2022 走看看