JavaScript canvas实现字符雨效果

本文实例为大家分享了JavaScript canvas实现字符雨效果的具体代码,供大家参考,具体内容如下

字符雨效果

分析如何实现

字符雨从上往下逐渐消失: 这是canvas每次画字符的时候就画一遍黑色背景,但是这个背景是有透明度的,并且这个黑色背景的透明度还比较小,只有零点零八(经过测试,0.08比较合适,也可以更改查看效果);字符是从上往下落,上面的字符先出现,下面的字符后出现,程序重复地画黑色背景,就算有透明度,叠加起来,上面的字符就会先被覆盖,下面的后出现的字符还是还比较明显,就形成了逐渐消失的效果。

只有其中一些列出现了字符: 如果不加以控制的话,那么canvas中每一列都会出现字符,不会出现参差不齐的效果。所以用一个代表出现机率的数来控制,当字符落到canvas的底部,并且拿一个随机数和出现机率进行比较,如果随机数大于其,那么这一列就可以从顶部再次出现字符,否则这一列在本次循环就不会出现字符,只有等待下次循环再次拿随机数来比较。这样就实现了有一些列出现字符,而另一些不出现字符的效果。

创建实例

let charRain = new CharRain("canvas_id");

HTML结构

<canvas id="canvas"></canvas>

CSS代码

body{       margin: 0;       padding: 0;       overflow: hidden; } #canvas{   background-color: #111; }

JS源码

;(function(win){     /**      * 创造字符雨      */     class CharRain     {       /**        * @description CharRain 类的构造函数        * @constructs        * @param {string} canvas_id - canvas 元素的 id       */       constructor(canvas_id){         this.canvas = document.getElementById(canvas_id);         this.context = this.canvas.getContext("2d");         this.bg_alpha = 0.08;    // canvas背景的透明度,也是字符消失的速度;取值范围:0 - 1         this.appearRate = 0.95;  // canvas中每一列字符下落到底部后再次出现字符的机率;取值范围:0 - 1         this.dropSpeed = 30;     // 字符下落速度         this.fontSize = 17;     // 字符大小;也确定了字符列的数目,列之间的间距         this.colunm = 0;        // 画布中的字符列的数目         this.isColorful = false; // 是否呈现彩色字符雨,默认为经典黑底绿字         this.drops = [];        // 记录每一列的字符下落的 y 值         this.timer = null;      // 定时器         this.chars = "abcdefghijklmnopqrstuvwxyz0123456789";  // 可选字符         this.init();       }       /**        * @description 初始化类        */       init(){         let _this = this;         this.setAttr();         win.addEventListener("resize", function (){ // 添加浏览器窗口变化监听,重新设置相关属性           _this.setAttr();         });         this.timer = setInterval(function (){       // 添加定时器,下落           _this.draw();         }, _this.dropSpeed);       }       /**        * @description 设置类的一些属性       */       setAttr(){         this.canvas.width = win.innerWidth;         this.canvas.height = win.innerHeight;                     // 重新设置 canvas 的宽度和高度         this.colunm = Math.ceil(win.innerWidth / this.fontSize); // 重新设置列数         for (let i=0; i<this.colunm; i++) {           if(!this.drops[i]) {                                    // 已经存在下落字符的列不用设置             this.drops[i] = win.innerHeight;                      // 字符瀑布流直接开始下落           }         }       }       /**        * @description 随机一个颜色        * @return {string} rgba 颜色值       */       randomColor(){         let r = Math.floor(Math.random()*256);         let g = Math.floor(Math.random()*256);         let b = Math.floor(Math.random()*256);         return "rgba("+r+","+g+","+b+", 1)";       }       /**        * @description 在画布上画出下落的字符       */       draw(){         this.context.fillStyle = "rgba(1,1,1," + this.bg_alpha + ")";    // 叠加画黑色背景,通过不透明度,形成字符逐渐消失的效果         this.context.fillRect(0, 0, win.innerWidth, win.innerHeight);    // 画矩形以清除之前画的字符         this.context.font = this.fontSize + "px Consolas";               // 设置字符的大小、样式         if(this.isColorful) {           this.context.fillStyle = this.randomColor();                   // 呈现彩色字符雨         } else {           this.context.fillStyle = "#00cc33";                             // 经典黑底绿字         }         for(let i=0; i<this.colunm; i++) {                               // 在每一列上画出字符           let index = Math.floor(Math.random() * this.chars.length);    // 随机一个字符           let x = i * this.fontSize;           let y = this.drops[i] * this.fontSize;                        // 字符在 y 轴方向上的距离           this.context.fillText(this.chars[index], x, y);               // 画字符           if (y>=this.canvas.height && Math.random()>this.appearRate) { // 字符落到底部 && 有再次出现的机率             this.drops[i] = 0;                                          // 0 代表每一列的字符位置回到顶部           } else {               this.drops[i]++;                                            // 字符逐渐下落,字符在 y 轴上的距离增加一           }         }        }     }     win.CharRain = CharRain;   }(window));

推荐阅读