JS 粒子特效時鐘

效果:http://www.scarecrow.top/seeview?aid=90

代碼下載:

https://gitee.com/scarecrowpqs/codes/nbo51eg7msacpzvf9whxk38

其中核心部分講解:

1、Canvas單位問題:

<canvas id="ScarecrowCanvasId_246154" width="600" height="400" style="background-color: rgb(12, 55, 143);"></canvas>代表 寬600px高400px,他的默認單位是像素(px) (注意:不能用Css來改變canvas的寬高,因爲他本身的像素分佈接受CSS分配,CSS只能調整她在顯示中的像素即你看到的像素,但是這樣他就會拉伸或者壓縮原本的Canvas)

例子:<canvas id="ScarecrowCanvasId_246154" width="600" height="400" style="background-color: rgb(12, 55, 143);width:1200px;height:800px;"></canvas>則是將Canvas的像素點放大了一倍,不是代表Canvas有橫向1200個像素點,縱向800像素點。你看到的是寬1200px高800px是HTML展示的寬度,實際是寬600px高400px。

此處還有一個點注意:

你本身Canvas設計的是1000x1000但是你截圖時顯示的不是1000X1000,那麼三種原因造成的:1、你是用CSS對Canvas進行了寬高操作。2、在我的電腦顯示配置中設置了文本基於標準文字放大或縮小了一定倍數。3、瀏覽器進行了放大或縮小。自己在查看的時候要去驗證一下。

2、代碼展示


var ScarecrowGrainTime = (function(window) {
    var ScarecrowGrainTime = function(el, num=800, backgroundColor = '#0C378F',size = 15, space=1) {
        var num = num < 800 ? 800 : num;
        if (size < 1) {
            size = 1;
        }
        return new ScarecrowGrainTime.fn.init(el, num, size, backgroundColor, space);
    }

    window.requestAnimationFrame = (function () {
        return window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function (callback) {
                setTimeout(callback, 1000 / 60);
            }
    })();

    ScarecrowGrainTime.fn = ScarecrowGrainTime.prototype = {
        constructor: ScarecrowGrainTime,
        //畫布寬
        canvasWidth: 0,
        //畫布高
        canvasHeight: 0,
        //畫布背景顏色
        canvasBackgroundColor:'#0C378F',
        //附屬元素
        el:'',
        //附屬元素對象
        elId:'',
        //canvasID
        canvasId:'',
        //canvasObj
        canvasObj:'',
        //畫板對象
        canvasDrawObj:'',
        //所有粒子
        allGrainList:[],
        //所有粒子數
        grainNum:0,
        //緩存所有座標
        allZb:[],
        //數字大小
        size:15,
        //數字間間距
        space:1,
        //顯示時間起點座標
        showX:-1,
        showY:-1,
        //初始化
        init: function(el, num, size, backgroundColor, space) {
            this.el = window.document.getElementById(el);
            this.elId = el;
            this.canvasWidth = parent.parseInt(this.el.clientWidth || this.el.offsetWidth);
            this.canvasHeight = parent.parseInt(this.el.clientHeight || this.el.offsetHeight);
            this.canvasBackgroundColor = backgroundColor;
            this.canvasId = 'ScarecrowCanvasId_' + this.getRandStr();
            this.grainNum = num;
            this.size = size;
            this.space = space;
            this.size =  this.canvasWidth / (9 * 8 + 5 * this.space) / 3 * 2;
        },
        //設置所有粒子數(如果需要調用必須在run方法之前)
        setGrainNum:function(num) {
          this.grainNum = num;
        },
        //設置數字之間間距(必須爲整數且必須在run 方法之前調用)
        setSpace:function(num) {
            this.space = parent.parseInt(num);
        },
        //設置數字字體大小(必須爲整數且必須在run 方法之前調用)
        setSize:function(num) {
            this.size = parent.parseInt(num);
        },
        //設置背景顏色(必須在run 方法之前調用)
        setBackgroundColor:function (colorStr) {
            this.canvasBackgroundColor = colorStr;
        },
        //設置時間的起點座標
        setShowPoint:function(x, y) {
            if (x == undefined || y == undefined) {
                this.showX = (this.canvasWidth - (this.size * 9 * 8 + this.size * this.space * 5)) / 2;
                this.showY = (this.canvasHeight - this.size * 12) / 2;
            } else {
                this.showX = x > this.canvasWidth || x < 0 ? 0 : x;
                this.showY = y > this.canvasHeight || x < 0 ? 0 : y;
            }
        },
        //開始運行
        run:function() {
            if (this.showX == -1) {
                this.setShowPoint();
            }
            this.createCanvas();
            this.createAllGrain(this.grainNum);
            var tileList = this.getNowTimeList();
            this.setTime(this.showX, this.showY, tileList[0],tileList[1],tileList[2],tileList[3],tileList[4],tileList[5], ':', this.space);
            this.showDongHua();
        },
        //創建畫板
        createCanvas:function () {
            var canvasObj = document.createElement('canvas');
            canvasObj.id = this.canvasId;
            canvasObj.width = this.canvasWidth;
            canvasObj.height = this.canvasHeight;
            canvasObj.style.backgroundColor = this.canvasBackgroundColor;
            this.canvasObj = canvasObj;
            this.canvasDrawObj = canvasObj.getContext('2d');
            this.el.appendChild(canvasObj);
        },
        //獲取隨機數
        getRandomNum:function(x=0, y=100000) {
            return parent.parseInt(Math.random() * (y - x)) + x;
        },
        //獲取隨機字符串
        getRandStr:function(len = 6) {
            var tempStr = "123456789abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            var relStr = "";
            for(var i = 0 ; i < len; i++) {
                relStr = relStr + tempStr[this.getRandomNum(0, 6)];
            }
            return relStr;
        },
        //獲取隨機顏色
        getRandomColor:function() {
            return "rgb(" + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + ")";
        },
        //繪製一個粒子
        createGrain:function (x = 400, y = 400, radius = 100, color='') {
            this.canvasDrawObj.strokeStyle = 'rgba(0,0,0,0)';
            this.canvasDrawObj.beginPath();
            this.canvasDrawObj.arc(x, y, radius,0,360*Math.PI/180);
            this.canvasDrawObj.stroke();
            var grd=this.canvasDrawObj.createRadialGradient(x,y,radius * 0.6, x,y,radius);
            grd.addColorStop(0,color == '' ? this.getRandomColor() : color);
            grd.addColorStop(1,'rgba(0,0,0,0)');
            this.canvasDrawObj.fillStyle=grd
            this.canvasDrawObj.fill();
        },
        //創建所有粒子座標信息
        createAllGrain:function (num) {
            var radiusStart = (this.size / 2) - 4 < 1 ? 1 : (this.size / 2) - 4;
            var startEnd = this.size / 2 < 1 ? 1 : this.size / 2;
            for (var i = 0; i<num; i++) {
                var obj = {
                    x:this.getRandomNum(0, this.canvasWidth),
                    y:this.getRandomNum(0, this.canvasHeight),
                    radius:this.getRandomNum(radiusStart , startEnd),
                    speed:this.getRandomNum(3, 10),
                    toX:0,
                    toY:0,
                    color:this.getRandomColor()
                };
                this.allGrainList.push(obj);
            }
        },
        //繪製所有粒子
        drawAllGrain:function(){
            var j = 0;
            for (var i in this.allGrainList) {
                if (this.allGrainList[i].x != this.allGrainList[i].toX) {
                    var times = Math.abs(this.allGrainList[i].toX - this.allGrainList[i].x) / this.allGrainList[i].speed;
                    var toY = Math.abs(this.allGrainList[i].toY - this.allGrainList[i].y) / times;
                    this.allGrainList[i].x = this.allGrainList[i].toX > this.allGrainList[i].x ? this.allGrainList[i].x + this.allGrainList[i].speed : this.allGrainList[i].x - this.allGrainList[i].speed;
                    this.allGrainList[i].y = this.allGrainList[i].toY > this.allGrainList[i].y ? this.allGrainList[i].y + toY : this.allGrainList[i].y - toY;
                    if (Math.abs(this.allGrainList[i].toX-this.allGrainList[i].x) < this.allGrainList[i].speed) {
                        this.allGrainList[i].x =  this.allGrainList[i].toX;
                        this.allGrainList[i].y =  this.allGrainList[i].toY;
                        j = j + 1;
                    }
                } else {
                    this.allGrainList[i].x =  this.allGrainList[i].toX;
                    this.allGrainList[i].y =  this.allGrainList[i].toY;
                    j = j + 1;
                }
                this.createGrain(this.allGrainList[i].x, this.allGrainList[i].y, this.allGrainList[i].radius, this.allGrainList[i].color)
            }
            return j == this.grainNum ? 1 : 0;
        },
        //清空畫板
        clearDeraw:function () {
            this.canvasObj.width = this.canvasWidth;
            this.canvasObj.height = this.canvasHeight;
        },
        //開始動畫
        showDongHua:function () {
            this.clearDeraw();
            if(this.drawAllGrain() == 1) {
                var tileList = this.getNowTimeList();
                this.setTime(this.showX, this.showY, tileList[0],tileList[1],tileList[2],tileList[3],tileList[4],tileList[5], ':', this.space);
                this.clearDeraw();
            }
            window.requestAnimationFrame(this.showDongHua.bind(this));
        },
        //獲取數字模板
        getShowNumList:function (num) {
            switch (num) {
                case 0:
                    return [
                        [0,0,1,1,1,1,1,0,0],
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [0,1,1,1,1,1,1,1,0],
                        [0,0,1,1,1,1,1,0,0],
                    ];
                case 1:
                    return [
                        [0,0,1,1,1,1,0,0,0],
                        [0,1,1,1,1,1,0,0,0],
                        [1,1,1,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,0,0,1,1,1,0,0,0],
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                    ];
                case 2:
                    return [
                        [0,0,1,1,1,1,1,0,0],
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [0,0,0,0,0,0,1,1,1],
                        [0,0,0,0,0,1,1,0,0],
                        [0,0,0,0,1,1,0,0,0],
                        [0,0,0,1,1,0,0,0,0],
                        [0,0,1,1,0,0,0,0,0],
                        [0,1,1,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,1,1,1,1,1,1,1],
                    ];
                case 3:
                    return [
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [0,0,0,0,0,0,1,1,0],
                        [0,0,0,0,0,1,1,0,0],
                        [0,0,0,0,1,1,1,0,0],
                        [0,0,0,0,0,1,1,0,0],
                        [1,1,0,0,0,0,1,1,0],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,1,1,1,1,1,1,1,0],
                    ];
                case 4:
                    return [
                        [0,0,0,0,0,0,1,1,0],
                        [0,0,0,0,0,1,1,1,0],
                        [0,0,0,0,1,1,1,1,0],
                        [0,0,0,1,1,0,1,1,0],
                        [0,0,1,1,0,0,1,1,0],
                        [0,1,1,0,0,0,1,1,0],
                        [1,1,0,0,0,0,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,0,0,0,0,0,1,1,0],
                        [0,0,0,0,0,0,1,1,0],
                        [0,0,0,0,0,0,1,1,0],
                    ];
                case 5:
                    return [
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,0],
                        [1,1,0,0,0,0,0,0,0],
                        [1,1,0,0,0,0,0,0,0],
                        [1,1,1,1,1,1,1,1,0],
                        [0,1,1,1,1,1,1,1,1],
                        [0,0,0,0,0,0,0,1,1],
                        [0,0,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,1,1,1,1,1,1,1,0],
                    ];
                case 6:
                    return [
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,0,0],
                        [1,1,0,0,0,0,0,0,0],
                        [1,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,1,1,1,1,1,1,1,0],
                    ];
                case 7:
                    return [
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [0,0,0,0,0,0,0,1,1],
                        [0,0,0,0,0,0,1,1,0],
                        [0,0,0,0,0,1,1,0,0],
                        [0,0,0,0,1,1,0,0,0],
                        [0,0,0,0,1,1,0,0,0],
                        [0,0,0,0,1,1,0,0,0],
                        [0,0,0,0,1,1,0,0,0],
                        [0,0,0,0,1,1,0,0,0],
                        [0,0,0,0,1,1,0,0,0],
                    ];
                case 8:
                    return [
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [0,1,1,1,1,1,1,1,0],
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,1,1,1,1,1,1,1,0],
                    ];
                case 9:
                    return [
                        [0,1,1,1,1,1,1,1,0],
                        [1,1,1,1,1,1,1,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,1,1,1,1,1,1,1,1],
                        [0,0,0,0,0,0,0,1,1],
                        [0,0,0,0,0,0,0,1,1],
                        [1,1,0,0,0,0,0,1,1],
                        [1,1,1,1,1,1,1,1,1],
                        [0,1,1,1,1,1,1,1,0],
                    ];
                case ':':
                        return [
                            [0,0,0,0,0,0,0,0,0],
                            [0,0,1,1,1,1,1,0,0],
                            [0,0,1,1,1,1,1,0,0],
                            [0,0,1,1,1,1,1,0,0],
                            [0,0,0,0,0,0,0,0,0],
                            [0,0,0,0,0,0,0,0,0],
                            [0,0,0,0,0,0,0,0,0],
                            [0,0,0,0,0,0,0,0,0],
                            [0,0,1,1,1,1,1,0,0],
                            [0,0,1,1,1,1,1,0,0],
                            [0,0,1,1,1,1,1,0,0],
                            [0,0,0,0,0,0,0,0,0],
                        ];
            }
        },
        //設置時間
        setTime:function (x=0, y=0, H1 = 0,H2 = 1,I1 = 0,I2 = 1,S1 = 0,S2 = 1,eox=':',space=5) {
            var w = this.size * (9+space);
            this.allZb = [];
            this.setNum(H1, x + (0 * w),y);
            this.setNum(H2, x + (1 * w),y);
            this.setNum(eox, x + (2 * w),y);
            this.setNum(I1, x + (3 * w),y);
            this.setNum(I2, x + (4 * w),y);
            this.setNum(eox, x + (5 * w),y);
            this.setNum(S1, x + (6 * w),y);
            this.setNum(S2, x + (7 * w),y);

            var m = 0;
            var zbNum = this.allZb.length;
            for(var i in this.allGrainList) {
                m = m % zbNum;
                this.allGrainList[i].toX = this.allZb[m].x;
                this.allGrainList[i].toY = this.allZb[m].y;
                m = m + 1;
            }
        },
        //設置一個數字
        setNum:function (num, x, y) {
            if (num < 0 || num > 9) {
                num = 0;
            }
            var numList = this.getShowNumList(num);
            for (var i in numList) {
                for (var j in numList[i]) {
                    if (numList[i][j] == 1) {
                        this.allZb.push({
                            x: x + this.size * j,
                            y: y + this.size * i
                        });
                    }
                }
            }
        },
        //獲取當前時間數組
        getNowTimeList:function () {
            var myDate = new Date();
            var myHours = myDate.getHours();
            var myMinu = myDate.getMinutes();
            var mySec = myDate.getSeconds();
            var relData = [parent.parseInt(myHours / 10),parent.parseInt(myHours % 10),parent.parseInt(myMinu / 10),parent.parseInt(myMinu % 10),parent.parseInt(mySec / 10),parent.parseInt(mySec % 10)];
            return relData;
        }
    }

    ScarecrowGrainTime.fn.init.prototype = ScarecrowGrainTime.fn;
    return ScarecrowGrainTime;
})(window);
//掛在全局
window.$=window.ScarecrowGrainTime=ScarecrowGrainTime;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body{
            width: 100%;
            height: 100%;
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body id="bodys">
<div style="width: 600px;height: 400px; background-color:red;display: block;margin: auto;" id="showCanvas"></div>
<script src="ScarecrowGrainTime.js"></script>
<script>
    //創建對象
    var obj = ScarecrowGrainTime('showCanvas');
    // //設置字體大小
    // obj.setSize(10);
    // //設置背景顏色
    // obj.setBackgroundColor('green');
    // //設置字體間間距
    obj.setSpace(2);
    // //設置時間顯示的起點座標
    // obj.setShowPoint(50,300);
    // //設置粒子數
    obj.setGrainNum(1500);
    //開始執行
    obj.run();
</script>
</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章