Arte generativa em JavaScript para as laterais do site

Após bastante tempo, finalmente inclui um JavaScript neste site.

Eu tenho um bloqueio enorme com relação ao uso de tecnologias para web, JavaScript, CSS e o próprio HTML parecem muito improvisadas para mim, principalmente a ideia de “single page application”.

Essa é uma limitação que eu tenho que superar. Mesmo porque, hoje em dia, a web é de fato a melhor e mais portável interface para a maioria dos programas. Apesar de ir contra muita coisa que acredito sobre minimalismo e economia de recursos.

Por enquanto o JavaScript que incluí não interfere muito com a página, o que ele faz é que quando a tela é grande demais para o conteúdo da página as duas faixas laterais que não eram utilizadas agora exibem arte digital gerada aleatoriamente.

O código é escrito de maneira que se não houver barras laterais, ou seja, não há espaço para desenhar, o script simplesmente termina e não fica ocupando recursos sem necessidade. Assim, quem estiver lendo a página em um tablet ou celular não vai sentir diferença alguma.

O código em si é bem simples, algumas funções de suporte e uma função de desenho chamada recursivamente usando requestAnimationFrame(update); essa função tenta rodar a aproximadamente 60 FPS, mas a maioria dos navegadores pausa o update se a página não estiver visível, assim não gastamos recursos se o usuário for para outra aba ou minimizar o navegador.

A função de desenho em si é bem pequena e hoje só tenho um efeito que é um quadriculado parecido com o mapa de calor do GitHub. A ideia é aos poucos adicionar outras funções que criem arte generativa nos mais diversos temas, fractais, labirintos, efeitos, etc. e então escolher um dos efeitos aleatoriamente na carga da página. 

O código-fonte está em https://crg.eti.br/digitalart.js.

Explicando o código

A função createCanvas é uma função auxiliar que chamo se for necessário criar as duas canvas nas laterais, e ela retorna o contexto que vou usar para desenhar.

function createCanvas(width, height, left) {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    canvas.style.position = 'fixed';
    canvas.style.top = '0';
    canvas.style[left ? 'left' : 'right'] = '0';
    canvas.style.zIndex = '-1';
    document.body.appendChild(canvas);
    return canvas.getContext('2d');
}

A função adjustCanvas verifica se tem algum espaço para criar as canvas e se houver cria as duas canvas e passa o contexto para a função de desenho, hoje só existe uma função de desenho, mas eventualmente haverá várias e daí essa função vai aleatoriamente sortear qual usar.

function adjustCanvas() {
    const screenWidth = window.innerWidth;
    const screenHeight = window.innerHeight;
    const contentWidth = 1024;
    const sideWidth = (screenWidth - contentWidth) / 2;

    if (sideWidth > 0) {
        const leftCtx = createCanvas(sideWidth, screenHeight, true);
        const rightCtx = createCanvas(sideWidth, screenHeight, false);

        githubHeatMap(leftCtx, sideWidth, screenHeight);
        githubHeatMap(rightCtx, sideWidth, screenHeight);
    }
}

Então a função githubHeatMap desenha um quadriculado verde como o mapa de calor do GitHub.

function githubHeatMap(ctx, width, height) {
    const cellWidth = 20;
    const cellHeight = 20;
    const cols = window.innerWidth / cellWidth;
    const rows = window.innerHeight / cellHeight;
    
    function update() {
        const col = Math.floor(Math.random() * cols);
        const row = Math.floor(Math.random() * rows);
        
        const x = col * cellWidth;
        const y = row * cellHeight;

        ctx.beginPath();
        ctx.roundRect(x, y, cellWidth - 2, cellHeight - 2, 3);
        ctx.fillStyle = `rgb(0, ${Math.random() * 255}, 0)`;
        ctx.fill();
        ctx.closePath();

        requestAnimationFrame(update);
    }
    update();
}

Por fim, no final do JavaScript temos as linhas para carregar o programa, e reagir caso o tamanho da tela mude.

document.addEventListener("DOMContentLoaded", adjustCanvas);
window.addEventListener('resize', function() {
    // Remove canvases antigos antes de adicionar novos
    document.querySelectorAll('canvas').forEach(canvas => canvas.remove());
    adjustCanvas();
});

E é isso, um pequeno código para adicionar arte generativa ao site e tornar a experiência um pouco menos árida.

Eu ainda tenho um longo caminho a percorrer para me sentir confortável com o desenvolvimento web, e não tenho pressa alguma para isso, mas sem dúvida não tem como escapar de JavaScript, CSS e HTML e criar uma base de conhecimento, saber as dores da tecnologia e como contorná-las é importante para qualquer desenvolvedor.


Cesar Gimenes

Última modificação