Code
Canvas
Basic Shapes
fillRect, strokeRect, arc, closePath and roundRect — the core drawing primitives.
Colors & Gradients
Linear, radial and conic gradients, drop shadows, and globalAlpha transparency.
Text Rendering
fillText, strokeText, font styles, textAlign, textBaseline, and measureText.
Transformations
translate, rotate, scale, setTransform and the save/restore state stack.
Bezier Paths
Quadratic and cubic Bézier curves, Path2D reuse, star polygons, and arcTo.
Animation Loop
requestAnimationFrame-driven bouncing balls with gravity, friction, and motion-blur trails.
Mouse Drawing
Interactive paint application — smooth draw/erase with brush colour and size controls.
Compositing Modes
All 16 globalCompositeOperation modes — from source-over to multiply and xor.
Pixel Manipulation
ImageData filters — grayscale, invert, sepia, brightness boost, and pixelate.
Particle System
Physics-based particles with buoyancy, turbulence, colour lifecycle, and additive blending.
Fractal Tree
Animated recursive fractal tree — dynamic branching angle with brown-to-green colour transition.
Conway's Game of Life
Cellular automaton on a toroidal grid — pause, resume, and randomise the population.
Flow Field
1,200 particles following a dynamic vector field built from layered sine/cosine noise.
Mandelbrot Set
Mandelbrot set with smooth colouring, auto-zooming into the Seahorse Valley.
Generative Art
Algorithmic tile grid — noise-driven hue and rotation with layered concentric ring overlays.
Fractal Tree
Advanced Animated recursive fractal tree — branching angle and shorten factor oscillate over time, colour transitions from bark to leaf.
let t = 0;
const branch = (
x: number, y: number,
angle: number, len: number,
depth: number
) => {
if (depth === 0 || len < 2) return;
const x2 = x + Math.cos(angle) * len;
const y2 = y + Math.sin(angle) * len;
// Brown trunk → green leaves
const ratio = 1 - depth / 12;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x2, y2);
ctx.strokeStyle = `rgb(
${101 - ratio * 50},
${67 + ratio * 100},
${33 + ratio * 20}
)`;
ctx.lineWidth = Math.max(0.5, depth * 0.8);
ctx.stroke();
// Animate spread & length with sin/cos
const spread = 0.45 + 0.1 * Math.sin(t);
const shorten = 0.67 + 0.04 * Math.cos(t * 0.7);
branch(x2, y2, angle - spread, len * shorten, depth - 1);
branch(x2, y2, angle + spread, len * shorten, depth - 1);
};
const draw = () => {
ctx.clearRect(0, 0, W, H);
// Start from bottom centre, pointing up (-π/2)
branch(W / 2, H - 20, -Math.PI / 2, H * 0.28, 12);
t += 0.012;
requestAnimationFrame(draw);
};Key Concepts
- Each recursive call draws one branch segment, then calls itself twice (left and right child)
- Base cases:
depth === 0orlen < 2— prevents infinite recursion - Branch angle in radians:
-Math.PI/2= straight up; add/subtractspread - Multiply length by
shorten < 1each level for exponential reduction - Modulate spread and shorten with
Math.sin(t)for a breathing/wind animation - 12 levels of recursion = 2¹² = 4096 leaf tips (keep depth ≤ 13 for performance)