002 - Core System

Das Core-System bildet das Fundament der cc-toolbox. Es löst ein zentrales Problem: Wie verwalte ich den State eines generativen Kunstwerks so, dass er persistierbar, synchronisierbar und über UI steuerbar ist?

Die Antwort: Ein zentrales ParameterObject, das als Single Source of Truth dient. Alle Komponenten lesen und schreiben darauf. Der IOManager koordiniert die Kommunikation, der TweakpaneManager bindet die UI an.

Komponenten

Klasse Datei Funktion
Artwork Artwork.ts Haupt-Container, initialisiert alles
SketchRunner Sketch.ts Führt Sketches aus
SceneGraph SceneGraph.ts Verwaltet Drawables/Agents
ParameterObject ParameterObject.ts Zentraler State-Store
IOManager IOManager.ts Event-Hub & Channels
TweakpaneManager TweakpaneManager.ts UI-Module-System
Format Format.ts Canvas-Formate (Screen, Print)
Viewport Viewport.ts Responsive Skalierung

Artwork

Der zentrale Container für jedes Kunstwerk.

Lifecycle:

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

Props:

Property Typ Beschreibung
canvas Canvas Canvas-Element & Größe
parameter ParameterObject Alle Parameter
tweakpane TweakpaneItems UI-Container
sceneGraph SceneGraph Agent-Container
format Format Aktives Format
animation AnimationState Timing-Info

SceneGraph

Verwaltet alle zeichenbaren Objekte (Agents/Drawables).

Features:

  • Hierarchische Struktur
  • Z-Order Management
  • Batch-Updates
  • Visibility Control

API:

Methode Beschreibung
add(agent) Agent hinzufügen
remove(agent) Agent entfernen
draw(ctx) Alle Agents zeichnen
forEach(fn) Über Agents iterieren

ParameterObject

Das ParameterObject ist das Herzstück der Architektur. Es ist ein einfaches JavaScript-Objekt, das den kompletten Zustand eines Artworks enthält – von Canvas-Größe über Farben bis zu Agent-spezifischen Einstellungen.

Warum so zentral?

Das Problem bei generativer Kunst: Man findet nach stundenlangem Tweaken endlich die perfekte Einstellung – und verliert sie beim nächsten Reload. Das ParameterObject löst das:

  1. Serialisierbar: Als JSON speicherbar (Snapshots!)
  2. Synchronisierbar: Über Sockets an Studio/andere Artworks
  3. UI-bindbar: Tweakpane liest und schreibt direkt darauf
  4. Versionierbar: Git-freundlich, diff-bar

Struktur:

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

Eigenschaften:

  • Serialisierbar (JSON)
  • Import/Export-fähig
  • Event-fähig über IOManager

IOManager

Der IOManager ist der Event-Hub der Anwendung. Er entkoppelt Komponenten voneinander – niemand muss direkt auf andere Komponenten zugreifen.

Das Problem ohne IOManager:

ColorSet ändert Farbe → muss alle Brushes kennen → enge Kopplung

Mit IOManager:

ColorSet → emits "colorset:changed" → IOManager → alle Subscriber bekommen es

Zwei Kommunikationsmuster:

  1. Channel-basiert (Pull)

    • Für Tweakpane-Updates
    • State-basiert
    • onUpdate() Callbacks
  2. Event-basiert (Pub/Sub)

    • Für Events wie colorset:changed
    • Payload-basiert
    • subscribe() / emit()

Beispiel-Events:

Event Payload Auslöser
colorset:changed { colors, id } ColorSet wechselt
format:changed { width, height } Format wechselt
parameter:updated { path, value } Parameter ändert sich

TweakpaneManager

Tweakpane ist eine fantastische UI-Library für Parameter-Manipulation. Aber bei komplexen Artworks mit vielen Agents wird das Management chaotisch: Wer schreibt wohin? Wessen State ist das?

Der TweakpaneManager löst das durch Module mit isolierten State-Bereichen. Jedes Modul:

  • Hat einen eigenen Namespace im ParameterObject
  • Kennt nur seinen eigenen State
  • Kommuniziert über IOManager-Channels

Das Brush-Pattern ist die Referenz-Implementierung: Ein Brush-Modul verwaltet parameter.tweakpane.{component}.brush.* und transformiert die UI-Werte (mit Prefix brush_) in Business-Logic-Werte (ohne Prefix).

Konzept:

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

TweakpaneModule API:

Methode Beschreibung
addBinding(key, params) UI-Control hinzufügen
onUpdate(handler) Update-Handler registrieren
getState() State lesen
setState(obj) State setzen

Format

Vordefinierte Canvas-Formate.

Kategorien:

Kategorie Beispiele
Screen 1080p, 4K, Instagram Square
Print A-Reihe A4, A3, A2 (300dpi)
Print US Letter, Legal
Custom Frei definierbar

Responsive Verhalten:

  • FitMode: 'contain' - In Container einpassen
  • FitMode: 'cover' - Container ausfüllen
  • FitMode: 'none' - Originalgröße

Vector

2D/3D Vektoroperationen.

Methoden:

Kategorie Methoden
Arithmetik add, subtract, multiply, divide
Länge magnitude, normalize, setMagnitude
Winkel angle, rotate, heading
Produkte dot, cross
Interpolation lerp, slerp
Utilities distance, clone, random

Coordinate & Size

Hilfsklassen für Positionen und Größen.

// 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 und Debugging-Utilities.

Modi:

  • silent - Keine Ausgabe
  • minimal - Nur Fehler
  • normal - Fehler + Warnungen
  • verbose - Alles

Methoden:

Methode Beschreibung
log(msg) Info-Log
warn(msg) Warnung
error(msg) Fehler
time(label) Timer starten
timeEnd(label) Timer stoppen