002 - Core System

The core system forms the foundation of the cc-toolbox. It solves a central problem: How do I manage the state of a generative artwork so that it's persistable, synchronizable, and controllable via UI?

The answer: A central ParameterObject that serves as the single source of truth. All components read from and write to it. The IOManager coordinates communication, and the TweakpaneManager binds the UI.

Components

Class File Function
Artwork Artwork.ts Main container, initializes everything
SketchRunner Sketch.ts Executes Sketches
SceneGraph SceneGraph.ts Manages Drawables/Agents
ParameterObject ParameterObject.ts Central State Store
IOManager IOManager.ts Event Hub & Channels
TweakpaneManager TweakpaneManager.ts UI Module System
Format Format.ts Canvas Formats (Screen, Print)
Viewport Viewport.ts Responsive Scaling

Artwork

The central container for each artwork.

Lifecycle:

    User           Sketch          Artwork         SceneGraph
      │               │               │               │
      │ SketchRunner  │               │               │
      │   .run()      │               │               │
      │──────────────>│               │               │
      │               │ new Artwork() │               │
      │               │──────────────>│               │
      │               │               │ initCanvas()  │
      │               │               │ initTweakpane()
      │               │ configure()   │               │
      │               │──────────────>│               │
      │               │               │ addAgent()    │
      │               │               │──────────────>│
      │               │               │               │
      │               │    ┌──────────────────────────┤
      │               │    │     Render Loop          │
      │               │    │                          │
      │               │ draw()        │               │
      │               │<──────────────│               │
      │               │    draw()     │               │
      │               │──────────────────────────────>│
      │               │    │                          │
      │               │    └──────────────────────────┤
      │               │               │               │

Props:

Property Type Description
canvas Canvas Canvas Element & Size
parameter ParameterObject All Parameters
tweakpane TweakpaneItems UI Container
sceneGraph SceneGraph Agent Container
format Format Active Format
animation AnimationState Timing Info

SceneGraph

Manages all drawable objects (Agents/Drawables).

Features:

  • Hierarchical Structure
  • Z-Order Management
  • Batch Updates
  • Visibility Control

API:

Method Description
add(agent) Add Agent
remove(agent) Remove Agent
draw(ctx) Draw All Agents
forEach(fn) Iterate Over Agents

ParameterObject

The ParameterObject is the heart of the architecture. It's a simple JavaScript object that contains the complete state of an artwork – from canvas size to colors to agent-specific settings.

Why so central?

The problem with generative art: You find the perfect setting after hours of tweaking – and lose it on the next reload. The ParameterObject solves this:

  1. Serializable: Saveable as JSON (Snapshots!)
  2. Synchronizable: Via Sockets to Studio/other Artworks
  3. UI-bindable: Tweakpane reads and writes directly to it
  4. Versionable: Git-friendly, diffable

Structure:

parameter
├── artwork                    # Artwork Settings
│   ├── canvas
│   └── animation
├── format                     # Format Settings
├── colorset                   # Active Colors
├── tweakpane                  # UI State (prefixed)
│   └── {component}
│       └── {subcomponent}
│           └── {key}: value
└── {agent}                    # Agent-specific
    └── {property}: value

Properties:

  • Serializable (JSON)
  • Import/Export capable
  • Event-capable via IOManager

IOManager

The IOManager is the event hub of the application. It decouples components from each other – no one needs to access other components directly.

The problem without IOManager:

ColorSet changes color → must know all Brushes → tight coupling

With IOManager:

ColorSet → emits "colorset:changed" → IOManager → all Subscribers receive it

Two communication patterns:

  1. Channel-based (Pull)

    • For Tweakpane updates
    • State-based
    • onUpdate() Callbacks
  2. Event-based (Pub/Sub)

    • For events like colorset:changed
    • Payload-based
    • subscribe() / emit()

Example Events:

Event Payload Trigger
colorset:changed { colors, id } ColorSet changes
format:changed { width, height } Format changes
parameter:updated { path, value } Parameter changes

TweakpaneManager

Tweakpane is a fantastic UI library for parameter manipulation. But with complex artworks with many agents, management becomes chaotic: Who writes where? Whose state is that?

The TweakpaneManager solves this through modules with isolated state areas. Each module:

  • Has its own namespace in the ParameterObject
  • Knows only its own state
  • Communicates via IOManager channels

The Brush Pattern is the reference implementation: A Brush module manages parameter.tweakpane.{component}.brush.* and transforms UI values (with prefix brush_) into business logic values (without prefix).

Concept:

TweakpaneManager
├── createModule(options)     → TweakpaneModule
│   ├── id: "brush:shape"
│   ├── statePath: ["brush", "shape"]
│   ├── stateDefaults: {...}
│   └── channelId: "ui:brush:shape"
└── modules: Map<id, Module>

TweakpaneModule API:

Method Description
addBinding(key, params) Add UI Control
onUpdate(handler) Register Update Handler
getState() Read State
setState(obj) Set State

Format

Predefined canvas formats.

Categories:

Category Examples
Screen 1080p, 4K, Instagram Square
Print A-Series A4, A3, A2 (300dpi)
Print US Letter, Legal
Custom Freely definable

Responsive Behavior:

  • FitMode: 'contain' - Fit in container
  • FitMode: 'cover' - Fill container
  • FitMode: 'none' - Original size

Vector

2D/3D vector operations.

Methods:

Category Methods
Arithmetic add, subtract, multiply, divide
Length magnitude, normalize, setMagnitude
Angle angle, rotate, heading
Products dot, cross
Interpolation lerp, slerp
Utilities distance, clone, random

Coordinate & Size

Helper classes for positions and sizes.

// Coordinate - Row/Col
const coord = new Coordinate(row, col);

// Size - Width/Height
const size = new Size(width, height);
size.area;     // → width * height
size.aspect;   // → width / height

Debug

Logging and debugging utilities.

Modes:

  • silent - No output
  • minimal - Errors only
  • normal - Errors + Warnings
  • verbose - Everything

Methods:

Method Description
log(msg) Info Log
warn(msg) Warning
error(msg) Error
time(label) Start Timer
timeEnd(label) Stop Timer