Shapes
Shapes are the building blocks of a scene. Every shape returns a ShapeBuilder that can be styled and animated by chaining modifiers.
How Shapes Render
- Shapes are centered on the canvas by default. Use
at({ x, y })ormove({ x, y })to position them. - All sizes are in pixels. Angles are in radians.
- Paths are drawn around the origin, then transformed by scale/rotate/move.
Primitive Shapes
Circle
Circle(radius)
Circle(60).fill('#0ea5e9').stroke({ color: '#0f172a', width: 4 })
Rect
Rect(width = 80, height = 80)
Rect(180, 100).fill('#111827').stroke({ color: '#f8fafc', width: 3 })
RoundedRect
RoundedRect(width = 120, height = 80, radius = 16)
radius can be a number or { tl, tr, br, bl } for per-corner radii.
RoundedRect(200, 110, { tl: 18, tr: 30, br: 12, bl: 24 }).fill('#22c55e')
Capsule
Capsule(width = 160, height = 60)
Uses the smallest dimension as the corner radius.
Capsule(220, 80).fill('#f97316')
Ellipse
Ellipse(width = 120, height = 80)
Ellipse(200, 110).fill('#0f172a').stroke({ color: '#38bdf8', width: 4 })
Line
Line(from, to)
Creates an open path with two points.
Line({ x: -120, y: 0 }, { x: 120, y: 0 })
.fill('rgba(0,0,0,0)')
.stroke({ color: '#22d3ee', width: 6 })
Path
Path(points, closed = true)
Path([
{ x: -120, y: 40 },
{ x: -40, y: -60 },
{ x: 60, y: 20 },
{ x: 120, y: -40 },
], false)
.fill('rgba(0,0,0,0)')
.stroke({ color: '#0ea5e9', width: 4 })
Polyline
Polyline(points)
A convenience for an open Path.
Polygon
Polygon(points, closed = true)
Identical to Path, but signals intent.
RegularPolygon
RegularPolygon(sides = 6, radius = 60, options?)
Options:
rotation(radians)
RegularPolygon(6, 70, { rotation: Math.PI / 6 }).fill('#a855f7')
Star
Star(points = 5, outer = 80, inner = 40, options?)
Options:
rotation(radians)
Star(5, 90, 36).fill('#facc15')
RegularStar
RegularStar(points = 5, radius = 80, options?)
Options:
innerRatio(0..1)rotation(radians)
RegularStar(6, 85, { innerRatio: 0.45 }).fill('#f472b6')
Triangle
Triangle(width = 120, height = 100, options?)
Options:
direction:up | down | left | rightrightAngle:topLeft | topRight | bottomLeft | bottomRight
Triangle(140, 120, { direction: 'down' }).fill('#0f172a').stroke({ color: '#22d3ee', width: 4 })
Arc
Arc(radius = 80, startAngle = 0, endAngle = Math.PI / 2, options?)
Options:
innerRadiusthicknesscounterclockwise
If thickness is provided, innerRadius is computed as radius - thickness.
Arc(80, 0, Math.PI * 1.3, { thickness: 18 }).fill('#38bdf8')
Ring
Ring(outer = 80, inner = 50)
Ring(90, 55).fill('#0f172a').stroke({ color: '#38bdf8', width: 3 })
Pie
Pie(radius)
Pie(80).fill('#f97316').trim({ from: 0.7, to: 0.7, duration: 1 })
Spiral
Spiral(turns = 3, radius = 80, points = 200, options?)
Options:
startRadiusrotationclockwise(default true)
Spiral(3, 90, 220).stroke({ color: '#a3e635', width: 4 })
BezierPath
BezierPath(commands)
Commands:
{ cmd: 'moveTo', x, y }{ cmd: 'lineTo', x, y }{ cmd: 'quadTo', cpx, cpy, x, y }{ cmd: 'cubicTo', cp1x, cp1y, cp2x, cp2y, x, y }{ cmd: 'close' }
BezierPath([
{ cmd: 'moveTo', x: -120, y: 0 },
{ cmd: 'cubicTo', cp1x: -40, cp1y: -80, cp2x: 40, cp2y: 80, x: 120, y: 0 },
]).stroke({ color: '#22d3ee', width: 5 })
Text
Text(value, options?)
Options:
fontfontSize(default 24)fontFamily(default "Georgia")fontWeightfontStylelineHeight(defaults to 1.2 * fontSize)maxWidthwrap(default false)align(CanvasTextAlign, defaultcenter)baseline(CanvasTextBaseline, defaultmiddle)letterSpacing(default 0)
Text('Disclose', { fontSize: 54, fontWeight: 600, letterSpacing: 2 })
.fill('#f8fafc')
.stroke({ color: '#0ea5e9', width: 2 })
Image
Image(src, width?, height?)
Images are loaded asynchronously. If width/height are omitted, intrinsic size is used.
Image('https://placehold.co/320x200/png', 160, 120)
.fill('#0ea5e9')
.fillMode('screen')
Builder Helpers
Shape
Shape() returns a path builder you can fill with points using .path() or .paths().
Copy / every
Copy() is used with .every(interval, factory) to spawn clones over time.
Example:
Circle(6)
.fill('#22d3ee')
.every(200, () => Copy().opacity({ from: 1, to: 0, duration: 800 }))
Shape Coordinates
- Shapes are centered at
(0, 0)by default. Rect,RoundedRect,Capsule,Ellipse,Image, andTextare centered on their midpoints.Path,Polygon, andPolylineuse raw points as provided.- Use
.anchor()to change the local anchor when rotating/scaling.