html:
<body>
<canvas id="c"></canvas>
</body>
css:
body {
background-color: black;
}
#c {
opacity: 0.8;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
js:
// 初始化
let c = document.getElementById('c');
let bg = document.getElementById('bg');
const w = (c.width = window.innerWidth);
const h = (c.height = window.innerHeight);
const ctx = c.getContext('2d');
const accelleration = 0.02; // 控制雨点下落的速度
const total = w;
const size = w / total;
const occupation = w / total;
const repaintColor = 'rgba(0, 0, 0, .1)';
const colors = [];
const dots = [];
const dotsVel = [];
/* 360/total 表示颜色范围,这里用色相表示,所有颜色都在一个色相环里 */
var portion = 360 / total;
for (var i = 0; i < total; ++i) {
colors[i] = portion * i;
dots[i] = h; // 屏幕高度
dotsVel[i] = 10; // 10?
}
function draw() {
window.requestAnimationFrame(draw);
/* 相当于给整个屏幕重新刷漆。repaintColor(透明度) 值越大,雨点的拖尾效果越小 */
ctx.fillStyle = repaintColor;
ctx.fillRect(0, 0, w, h);
for (var i = 0; i < total; ++i) {
var currentY = dots[i] - 1;
dots[i] += dotsVel[i] += accelleration;
ctx.fillStyle = 'hsl(' + colors[i] + ', 80%, 50%)';
/* *绘制* */
/* (x = 当前列; y; 宽度为1; 高度为 ) */
ctx.fillRect(occupation * i, currentY, 2, dotsVel[i] + 1);
if (dots[i] > h && Math.random() < 0.001) {
dots[i] = dotsVel[i] = 0;
}
}
}
draw();
/**
* 问题:这个anim()方法中在一个requestAnimationFrame周期中一共绘制了多少次:
* 1 - 单次绘制:重新给页面画上黑色的背景
* 2 - for{}循环:循环了屏幕宽度那么多次,每次循环绘制一个雨点
*
* 如果当前列的雨点超出了屏幕的高度,且加一个随机数,重置当前雨点到原点
*/
成品: