“Computadores são instrumentos, e existe uma tradição de criar instrumentos para artistas.” — Casey Reas, cocriador do Processing

Tem uma coisa que acontece quando você escreve ellipse(mouseX, mouseY, 50, 50) pela primeira vez e move o mouse pela tela. É ridiculamente simples, um círculo que segue o cursor, mas alguma coisa vira naquele momento. Você percebe que código não precisa ser só lógica de negócio, banco de dados ou API. Código pode ser sobre forma, cor, movimento e tempo. Pode ser sobre fazer algo bonito.

Essa é a promessa do p5.js, e ela é cumprida desde a primeira linha.

De onde vem tudo isso

A história começa no MIT, nos anos 1990, com um designer chamado John Maeda. Ele trabalhava com tipografia, estética e sistemas visuais, mas se frustrava com as ferramentas gráficas da época: elas permitiam operar a interface, mas não davam controle real sobre o processo. Maeda queria programar o design, não apenas clicar em botões.

Então criou o Design By Numbers (DBN), uma linguagem pensada para artistas e designers, onde o canvas era o output e a matemática era a pincelada. Foi o embrião do que viria depois.

Dois dos seus alunos, Casey Reas e Ben Fry, levaram essa ideia mais longe. Em 2001 criaram o Processing, uma linguagem baseada em Java, open source, feita para que artistas pudessem programar e programadores pudessem criar arte. O objetivo declarado era criar um software sketchbook: um lugar para experimentar, rascunhar e aprender com código visual.

O Processing virou um fenômeno. Professores de arte começaram a ensinar programação com ele. Artistas visuais passaram a usá-lo em instalações interativas. Designers exploravam sistemas generativos inteiros a partir dessa lógica.

O único problema é que o Processing rodava em Java, o que significava instalação, ambiente próprio e mais atrito para compartilhar resultados na web. Em 2013, Lauren Lee McCarthy resolveu esse problema ao criar o p5.js.

A ideia era trazer a filosofia do Processing para o navegador, em JavaScript. Sem compilação, sem fricção, sem pedir nada além de um browser. Você escreve código, abre a página, vê na hora. E pode mandar o link para qualquer pessoa.

A filosofia que torna diferente

O p5.js não é apenas uma biblioteca JavaScript para desenhar formas. Ele também carrega uma postura sobre o que programação pode ser.

A maior parte das ferramentas de criação visual separa o ato de criar do ato de programar. Você usa Photoshop, Figma ou uma interface visual qualquer, e o código fica escondido por baixo. O p5.js faz o contrário: o código é a interface. Cada linha vira uma decisão visual, uma escolha de posição, cor, ritmo ou comportamento.

Essa proximidade entre código e resultado muda a relação com a programação. Bugs podem virar distorções interessantes. Variáveis aleatórias podem virar surpresa. Um loop for pode se transformar num padrão repetitivo. A abstração deixa de ser abstrata porque você o efeito de cada instrução.

Setup e draw: o coração do p5.js

Todo sketch em p5.js tem uma estrutura básica com duas funções:

function setup() {
  // roda UMA vez, no início
  createCanvas(800, 600); // cria um canvas de 800x600px
  background(20);         // cor de fundo (0-255)
}
 
function draw() {
  // roda em LOOP, 60 vezes por segundo
  ellipse(mouseX, mouseY, 50, 50); // círculo na posição do mouse
}

setup() é onde você prepara o ambiente: tamanho do canvas, modo de cor e tudo o que só precisa acontecer uma vez. draw() é o loop principal, onde a animação vive.

Essa separação entre setup e draw é uma das decisões de design mais inteligentes da ferramenta. Ela torna óbvio o que é estático e o que é dinâmico, sem exigir que você gerencie um event loop manualmente.

As funções que você vai usar todo dia

Formas básicas

point(x, y);
line(x1, y1, x2, y2);
rect(x, y, largura, altura);
ellipse(x, y, largura, altura);
triangle(x1, y1, x2, y2, x3, y3);
arc(x, y, w, h, inicio, fim);
 
fill(r, g, b);
stroke(r, g, b);
strokeWeight(2);
noFill();
noStroke();

Cor e transparência

fill(255, 0, 0);
fill(0, 128, 255);
fill(255, 0, 0, 100);
fill('#ff5733');
 
colorMode(HSB, 360, 100, 100, 100);
fill(200, 80, 90);

HSB é especialmente poderoso em arte generativa porque você pode girar o matiz com algo como hue + frameCount e criar paletas vivas sem calcular RGB manualmente.

Tempo e animação

frameCount
frameRate()
millis()
 
let x = width / 2 + sin(frameCount * 0.05) * 200;
ellipse(x, height / 2, 40, 40);

A função sin() é uma das mais usadas no p5.js. Ela oscila entre -1 e +1 de forma suave. Multiplique por uma amplitude e some a uma posição central, e você ganha movimento orgânico com uma linha.

Aleatório vs. orgânico: random() e noise()

Essa é uma das distinções mais importantes para quem começa com p5.js.

random() — o caos puro

let x = random(0, width);
let cor = random(255);

random() gera um número diferente toda vez, sem relação com o anterior. É útil, mas tende a parecer nervoso e artificial quando usado diretamente para movimento.

noise() — o orgânico

O Perlin Noise, implementado em noise(), foi desenhado para ser suave e coeso. Valores próximos no espaço ou no tempo retornam resultados próximos. O resultado parece mais natural: nuvens, água, terreno, deriva.

let t = 0;
 
function draw() {
  let x = noise(t) * width;
  let y = noise(t + 100) * height;
 
  ellipse(x, y, 20, 20);
  t += 0.01;
}

O + 100 no segundo noise() é um truque clássico: como noise é determinístico, dois valores no mesmo ponto retornam o mesmo resultado. O offset evita que x e y repitam o mesmo padrão.

Noise também funciona em 2D e 3D:

for (let x = 0; x < width; x += 20) {
  for (let y = 0; y < height; y += 20) {
    let angulo = noise(x * 0.005, y * 0.005) * TWO_PI * 2;
    let comprimento = 15;
    line(
      x,
      y,
      x + cos(angulo) * comprimento,
      y + sin(angulo) * comprimento
    );
  }
}

Esse padrão, um flow field baseado em noise 2D, é uma das técnicas mais recorrentes da arte generativa em p5.js.

Coordenadas polares: círculos que respiram

O sistema cartesiano é o padrão, mas coordenadas polares são essenciais para formas circulares mais interessantes.

function draw() {
  background(10, 10, 10, 25);
  translate(width / 2, height / 2);
 
  beginShape();
  for (let a = 0; a < TWO_PI; a += 0.05) {
    let r = 150 + noise(cos(a) + 1, sin(a) + 1, frameCount * 0.01) * 80;
    let x = r * cos(a);
    let y = r * sin(a);
    vertex(x, y);
  }
  endShape(CLOSE);
}

Usar background() com alpha baixo cria rastro em vez de apagar tudo a cada frame, e isso já muda completamente a sensação de movimento.

Exemplo completo: sistema de partículas

Um sistema de partículas é um dos projetos clássicos de p5.js intermediário.

let particulas = [];
 
function setup() {
  createCanvas(800, 600);
  colorMode(HSB, 360, 100, 100, 100);
  background(0, 0, 10);
}
 
function draw() {
  background(0, 0, 10, 8);
 
  if (mouseIsPressed) {
    for (let i = 0; i < 3; i++) {
      particulas.push(new Particula(mouseX, mouseY));
    }
  }
 
  for (let i = particulas.length - 1; i >= 0; i--) {
    particulas[i].update();
    particulas[i].draw();
 
    if (particulas[i].morta()) {
      particulas.splice(i, 1);
    }
  }
}
 
class Particula {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = p5.Vector.random2D().mult(random(1, 4));
    this.acc = createVector(0, 0.05);
    this.vida = 255;
    this.cor = random(180, 280);
    this.tamanho = random(4, 14);
  }
 
  update() {
    this.vel.add(this.acc);
    this.pos.add(this.vel);
    this.vida -= 3;
  }
 
  draw() {
    noStroke();
    fill(this.cor, 80, 100, map(this.vida, 0, 255, 0, 80));
    ellipse(this.pos.x, this.pos.y, this.tamanho);
  }
 
  morta() {
    return this.vida <= 0;
  }
}

Repare no uso de p5.Vector, que facilita muito física básica. Com algumas linhas, você tem posição, velocidade e aceleração funcionando de forma clara.

O ecossistema de bibliotecas

Uma das forças do p5.js é sua extensibilidade.

BibliotecaO que faz
p5.soundWeb Audio API com FFT, osciladores, gravação e análise de frequência
ml5.jsMachine learning no browser: pose detection, classificação e geração
p5.collide2DDetecção de colisão entre formas
p5.guiSliders, botões e toggles para controlar parâmetros
p5.svgExportar o canvas como SVG
Toxiclibs.jsFísica, geometria computacional e cinemática
RiTa.jsTexto generativo, gramáticas e linguística computacional

A combinação p5.sound + FFT merece destaque:

let fft;
 
function setup() {
  createCanvas(800, 400);
  let mic = new p5.AudioIn();
  mic.start();
  fft = new p5.FFT();
  fft.setInput(mic);
}
 
function draw() {
  background(20);
  let espectro = fft.analyze();
 
  noStroke();
  for (let i = 0; i < espectro.length; i++) {
    let h = map(espectro[i], 0, 255, 0, height);
    fill(map(i, 0, espectro.length, 0, 360), 80, 100);
    rect(map(i, 0, espectro.length, 0, width), height - h, width / espectro.length, h);
  }
}

Com isso, já dá para criar visualizadores reativos ao som com poucas linhas.

Plataformas e comunidade

p5.js Web Editor

O editor oficial em editor.p5js.org. Roda no browser, permite salvar sketches e compartilhar links facilmente.

OpenProcessing

openprocessing.org funciona como uma grande galeria viva de sketches, referências e forks da comunidade.

fxhash

fxhash.xyz virou uma das pontes entre arte generativa, publicação e mercado. Muita coisa feita lá usa p5.js como base.

Gorilla Sun

gorillasun.de é um dos melhores lugares para leitura mais reflexiva e prática sobre arte generativa contemporânea.

As pessoas por trás

Lauren Lee McCarthy

Criadora do p5.js, artista e pesquisadora. Trouxe a filosofia do Processing para o browser e reduziu drasticamente a barreira de entrada para programação criativa.

Casey Reas e Ben Fry

Criadores do Processing, base conceitual e histórica que levou ao p5.js.

Daniel Shiffman

Professor, autor de The Nature of Code e criador do The Coding Train, provavelmente a maior porta de entrada em vídeo para esse universo.

Tim Rodenbroker

Designer e educador com foco em composição, sistemas visuais e creative coding com um pé mais forte no design.

Ferramentas offline e de desenvolvimento

Escrever no editor web é ótimo para começar, mas projetos maiores pedem um ambiente local.

VSCode + extensão p5.vscode

É a combinação mais popular para autocomplete, boilerplate e preview em browser.

Instalação local simples

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
</head>
<body>
  <script>
    function setup() {
      createCanvas(800, 600);
    }
 
    function draw() {
      background(20);
      ellipse(mouseX, mouseY, 50, 50);
    }
  </script>
</body>
</html>

Salvou, abriu no browser, já funciona.

p5.js CLI

npm install -g p5
p5 create meu-projeto
cd meu-projeto
npm start

Atom + Hydra

Para live coding e performance visual, a combinação de p5.js com Hydra ainda aparece bastante em festivais e contextos audiovisuais.

Roteiro para quem quer aprender de verdade

Ponto de partida

  1. Referência oficialp5js.org/reference
  2. The Coding Trainyoutube.com/@TheCodingTrain
  3. Gorilla Sun — Getting Started with p5.jsgorillasun.de/blog/getting-started-with-p5js

Nível intermediário

  1. Nature of Codenatureofcode.com
  2. Tim Rodenbrokertimrodenbroeker.de
  3. Estudo sério de Perlin Noise e sistemas baseados em campos

Avançado

  1. Sistemas autônomos, flocking e agentes
  2. Estudar sketches de terceiros no OpenProcessing
  3. Trabalhar com hash determinístico e publicação generativa no fxhash

Por que p5.js e não outra coisa?

Existem alternativas: Three.js para 3D, D3.js para dados, Canvas API puro para controle fino, GLSL e WebGL para GPU. Cada uma tem seu lugar.

Mas o p5.js tem uma qualidade rara: ele é feito para o processo criativo, não para o produto final. A API foi desenhada para encurtar a distância entre ideia e imagem. Você pensa em termos visuais, círculo, cor, velocidade, repetição, e o código responde nessa mesma linguagem.

É por isso que a ferramenta segue viva em ensino, prototipação e arte generativa. Ela recompensa curiosidade imediatamente.

Onde colocar no seu site

Diferente de GLSL, embutir p5.js num site é simples:

<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
 
<div id="meu-sketch"></div>
 
<script>
const sketch = (p) => {
  p.setup = () => {
    p.createCanvas(600, 400).parent('meu-sketch');
    p.background(20);
  };
 
  p.draw = () => {
    p.noStroke();
    p.fill(p.random(360), 80, 100, 30);
    p.colorMode(p.HSB);
    p.ellipse(p.mouseX, p.mouseY, 40, 40);
  };
};
 
new p5(sketch);
</script>

O modo instância encapsula tudo dentro de uma função, evitando conflitos com o restante do JavaScript da página.

Se a curiosidade aqui começar a puxar mais para gráficos em GPU e matemática visual, esta nota conversa bem com Shader Art: A Arte de Pintar com Matemática Pura. Se a intenção for pensar em publicação, estética da web pessoal e experimentação no navegador, ela também encosta naturalmente em Webmastery.

Não existe código certo ou errado em arte generativa. Existe o que te interessa explorar. A ferramenta é simples o suficiente para sair do caminho e deixar você pensar sobre forma, movimento, sistema e tempo.