用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 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人14 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人14 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR20 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香22 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q24985969325 分钟前
前端预览word、excel、ppt
前端·word·excel
小华同学ai30 分钟前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_91539 分钟前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#