Fractal tree

프랙탈 나무

A trunk that splits into two shorter branches, each of which splits again by the exact same rule.

Also known as: Recursive treeBinary tree fractal
···
js
const c = document.createElement('canvas');
document.body.appendChild(c);
c.style.width = '100%'; c.style.height = '100%';
const ctx = c.getContext('2d');
const cs = getComputedStyle(document.documentElement);
const ACCENT3 = cs.getPropertyValue('--accent-3').trim() || '#18c29c';
let w, h;
function resize() {
  const dpr = Math.min(devicePixelRatio || 1, 2);
  w = innerWidth; h = innerHeight;
  c.width = w * dpr; c.height = h * dpr;
  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
addEventListener('resize', resize);
resize();

function branch(x, y, len, ang, depth, sway) {
  if (depth === 0 || len < 3) return;
  const nx = x + Math.cos(ang) * len, ny = y + Math.sin(ang) * len;
  ctx.lineWidth = Math.max(0.6, depth * 0.9);
  ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(nx, ny); ctx.stroke();
  const spread = 0.5 + sway;
  branch(nx, ny, len * 0.72, ang - spread, depth - 1, sway);
  branch(nx, ny, len * 0.72, ang + spread, depth - 1, sway);
}
function draw(t) {
  ctx.fillStyle = '#0d0d12'; ctx.fillRect(0, 0, w, h);
  ctx.strokeStyle = ACCENT3; ctx.lineCap = 'round';
  const sway = Math.sin(t * 0.0009) * 0.07;
  const baseLen = Math.min(w, h) * 0.24;
  branch(w / 2, h * 0.92, baseLen, -Math.PI / 2, 10, sway);
}
draw(0); // 재귀는 즉시 끝나므로 첫 프레임부터 나무 전체가 보인다
(function loop(t) { draw(t); requestAnimationFrame(loop); })(0);

"Draw a line, then from its tip draw two shorter lines angled slightly left and right, then repeat the exact same thing from each of those" — that one sentence becomes a function that calls itself (recursion), verbatim. Where an L-system reaches the same shape through string rewriting, a fractal tree gets there through recursive calls that pass down coordinates and angle directly — same concept, a different implementation path.

Each split shortens the branch by some ratio (say 0.72×), and without a depth limit (say 10 levels) the recursion never stops — a "stop once you reach this depth" condition is mandatory. Deeper trees grow exponentially more complex (branch count is 2 to the power of depth), and just three numbers — angle, length ratio, depth — swing the silhouette anywhere from a pine to a shrub.

This demo adds a small time-based sway to the angle every frame, so instead of a frozen diagram it reads like a tree moving in the wind. It's a textbook example for teaching recursion visually, and in design work it's used for branch-, vein- or river-like textures in a background.

When to use

Use it for branch-, vein- or lightning-like background textures, or to visually teach recursion. Cost grows sharply past about 12 levels of depth.