Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Shapes — the cast

Everything on screen is an entity with a name (its first argument). You declare shapes once; the name is how you address them later in the script.

The six primitives

Each line below is the whole call — copy it and tweak the numbers.

shapewritedraws
circlecircle(sun, (cx, cy), 90);a circle, radius 90, at the centre
rectrect(box, (cx, cy), 200, 120);a rectangle 200 wide, 120 tall
lineline(edge, (100, 100), (400, 300));a line from point to point
arrowarrow(v, (100, 400), (400, 400));a line with an arrowhead at the end
dotdot(p, (cx, cy), 8);a small filled dot, radius 8
texttext(cap, (cx, 640), "hello");a text label anchored at a point

Points are (x, y) in pixels, origin top-left, y increasing downward. Use cx, cy, w, h to stay canvas-independent.

// the six primitive shapes, drawn on together.
title("Shapes");
canvas("16:9");

text(t, (cx, 90), "six primitives");  color(t, cyan);  size(t, 32);  hidden(t);

circle(c, (240, 380), 80);            color(c, cyan);     stroke(c, 4);  untraced(c);
rect(r,   (470, 380), 150, 150);      color(r, magenta);  stroke(r, 4);  untraced(r);
line(l,   (640, 300), (820, 460));    color(l, lime);     stroke(l, 4);  untraced(l);
arrow(a,  (900, 460), (1040, 300));   color(a, cyan);     stroke(a, 4);  untraced(a);
dot(d,    (1110, 380), 12);           color(d, magenta);  hidden(d);
text(lbl, (640, 620), "circle · rect · line · arrow · dot · text");
color(lbl, dim);  size(lbl, 24);  hidden(lbl);

show(t, 0.5);
par { draw(c);  draw(r);  draw(l);  draw(a);  show(d); }
show(lbl, 0.5);
wait(1.2);

▶ See it play:

Modifiers — style a shape at t = 0

A shape starts plain. Modifiers change how it looks before the animation begins. They take the entity name first, then a value:

modifiereffectexample
color(id, c)fill / stroke colourcolor(sun, cyan);
stroke(id, w)line thicknessstroke(sun, 4);
size(id, n)text sizesize(cap, 30);
glow(id, n)neon halo strengthglow(sun, 8);
opacity(id, 0..1)transparencyopacity(sun, 0.5);
filled(id) / outlined(id)turn fill / outline onfilled(box);
hue(id, deg)colour by an angle (0–360) — for gradients & loopshue(seg, 200);
z(id, n)draw order (higher = on top)z(box, 5);

And two that decide how a shape first appears:

modifierpairs withgives
hidden(id)show(id)a fade-in
untraced(id)draw(id)a draw-on (pen tracing the outline)

Colours are a fixed palette: fg, void, cyan, magenta, lime, dim, panel. For a computed colour (say, one per item in a loop) use hue(id, degrees). More in Colour & style.

Naming things in a loop

When you make many shapes with a for loop, give each a unique name with interpolation{expr} glued to the name:

for i in 0..5 {
  dot(p{i}, (200 + i*180, cy), 8);   // p0, p1, p2, p3, p4
}

That’s your cast. Now let’s make it move → Verbs.