Skip to content

Dev & Deploy

Radim Brnka edited this page Mar 5, 2026 · 5 revisions

fractal-2026-01-22_19-40-42

Prerequisites

  • Node.js (v12 or later)
  • npm (or yarn)

Installation

  1. git clone https://github.com/rbrnka/fractal-traveler.git
  2. cd fractal-traveler
  3. npm install

Project Overview

You can use this section for a system prompt when working with AI in this repository.

Synaptory Fractal Traveler is a WebGL-based interactive fractal explorer (Mandelbrot, Julia, Riemann Zeta, Rössler Attractor) built with vanilla JavaScript + webpack. It runs entirely in the browser with GPU-accelerated GLSL shaders.

Commands

# Development with hot reload (localhost:8080)
npm start

# Development build (one-shot, no watch)
npm run build-dev-nowatch

# Development build with file watching
npm run build-dev-watch

# Production build (minified, no console.* calls)
npm run build-prod

# Run all tests
npm test

# Run a single test file
npx jest --config ./src/config/jest.config.js src/tests/<filename>.test.js

# Generate JSDoc documentation
npm run docs

# Launch palette editor tool (localhost:3030)
npm run palette-editor

Architecture

Entry Point & Initialization

src/main.js is the webpack entry point. On DOMContentLoaded it:

  1. Reads URL params to determine fractal type and initial position
  2. Instantiates the appropriate renderer (MandelbrotRenderer, JuliaRenderer, RiemannRenderer, or RosslerRenderer)
  3. Calls initUI(fractalApp) to wire up all controls
  4. Optionally animates to a URL-specified location

Renderer Class Hierarchy

Renderer (src/renderers/renderer.js)
  └─ FractalRenderer (src/renderers/fractalRenderer.js)       ← abstract: pan/zoom/rotate/animate/palette
       ├─ MandelbrotRenderer (src/renderers/mandelbrotRenderer.js)
       ├─ JuliaRenderer (src/renderers/juliaRenderer.js)
       ├─ RiemannRenderer (src/renderers/riemannRenderer.js)
       └─ RosslerRenderer (src/renderers/rosslerRenderer.js)
  • Renderer: WebGL context init, shader compilation, baseDraw() (full-screen quad)
  • FractalRenderer: pan/zoom/rotation state, palette management, animation engine (animateTravelToPreset, animateDive, demo tour), adaptive quality control, screenToFractal() conversion
  • Concrete renderers: implement createFragmentShaderSource(), init(), draw(), reset(), and hold their own PRESETS/PALETTES data loaded from JSON

Shaders

All GLSL shaders are in src/shaders/. Webpack loads them as raw strings via asset/source. Each renderer selects its fragment shader(s):

Renderer Shaders
Mandelbrot mandelbrot.frag (perturbation), mandelbrot.series.frag (series approx + perturbation)
Julia julia.frag (perturbation), julia.legacy.frag, julia.preview.frag
Riemann riemann.frag, riemann-borwein.frag, riemann-siegel.frag, riemann-double.frag, riemann-dirichlet.frag
Rössler rossler.frag

Shared vertex shader: vertexShaderInit.vert (full-screen quad, sets vTexCoord).

Mandelbrot and Julia use rebased perturbation theory with a reference orbit stored in a WebGL texture (OES_texture_float). The reference orbit is recalculated when the view drifts too far from the reference point.

Data / Presets

src/data/*.json holds curated presets and palettes for each fractal mode. These are imported directly by the respective renderer. The schema is in src/data/fractal.schema.json.

UI Layer

src/ui/ui.js is the central UI module — it holds all DOM wiring, button handlers, mode-switching logic, and calls back into the active renderer. Supporting UI modules:

  • hotkeyController.js — keyboard shortcuts
  • mouseEventHandlers.js / touchEventHandlers.js — pointer input (zoom, pan, rotate)
  • juliaSlidersController.js — Julia c-parameter sliders
  • juliaPreview.js / juliaPreviewRenderer.js — live Julia thumbnail in Mandelbrot mode
  • screenshotController.js — clean screenshot capture
  • debugPanel.js — on-screen diagnostics (dev builds only)
  • axesOverlay.js / zetaPathOverlay.js / zetaPathOverlayRS.js — canvas overlays

Global Utilities

  • src/global/constants.js — all constants, feature flags (FF_*), FRACTAL_TYPE enum, APP config, DEBUG_MODE (injected by webpack at build time)
  • src/global/utils.js — URL params, color conversion, math helpers, double-double arithmetic (ddMake, ddAdd, etc.)
  • src/global/utils.fractal.js — fractal-specific math (zoom/coordinate conversions)
  • src/global/types.js — JSDoc @typedef declarations only (no runtime code)
  • src/global/audioManager.js — Riemann tour background music

Feature Flags

Feature flags live in src/global/constants.js and are plain boolean constants (e.g., FF_ADAPTIVE_QUALITY, FF_RIEMANN_SHADER_DROPDOWN, FF_LEGACY_JULIA_RENDERER). Toggle them directly in that file.

Build Behavior

  • DEBUG_MODE: FULL in dev builds, NONE in production. All if (DEBUG_MODE) branches are tree-shaken in production. console.* calls are also dropped via Terser.
  • __APP_VERSION__: Injected from package.json via webpack DefinePlugin.
  • Output goes to dist/ (cleaned on each build).
  • Dev server: localhost:8080, HMR enabled.

Tests

Tests live in src/tests/ and use Jest + jsdom. Config: src/config/jest.config.js. GLSL shader files are mocked via src/tests/__mocks__/fileMock.js. Tests cover renderers, event handlers, UI, and utilities.

Tools

tools/palette-editor/ — standalone HTML tool for creating custom Julia palettes. Run with npm run palette-editor.

Documentation

  • Full documentation is available here.
  • Also, check out open issues and feel free to chime in!

Clone this wiki locally