Algorithmic Art
Create original generative art with p5.js. Adapted from Anthropic's algorithmic-art skill.
Important — copyright
Never copy a specific living artist's style by name. Create original work. It's fine to use general techniques (flow fields, Voronoi, L-systems, cellular automata) but don't reproduce identifiable signature styles.
Template
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{Title}}</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js"></script>
<style>body { margin: 0; background: #111; }</style>
</head>
<body>
<script>
let seed = 42 // change to get a different piece
let particles = []
function setup() {
createCanvas(windowWidth, windowHeight)
randomSeed(seed)
noiseSeed(seed)
for (let i = 0; i < 1000; i++) {
particles.push({ x: random(width), y: random(height), age: 0 })
}
background(17)
}
function draw() {
noStroke()
for (let p of particles) {
let n = noise(p.x * 0.005, p.y * 0.005, frameCount * 0.005)
let angle = n * TWO_PI * 2
p.x += cos(angle) * 1.5
p.y += sin(angle) * 1.5
p.age++
fill(255, 200, 100, 30)
circle(p.x, p.y, 1.5)
if (p.age > 200 || p.x < 0 || p.x > width || p.y < 0 || p.y > height) {
p.x = random(width); p.y = random(height); p.age = 0
}
}
}
</script>
</body>
</html>
Write this to /tmp/art.html (substitute the user's parameters), then tell them to open /tmp/art.html.
Common techniques
Flow field (above)
Particles follow a Perlin noise vector field. Tunable: noise scale, particle count, particle alpha, max age.
Recursive subdivision
Divide a rectangle, recursively subdivide a random child. Mondrian-style outputs.
Cellular automata
2D grid, each cell updates from neighbors. Conway's Game of Life is the simplest example.
Voronoi / Delaunay
Point set + nearest-neighbor regions. Creates organic cellular patterns.
L-systems
String-rewriting grammars producing tree/plant-like structures.
Parameter exploration
Always expose 3-5 named parameters at the top of the script:
const PARAMS = {
seed: 42,
particleCount: 1000,
noiseScale: 0.005,
alpha: 30,
speed: 1.5,
}
Let the user iterate by tweaking values. Bonus: add a small dat.gui or noUiSlider panel for live tuning.
Reproducibility
Always use randomSeed() and noiseSeed() with an explicit number. This makes the same seed reproduce the same image — essential for the user to lock in a piece they like.
Output
Return the full HTML, including the seed used. Suggest 2-3 alternative seeds the user can try if they want variations.