🌀 Mandelbrot Set Tutorial

Learn to code fractals in TypeScript with interactive zoom

What is the Mandelbrot Set?

The Mandelbrot set is a mathematical set of complex numbers that creates stunning fractal patterns. A point c belongs to the Mandelbrot set if the sequence:

zâ‚€ = 0
z_{n+1} = z_n² + c

remains bounded (doesn't go to infinity) as n approaches infinity.

Step 1: Setup the Canvas

First, we create a canvas and get its 2D rendering context:

const canvas = document.getElementById('canvas') as HTMLCanvasElement; const ctx = canvas.getContext('2d')!; const width = 500; const height = 500; canvas.width = width; canvas.height = height;

Step 2: Define the Viewport

We need to map pixel coordinates to complex number coordinates:

let minX = -2.5, maxX = 1.0; let minY = -1.0, maxY = 1.0;

These define the initial viewing window in the complex plane.

Step 3: The Mandelbrot Function

This function checks if a complex number is in the set:

function mandelbrot(cx: number, cy: number): number { let x = 0, y = 0; let iteration = 0; const maxIter = 100; while (x*x + y*y <= 4 && iteration < maxIter) { const xTemp = x*x - y*y + cx; y = 2*x*y + cy; x = xTemp; iteration++; } return iteration; }

Key points:

• We iterate z = z² + c starting from z = 0

• If |z| > 2, the point escapes to infinity

• We return how many iterations it took to escape

Step 4: Drawing the Fractal

We iterate through each pixel and color it based on iterations:

function draw() { const imageData = ctx.createImageData(width, height); for (let px = 0; px < width; px++) { for (let py = 0; py < height; py++) { // Map pixel to complex plane const x = minX + (px / width) * (maxX - minX); const y = minY + (py / height) * (maxY - minY); const iter = mandelbrot(x, y); const color = getColor(iter); const idx = (py * width + px) * 4; imageData.data[idx] = color.r; imageData.data[idx + 1] = color.g; imageData.data[idx + 2] = color.b; imageData.data[idx + 3] = 255; } } ctx.putImageData(imageData, 0, 0); }

Step 5: Coloring the Fractal

We use the iteration count to create beautiful colors:

function getColor(iteration: number) { if (iteration === 100) { return { r: 0, g: 0, b: 0 }; } const hue = (iteration / 100) * 360; // Convert HSL to RGB... }

Step 6: Click to Zoom

Add interactivity by zooming into clicked areas:

canvas.addEventListener('click', (e) => { const rect = canvas.getBoundingClientRect(); const px = e.clientX - rect.left; const py = e.clientY - rect.top; // Convert to complex coordinates const x = minX + (px / width) * (maxX - minX); const y = minY + (py / height) * (maxY - minY); // Zoom in by 2x around clicked point const rangeX = (maxX - minX) / 4; const rangeY = (maxY - minY) / 4; minX = x - rangeX; maxX = x + rangeX; minY = y - rangeY; maxY = y + rangeY; draw(); });

Try It Yourself!

Click anywhere on the fractal to zoom in 2x on that location. Use the reset button to return to the original view.

Tip: Try clicking on the edges of the set where you see intricate patterns!

Current View:
X: -2.5 to 1.0
Y: -1.0 to 1.0
Next TypeScript tutorial: Animated plasma effect