An implementation of an artificial life program, first developed in
the 1980s. In brief, just three simple rules lead to intelligent
flocking behaviour. Implemented all my own tooling from the groundup,
including vector algebra and dynamic frame loop adjustments.
A re-implementation of Boids, but mounted inside a React component,
ready to be imported into your own React app.
A simple flashcard app for learning Braille. Uses the Leitner method
of spaced repetition to gradually build up your confidence.
A simple flashcard app for learning Morse Code. Uses a custom spaced
repetition method (although not strictly the Leitner method).
A tribute to the vaporwave aesthetic. Take a sunset trip through the
infinite metropolis. Rendered with
A Julia Set renderer whose initial offset value rotates through the
complex plane. Primarily written in Rust compiled to WASM, and called
A Lindenmayer fractal generator. Creates a random branch structure and
recursively reapplies it to itself. Written solely in Vanilla JS and
HTML5 Canvas. Dynamically computes ideal depth generation based on
A little Connect4 implementation. Can you beat the AI? Uses minimax
over a limited depth, falling back to a heuristic value heatmap when
that depth is exceeded.
A simple visualizer for Langton's Ant, a cellular automaton first
described by Christopher Gale Langton in 1986.
A simple population center simulation. Cities emerge over time, and
connect to one another. As they form more connections, they can grow
in size. But if they are not connected to a smaller city, they
collapse and decay.
Perlin noise in 2D starts by generating a grid of random unit vectors.
But what if the unit vectors were smoothly rotating over time? In this
project a create a smoothly animated Perlin noise field.
The famous bouncing DVD logo animation. The only twist I've added is
that it will never hit a corner exactly. I do this by initiallizing
the position with irrational numbers, but only ever advancing position
by integers. In this way we know we'll never hit a corner since they
are positioned at integer x-y-coordinates.
A clock represents the passage of time by the movement of three arms
rotating in front of a circular face. But what if we broke those
rules? 'Time After Time' is an experiment in visualizing time in
Initially intended to play around with Moiré effects, I ended up
dialling everything up to 11 and making this eyeball torturer.
A browser bookmarklet for providing hints while playing Wordle. The
provided hint is chosen at random without prior knowledge of the
A little experiment with voronoi cells. A cloud of points travel
randomly across the world space, while every frame the space is
divided by Voronoi cells. The heavy lifting is done by
Animates a rotating tiling system. I got the idea for this while
looking at a brick wall and observing that the conventional brick
laying pattern is great at preventing slipping vertically but not
horizontally. So I started wondering about tiling patterns which don't
allow slippage in any direction, and I made this to help me visualize
A minimal interface for performing Gravatar lookups. If a matching
Gravatar is not found, an
is displayed instead.
A simple weight tracker. Data is only stored in localstorage, unique
to your device and browser. No networking, no tracking, not a single
API call after the page load.
A one-day hack to build a physics simulation, which aims to
demonstrate that temperature mixing is an emergent property of thermal
expansion. Got the idea for this while watching a pot of water boil.
A little test of three.js, which itself uses WebGL. Renders a rotating
cube and some point lights in real time. A great example of how
Hand made raytracer using only Typescript. A fun experiment in the
mathematics of perspective geometry. Performance is very much
bottlenecked by the browser. But becomes fully memoized after 100
A minimal frontend to the brilliant
An API of Ice and Fire.
Featuring pagination, filtering and a little memoization.
A reusable React component and hook library. Complete with test
coverage, extensive documentation and publically available Storybook.
Living documentation is generated dynamically by JSDocs coming
directly from the source code itself. Primarily an exercise in
perfecting project processes, rather than creating a lot of content.