← Prompts

Fractal Explorer

Read the current prompt
# Task: Build an Interactive Fractal Explorer

Build an interactive Mandelbrot & Julia set explorer (vanilla JS, no external assets, no CDN, no libraries) with deep, smooth zooming and beautiful coloring. The top priority is **rendering performance and math precision** — frame-by-frame responsiveness while zooming, and correct iteration math at every depth.

## Core Specification

**Rendering Engine**
- Canvas 2D with an `ImageData`/typed-array pixel pipeline (compute escape iterations into a buffer, colorize, blit — no per-pixel DOM or rect calls)
- Escape-time algorithm with **smooth (continuous) coloring** — the fractional iteration count (`n + 1 - log2(log|z|)`) so bands don't appear
- Iteration limit that scales with zoom depth (deeper zooms need more iterations; tie it to magnification, with a manual override slider)
- Progressive rendering: draw a coarse pass fast (e.g. 1/4 resolution), refine to full resolution — the view must never freeze for seconds on interaction; cancel in-flight renders when the view changes
- Optional: render tiles via Web Workers (inline via Blob URL) — welcome if you can keep it simple, skip if it compromises correctness

**Navigation**
- **Click-and-drag rectangle zoom:** drag a selection box, release to zoom into exactly that region — with a live rectangle overlay
- **Wheel zoom** toward the cursor at a smooth rate; **drag to pan** (with momentum optional)
- Depth/magnification readout (e.g. `×3.4e9`), back button (zoom history stack), reset view
- **Julia mode:** click any point (or press J) to open the Julia set for that c-value — in a second pane or swapped main view; moving the cursor over the Mandelbrot view can live-preview the Julia set for the hovered c

**Coloring**
- At least 4 selectable palettes (e.g. fire, ocean, monochrome, psychedelic cyclic) with smooth interpolation between palette stops
- Interior (set membership) rendered black
- Palette cycling offset slider for animated color drift if desired (must not recompute iterations — colorize pass only)

**Precision & Limits**
- Standard double-precision zoom is fine to ~1e13 magnification; document and enforce a max-depth cap where precision visibly degrades (block zooming past it or warn)
- Save/load: bookmark named views (center, zoom, palette, iterations, set type, Julia c) into `localStorage`; URL-hash state (shareable link) optional but nice

## Visual Style
- Full-bleed canvas; a minimal glassy HUD (magnification, center coordinates, iterations, FPS) that hides when idle
- Crosshair/reticle in Julia-preview mode; elegant zoom-box overlay with inverted-color border
- Palette selector as swatch chips; everything keyboard-accessible (arrows pan, +/- zoom)

## Technical Requirements
- Vanilla JS; all code organized with clear section comments
- The core iteration loop must be allocation-free (no objects/arrays created per pixel per frame)
- Tunable constants block at the top (max iterations base/scale, zoom speed, palettes, progressive-refine passes)
- Expose a minimal debug interface on `window` (e.g. `fractal.iterationsAt(re, im)`, `fractal.setView({re, im, scale})`) so the math can be probed headlessly

## Quality Bar (must hit all)
- Iteration counts are mathematically correct: known interior points (e.g. c = 0, c = -1) reach max iterations; known exterior points (e.g. c = 2) escape immediately
- Drag-zoom lands on exactly the selected rectangle — the region framed is the region rendered (aspect-ratio handling must not silently shift it)
- Continuous coloring: no hard band edges when smooth coloring is on
- Interaction stays responsive while rendering: panning during a progressive render cancels and restarts without artifacts or ghost tiles
- A bookmark restored from `localStorage` reproduces the identical view

## Self-Check Before Finishing
Verify with the browser tools, using the debug interface:
- `iterationsAt(0, 0)` and `iterationsAt(-1, 0)` hit the max-iteration cap (interior); `iterationsAt(2, 0)` escapes in ≤ 3 iterations; `iterationsAt(0.25, 0)` (cusp boundary) shows the expected high-but-finite escape
- Zoom 1000× into a seahorse-valley location and confirm the render still shows structure (not flat noise or bands of precision garbage)
- Programmatically drag-select a rectangle and assert the resulting view center/scale match the selection math
- Save a bookmark, change the view, restore the bookmark, and assert the view state is identical