Criando o efeito do Código-Fonte da Matrix como background do meu site com React

Escrito em 16 de setembro de 2021 - 🕒 2 min. de leitura

Para comemorar o lançamento do trailer do Matrix 4, quero adicionar um efeito do Código-Fonte da Matrix no background desse site, que já está implantado, e você pode testá-lo usando o Código Konami 👀

O efeito do Código-Fonte da Matrix

Como fazer isso com Javascript?

A melhor maneira de fazer esse tipo de efeito é usando o elemento HTML canvas. A maioria das coisas 3D ou jogos que você vê por aí usando Javascript são renderizadas no canvas.

Como tinha certeza de que alguém já tinha feito um artigo sobre como fazer isso, eu pesquisei um pouco e encontrei este artigo que mostra como fazer com vanilla Javascript, então vamos adaptar o código do Ganesh a um funcional component com React.

O código

O React é apenas um wrapper para o código original, que será configurado no hook useEffect. Também adicionei alguns estilos ao elemento canvas para fazer o efeito aparecer no background do meu blog.

import React, { useEffect, useRef } from 'react';

function MatrixBackground({ timeout }) {
    const canvas = useRef();

    useEffect(() => {
        // Ganesh's code go here
    }, [canvas, timeout]);

    return (
        <div
            style={{
                // custom styles to make it show up in the background
                background: '#000000',
                overflow: 'hidden',
                position: 'fixed',
                height: '100%',
                width: '100%',
                zIndex: -1,
                left: '0',
                top: '0',
            }}
        >
            <canvas
                ref={canvas}
            />
        </div>
    );
}

export default MatrixBackground;

Para o useEffect com o código, é simplesmente copiar e colar o original com a adição de um return para limpar o loop do setInterval.

useEffect(() => {
    const context = canvas.current.getContext('2d');

    const width = document.body.offsetWidth;
    const height = document.body.offsetHeight;
    canvas.current.width = width;
    canvas.current.height = height;

    context.fillStyle = '#000';
    context.fillRect(0, 0, width, height);

    // calculate how many 'lines' to show and animate
    const columns = Math.floor(width / 20) + 1;
    const yPositions = Array.from({ length: columns }).fill(0);

    context.fillStyle = '#000';
    context.fillRect(0, 0, width, height);

    const matrixEffect = () => {
        context.fillStyle = '#0001';
        context.fillRect(0, 0, width, height);

        context.fillStyle = '#0f0';
        context.font = '15pt monospace';

        yPositions.forEach((y, index) => {
            const text = String.fromCharCode(Math.random() * 128);
            const x = index * 20;
            context.fillText(text, x, y);

            if (y > 100 + Math.random() * 10000) {
                yPositions[index] = 0;
            } else {
                yPositions[index] = y + 20;
            }
        });
    };

    const interval = setInterval(matrixEffect, timeout);
    return () => {
        clearInterval(interval);
    };
}, [canvas, timeout]);

Você pode encontrar o código completo nesse GitHub Gist. Não se esqueça de clicar na estrela do Gist ✨ 😃

Tags:


Publicar um comentário

Comentários

Nenhum comentário.