用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>
相关推荐
Boilermaker199219 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子30 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y1 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构