最终效果
实现原理
先根据屏幕的宽度跟每一列的宽度,生成 x 列
,然后添加到一个数组之中,由这个数组来控制每一列中每一行的的位置,再画完一行之后,使用canvas的api来擦除上一次渲染的行,这样就可以做到渐变下落的效果。然后再添加一点随机的逻辑,达到下落时机不同的效果。
实现过程
设置canvas,获取列数
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>代码雨</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
</style>
<body>
<canvas id="canvas-container"></canvas>
</body>
<script type="text/javascript">
const window_width = window.innerWidth
const window_height = window.innerHeight
const _canvas = document.getElementById('canvas-container')
const _canvas_content = _canvas.getContext('2d')
_canvas.width = window_width
_canvas.height = window_height
// 设置列宽 行高
const column_w = 20
const row_h = 20
// 总列数
const columns = Math.floor(window_width/column_w)
</script>
</html>
从动图可以看见下落的东西其实是一些文本跟随机的颜色
html
<script type="text/javascript">
...
const text = 'hello-word'
const random = (max,min) => Math.floor(Math.random() * (max - min + 1))
const randomText = () => text[random(text.length - 1,0)] // 获取随机文本
const randomColor = () => ['#eaac00','#0088F7','#FE7D0D','#4DCBA7'][random(3,0)] // 设置随机的颜色
</script>
最后完善一些渲染的逻辑
html
<script type="text/javascript">
...
// 由这个数组来控制每一列的渲染位置
const nextChar = new Array(columns).fill(0)
// 渲染函数
const draw = () => {
// 擦一下画布
_canvas_content.fillStyle = 'rgba(240,240,240,0.1)'
_canvas_content.fillRect(0,0,window_width,window_height)
// 循环渲染出画布的位置
for (let i = 0; i < columns; i++) {
// 颜色 位置
_canvas_content.fillStyle = randomColor()
const char = randomText()
const x = column_w * i
const y = (nextChar[i] + 1) * row_h
if (y > window_height && Math.random() > 0.9){
nextChar[i] = 0
}else{
nextChar[i]++;
}
_canvas_content.fillText(char,x,y)
}
}
</script>
以上代码,在if中添加了Math.random() > 0.9
就是为了达到让代码下落的时候出现偏差,从而达到错落有致的效果。 这个时候调用一下draw()
,如下图:
调用多几次的效果
最后再加个轮询,让他不停的调用draw函数就可以了
html
<script type="text/javascript">
...
setInterval(() => {
draw()
},50)
</script>
到此,大功告成。以下是完整代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>代码雨</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
</style>
<body>
<canvas id="canvas-container"></canvas>
</body>
<script type="text/javascript">
const window_width = window.innerWidth
const window_height = window.innerHeight
const _canvas = document.getElementById('canvas-container')
const _canvas_content = _canvas.getContext('2d')
_canvas.width = window_width
_canvas.height = window_height
const column_w = 20
const row_h = 20
const columns = Math.floor(window_width / column_w)
const text = 'hello-word!'
const random = (max,min) => {
return Math.floor(Math.random() * (max - min + 1))
}
const randomText = () => {
return text[random(text.length - 1,0)]
}
const randomColor = () => {
return ['#eaac00','#0088F7','#FE7D0D','#4DCBA7'][random(3,0)]
}
const nextChar = new Array(columns).fill(0)
console.log(nextChar,'nextChar')
function draw() {
_canvas_content.fillStyle = 'rgba(240,240,240,0.1)'
_canvas_content.fillRect(0,0,window_width,window_height)
for (let i = 0; i < columns; i++) {
// 颜色 位置
_canvas_content.fillStyle = randomColor()
const char = randomText()
const x = column_w * i
const y = (nextChar[i] + 1) * row_h
if (y > window_height && Math.random() > 0.9){
nextChar[i] = 0
}else{
nextChar[i]++;
}
_canvas_content.fillText(char,x,y)
}
}
setInterval(() => {
draw()
},50)
</script>
</html>