用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>
相关推荐
艾克马斯奎普特1 分钟前
Vue.js 3 渐进式实现之响应式系统——第八节:调度执行
前端·vue.js
小old弟1 分钟前
🤔不会搭建技术博客,Trae+vitepress,😎3s搞定
前端·trae
陈奕迅本讯2 分钟前
前端-Vue2组件化编程
前端·javascript·vue.js
十五_在努力4 分钟前
参透 JavaScript —— 异步编程与Promise
前端·javascript·promise
顾林海6 分钟前
Flutter 图片组件全面解析:从基础加载到高级应用
android·前端·flutter
背书包的甜瓜8 分钟前
使用sass 实现px转vh或vw,适配适老化时,在设计图字体大小的基础上,增加3px(可配置),
前端·css·sass
十五_在努力8 分钟前
参透 JavaScript —— 图解 Event Loop 事件循环
前端·javascript
十五_在努力15 分钟前
参透JavaScript —— 判断数据类型的四种方式
前端·javascript
依辰22 分钟前
小程序自动化构建与版本管理方案优化
前端·javascript·微信小程序
Geoffwo22 分钟前
取消echarts地图悬浮时默认黄色高亮
前端·javascript·echarts