[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