用canvas画个代码雨玩玩

最终效果

实现原理

根据屏幕的宽度跟每一列的宽度,生成 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>
相关推荐
咖啡の猫2 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲4 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5815 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路5 小时前
GeoTools 读取影像元数据
前端
ssshooter5 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry6 小时前
Jetpack Compose 中的状态
前端
dae bal7 小时前
关于RSA和AES加密
前端·vue.js
柳杉7 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog7 小时前
低端设备加载webp ANR
前端·算法
LKAI.8 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi