You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript矩阵雨效果中用charAt逐字符显示指定句子?

修改矩阵雨代码:显示指定句子而非随机字符

我朋友想要修改绿色矩阵雨代码,让它下落指定句子而不是随机字母。原代码如下:

原HTML代码

html {
    background: black;
    height: 100%;
    overflow: hidden;
}

body {
    margin: 0;
    padding: 0;
    height: 100%;
}

原JavaScript代码

const canvas = document.getElementById('Matrix');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;


const alphabet = "Where they at though?"

const fontSize = 16;
const columns = canvas.width/fontSize;

const rainDrops = [];

for( let x = 0; x < columns; x++ ) {
    rainDrops[x] = 1;
}

const draw = () => {
    context.fillStyle = 'rgba(0, 0, 0, 0.05)';
    context.fillRect(0, 0, canvas.width, canvas.height);
    
    context.fillStyle = '#0F0';
    context.font = fontSize + 'px monospace';

    for(let i = 0; i < rainDrops.length; i++)
    {
        const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length));
        context.fillText(text, i*fontSize, rainDrops[i]*fontSize);
        
        if(rainDrops[i]*fontSize > canvas.height && Math.random() > 0.975){
            rainDrops[i] = 0;
        }
        rainDrops[i]++;
    }
};

setInterval(draw, 30);

原代码逻辑是:用Canvas铺满屏幕,按字体大小划分列,rainDrops数组控制每列字符下落的垂直位置。draw函数每30ms执行一次,通过半透明黑色背景实现字符淡出效果,当前是随机从指定字符串中选取字符。

现在需要实现逐字符枚举指定句子,而非随机选字符,试过多种方法都没成功,希望能按顺序显示完整句子且不陷入循环。


修改方案

核心思路是给每一列分配句子的对应字符索引,同时控制每列的下落节奏,确保句子完整显示。具体改动如下:

修改后的JavaScript代码

const canvas = document.getElementById('Matrix');
const context = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const targetSentence = "Where they at though?";
const sentenceLength = targetSentence.length;

const fontSize = 16;
const columns = Math.floor(canvas.width / fontSize);

// 每列存储下落位置、当前字符索引、是否完成一轮句子显示
const rainDrops = [];

for (let x = 0; x < columns; x++) {
    rainDrops[x] = {
        yPos: 1,
        charIndex: x % sentenceLength,
        hasCompleted: false
    };
}

const draw = () => {
    context.fillStyle = 'rgba(0, 0, 0, 0.05)';
    context.fillRect(0, 0, canvas.width, canvas.height);
    
    context.fillStyle = '#0F0';
    context.font = `${fontSize}px monospace`;

    for (let i = 0; i < rainDrops.length; i++) {
        const drop = rainDrops[i];
        // 按索引取句子中的对应字符
        const text = targetSentence.charAt(drop.charIndex);
        context.fillText(text, i * fontSize, drop.yPos * fontSize);

        // 字符超出屏幕时,判断是否重置列
        if (drop.yPos * fontSize > canvas.height) {
            if (drop.hasCompleted || Math.random() > 0.975) {
                drop.yPos = 0;
                drop.charIndex = 0;
                drop.hasCompleted = false;
            }
        }

        drop.yPos++;
        // 推进字符索引,到达末尾标记完成状态
        if (drop.charIndex < sentenceLength - 1) {
            drop.charIndex++;
        } else {
            drop.hasCompleted = true;
        }
    }
};

setInterval(draw, 30);

关键改动说明

  • 重构rainDrops数组,给每列增加字符索引和完成状态,解决原代码仅存储位置的局限
  • 去掉随机选字符逻辑,直接按charIndex从目标句子中取对应字符
  • 控制每列的字符索引递增,到达句子末尾后标记为已完成,重置时回到句子开头,保证完整显示
  • 保留原有的随机重置概率,同时增加完成状态判断,避免句子显示中途中断

内容的提问来源于stack exchange,提问作者Jordan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:00:54