Algorithmic design
Writing your own scripts
A script is plain JavaScript that runs from top to bottom, once per run. It draws shapes onto
the artboard and can change the objects that are selected. There is no setup() or draw(),
no animation, and nothing to import: every function below is simply there.
Open Menu ▸ Algorithmic design ▸ New script… to start from empty code, or open an example and change it. The Code tab has a Reference button that lists every function, with a filter. Press Run, or ⌘Enter (Ctrl+Enter on Windows), to see the result.
A first script
// Rings that get thinner towards the edge.
const rings = param('rings', 24, { min: 3, max: 80, step: 1 });
const weight = param('weight', 2, { min: 0.25, max: 6, step: 0.25, unit: 'pt' });
const ink = param('ink', '#111111');
const R = Math.min(artboard.width, artboard.height) * 0.45;
for (const i of range(1, rings + 1)) {
const t = i / rings; // near 0 in the middle, 1 at the edge
circle(artboard.center, R * t, { stroke: ink, strokeWidth: pt(weight * (1 - t) + 0.25) });
}
The three param() lines become two sliders and a color picker under Controls. Moving
one runs the script again with the new value.
Coordinates and units
- Coordinates are artboard pixels, from the top-left corner, with y going down.
artboard.width,artboard.heightandartboard.centergive the size of the artboard the result lands on. Build from them and the design fits a business card and a poster alike.mm(),cm(),pt()andinch()turn real units into artboard pixels. Stroke widths read best in points:strokeWidth: pt(0.5).
Sliders and inputs
param(key, default, options) declares a control and returns its current value:
| Default | Becomes |
|---|---|
A number with min and max |
A slider (add step, unit and label as you like) |
true or false |
A switch |
Text with choices |
Buttons, or a menu for longer lists |
A color such as '#e4572e' |
A color picker |
vec(x, y) |
A point with x and y fields |
Drawing
Every drawing function takes a style as its last argument:
{ fill, stroke, strokeWidth, opacity, rotation, cornerRadius, name, cap, join }. With no fill
and no stroke, closed shapes are filled black and open lines are stroked black.
| Function | Draws |
|---|---|
rect(x, y, width, height) |
A rectangle from its top-left corner |
circle(x, y, radius), ellipse(x, y, rx, ry) |
Around a center |
line(x1, y1, x2, y2), polyline(points), polygon(points) |
Straight lines through points |
star(x, y, outer, inner, points), regular(x, y, radius, sides) |
Stars and regular polygons |
path(p => p.moveTo(…).lineTo(…).cubicTo(…).arc(…).close()) |
Any shape, or SVG path data |
group(() => { … }, { x, y, rotation, scale }) |
Draws inside a group that moves, turns or scales everything in it |
Shapes stack in the order they are drawn: a later shape covers an earlier one.
Randomness that repeats
random(), randomInt(), gaussian(), pick() and shuffle() give the same results every
time the script runs with the same settings, and so does Math.random(). New variation
changes the seed, and with it every random choice. noise(x, y) gives smooth values between
0 and 1 that change gradually from place to place, the basis of flow fields and landscapes.
Point sets and contour lines
| Function | Gives |
|---|---|
poissonDisk(distance) |
Points spread evenly at random, never closer than distance |
delaunay(points) |
The triangles between points |
voronoi(points) |
The cell around each point, clipped to the artboard |
contours((x, y) => value, levels) |
Contour lines of any function, like a hiking map: each line has points, level and closed |
Changing the selection
selection holds the objects that were selected when the script ran, in the order they were
selected. Each item tells you its kind, position, size, colors and outline, and has methods
to change it: move, moveTo, rotate, scale, set, clone and remove.
for (const [i, item] of selection.entries()) {
item.rotate(i * 15).set({ opacity: 1 - i * 0.1 });
}
When a script reads the selection, it runs again whenever the selection changes while the window is open.
Colors
color(), rgb(), hsl() and oklch() make colors; cmyk(c, m, y, k) makes a print color
that keeps its ink values; mix(), lighten() and darken() change them. palette holds the
document's swatches.
When something goes wrong
If a script stops, the Code tab marks the line and explains what went wrong, often with a
hint. log() writes values to the Log under the code. A run must finish within five
seconds, and can draw up to 20,000 shapes; see
Privacy, safety and limits.