The Lab
Techniques I’ve worked out on websites and projects, written up with the code that runs them.
P.S. A few of them are running on this page right now.
Fit
WebGL · CameraAn orthographic camera has no field of view to fall back on, so framing the hero room in an unknown viewport is arithmetic: two candidate zooms, one per axis, and the more restrictive one wins.
The diorama in the hero at the top of the home page, at any window size. Drag the browser edge about. The room grows and shrinks but never leaves the frame, because the thing being fitted is a box of world units.
Scrub
Scroll · GSAPThe statement on the home page is not triggered by scroll. It's played by it. Thirteen words ink in, half a beat apart, and the beat that matters most is the one where nothing animates at all.
This runs on the home page, just past the selected-work list: 'Worlds rendered live in the browser. You feel them before you read them.' inks in word by word as you scroll it, holds still, then leaves. Scroll it slowly, then scroll back up. It un-inks, because scroll is the only clock it has.
Magnet
GSAP · InteractionEvery text button and pill on this site leans toward the cursor as it approaches. The arithmetic is three lines. The thing that makes it read as weight rather than jitter is the fourth, and it's one GSAP call.
Every text button and pill on this site. The 'Start a project' pill in the home page hero is the nearest one, and the 'Go and look' button below this paragraph is another. Approach either slowly and watch it lean before you arrive.
Swarm
WebGL · InstancingFive packets crawl the cable across the floor of the hero, and between them they cost one draw call and five floats. An InstancedMesh, a Catmull-Rom curve, and a matrix buffer the CPU rewrites every frame.
The cable running across the floor from the rack to the desk in the hero diorama. The faint green pulses crawling along it are the packet feed. Watch one for a few seconds and you'll see it swell as it passes the middle of its run.
Halftone
WebGL · ShaderUnder the screenshots on the work index, one project's stripes dissolve into the next in three-pixel squares. Quantise the screen coordinate, hash the square, threshold once per cell. A dissolve made of grain rather than of edge.
The work index. Hover a project row and a panel parks beside it showing that project's screenshot. Underneath, this shader runs at a three-pixel cell, and you can catch its grain in the moment one screenshot hands over to the next.
Pool
Canvas · SimulationA pond you can tap, from two arrays and one line of arithmetic. The line is the wave equation written out longhand, and the thing that makes it look like water isn't the height. It's the slope.
Not on the site yet.
Shaft
WebGL · GeometryThe beam through the workshop window is not a post-processing pass. It's a five-quad prism from the window rectangle to its projection on the floor, rebuilt from the live sun vector every frame.
The window in the hero diorama on the home page. Click the window itself. It advances the sun twelve hours over 2.4 seconds, and the shaft is rebuilt on every frame of that sweep.
Plume
WebGL · ShaderThe steam off the coffee mug in the hero is one tall quad. The vertex shader folds it, the fragment shader carves its alpha out of scrolling noise, and nothing in it is a particle.
This is the plume rising off the mug on the desk in the hero diorama on the home page. One draw call, no simulation, and a per-frame cost of two uniform updates and an atan2.
Velocity
Scroll · MotionHow fast you're scrolling is a design input, and the browser never hands you a usable number for it. One line of smoothing turns a spiky per-frame delta into the signal half this site leans on.
Open any case study from the work index and scroll. The hero lines lean as they leave. The faster you go, the further they lean, up to four degrees and no further.
Dissolve
WebGL · ShaderEvery transition on this site is one shader eating the page from a corner. No slide, no wipe, no straight line anywhere. The whole trick is four lines, and it comes down to where you add the noise.
This is the same shader that runs when you open the menu from the button in the top right. Go on, open it, then come back.