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
{
constructor(canvas_id){
this.canvas = document.getElementById(canvas_id);
this.context = this.canvas.getContext("2d");
this.bg_alpha = 0.08;
this.appearRate = 0.95;
this.dropSpeed = 30;
this.fontSize = 17;
this.colunm = 0;
this.isColorful = false;
this.drops = [];
this.timer = null;
this.chars = "abcdefghijklmnopqrstuvwxyz0123456789";
this.init();
}
init(){
let _this = this;
this.setAttr();
win.addEventListener("resize", function (){
_this.setAttr();
});
this.timer = setInterval(function (){
_this.draw();
}, _this.dropSpeed);
}
setAttr(){
this.canvas.width = win.innerWidth;
this.canvas.height = win.innerHeight;
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;
}
}
}
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)";
}
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;
this.context.fillText(this.chars[index], x, y);
if (y>=this.canvas.height && Math.random()>this.appearRate) {
this.drops[i] = 0;
} else {
this.drops[i]++;
}
}
}
}
win.CharRain = CharRain;
}(window));