Off the clock
Art made from code.
- What
- Generative art I write myself. Six pieces, one for each turn in my story.
- How
- Each piece is a single TypeScript function drawing to an HTML canvas, 60 times a second. No images, no art libraries.
- Why it's here
- It's where I practise the maths, motion and performance work that goes into the products.
Every tile is the live piece. Move over it, then open it full screen to make a new variation.
The pieces, and what each one runs on
- 01Survey
Where it started: field geology
WhyA geologist reads ground through contour lines. This is that map, alive, so you can disturb the terrain.
HowLayered noise makes a height field. Marching squares traces 13 contour levels across it every frame, with every fourth line drawn heavier as on a survey sheet. Your cursor raises a borehole.
TypeScript · Canvas 2D · Fractal value noise · Marching squares · requestAnimationFrame
- 02Current
Native ads and content: attention as a current
WhyNative ads taught me that attention moves like water. You cannot push it, only read the current.
HowAbout two thousand particles take their direction from a noise field. Each frame fades the last one, so movement leaves trails. Within 160 px of your cursor they are pulled into a vortex.
TypeScript · Canvas 2D · Flow field · Particle system · Alpha-blended trails
- 03Interference
Building a team: patterns that only exist together
WhyA team makes patterns no single person has. Building a 24-person team felt like this.
HowTwo sets of concentric rings: one drifts slowly, the other follows your cursor. The rippling pattern exists only where they overlap.
TypeScript · Canvas 2D · Moiré interference
- 04Signal field
Going all-in on AI
WhyAI, for me, is structure that still moves: a grid that keeps its shape while something flows through it.
HowA grid of short strokes, each angled by a slow sine field. Near your cursor the angles bend into a vortex and turn coral. It is the same grid as the hero of this site.
TypeScript · Canvas 2D · Vector field · Shared with the v7 hero
- 050.10 inch
Running a US operation, then CompliSure
WhyThe CompliSure rule as a toy: rain only counts when an unbroken run reaches a tenth of an inch.
HowDrops that land in the gauge raise its level. Your cursor is an umbrella: hold it over the gauge and the run breaks, so the level resets to zero, exactly as the permit rule does. Let the rain reach 0.10 inch unbroken and the gauge stamps QUALIFYING.
TypeScript · Canvas 2D · Particle simulation · Small state machine
- 06Lahore, 7 pm
Now: Lahore evenings, California mornings
WhyThe hour I start work: seven in the evening in Lahore, while California wakes up.
HowThe sky is drawn as horizontal bands and the sun is cut into the same bands. Below the horizon the rows ripple like water. Your cursor moves the sun.
TypeScript · Canvas 2D · Scanline rendering
How I make these
- 1
Start from the story
One turn in my life, one feeling. Survey is a geologist's map; 0.10 inch is the rule CompliSure enforces.
- 2
Write the rule in one sentence
Before any code: what moves, what it obeys, what your hand changes. If the sentence is fuzzy, the piece will be too.
- 3
Prototype on a bare canvas
TypeScript and the Canvas 2D API, no libraries. Tune by eye until it feels right at rest and when touched.
- 4
Make it safe to ship
Sharp on retina screens, paused when off screen, a still frame for people who turn motion off, light enough for a phone.
The toolkit
- Language
- TypeScript
- Rendering
- Canvas 2D, requestAnimationFrame, device-pixel-ratio sizing
- Maths
- Value noise and fBm, marching squares, vector and flow fields, particle systems
- Performance
- IntersectionObserver pauses pieces off screen; ResizeObserver keeps them sharp
- Accessibility
- Reduced-motion users get a still frame; every piece has a written description