011 - Export System

The Export System enables SVG export, snapshots, video, and exhibition mode.

Why Multiple Export Formats?

Different use cases require different formats:

Vector (SVG): For pen plotters, print, laser cutters. Resolution-independent, precise paths.

Raster (PNG/JPG): For screens, social media. Exactly as displayed.

Video: For animations, social reels, archive.

Exhibition Mode: For galleries. Automated operation, restart on crash, parameter changes.

Components

Class File Function
SVGExporter SVGExporter.ts Canvas → SVG
Snapshot Snapshot.ts Screenshot System
VideoExporter VideoExporter.ts Video Recording
SequencePlayer SequencePlayer.ts Snapshot Playlists
ExhibitionRunner ExhibitionRunner.ts Artwork Playlists
ExhibitionPackageBuilder ExhibitionPackageBuilder.ts Build Packages

SVG Export

Canvas-to-SVG conversion for plotters.

How Does It Work?

The SVGExporter doesn't "translate" canvas pixels – instead, it records all draw calls (lines, circles, arcs) and builds an SVG DOM tree. Each canvas layer becomes an SVG group (<g>).

Why is this complex? Because SVG has no gradient fills like Canvas, and vice versa. Some effects must be approximated.

Layer System

┌─────────────────────────────────────────┐
│              SVG Document               │
│  ┌───────────────────────────────────┐  │
│  │           <g id="layer-0">        │◄─── Background Layer
│  │  ┌─────────────────────────────┐  │
│  │  │  <rect fill="..."/>         │  │
│  │  └─────────────────────────────┘  │
│  └───────────────────────────────────┘  │
│  ┌───────────────────────────────────┐  │
│  │           <g id="layer-1">        │◄─── Shapes Layer
│  │  ┌─────────────────────────────┐  │
│  │  │  <circle cx="..."/>         │  │
│  │  │  <path d="..."/>            │  │
│  │  └─────────────────────────────┘  │
│  └───────────────────────────────────┘  │
│  ┌───────────────────────────────────┐  │
│  │           <g id="layer-2">        │◄─── Effects Layer
│  │  ┌─────────────────────────────┐  │
│  │  │  <polyline points="..."/>   │  │
│  │  └─────────────────────────────┘  │
│  └───────────────────────────────────┘  │
└─────────────────────────────────────────┘

SVGExporter API

Method Description
startDocument(width, height) Start SVG Document
endDocument() Complete and Return
beginLayer(name) Create new Layer
endLayer() Complete Layer
line(x1, y1, x2, y2) Draw Line
circle(cx, cy, r) Draw Circle
rect(x, y, w, h) Draw Rectangle
path(d) Draw SVG Path
polygon(points) Draw Polygon

Gradients and Patterns

The SVGExporter supports:

Type SVG Equivalent
LinearGradient <linearGradient>
RadialGradient <radialGradient>
Pattern <pattern>

Definition:

exporter.defineGradient({
  id: 'myGradient',
  type: 'linear',
  stops: [
    { offset: 0, color: '#FF0000' },
    { offset: 1, color: '#0000FF' },
  ],
});

exporter.setFill('url(#myGradient)');

Pen/Color Management

Method Description
setPen(penId) Set Pen (for Plotter)
setFill(color) Fill Color
setStroke(color, width) Stroke Color & Width
setOpacity(value) Transparency

Plotter Optimization

Option Description
optimizePaths Combine connected paths
sortPaths Sort for shortest travel
groupByColor Group by color (= pen)

Snapshots

Screenshots of the canvas.

Snapshot API

Method Description
take(canvas, opts) Create Snapshot
save(snapshot, path) Save to Disk
toDataURL(canvas) As Base64

Options

Option Type Description
format 'png' | 'jpg' File Format
quality number Quality (0-1)
scale number Scale Factor
includeMetadata boolean Include Parameters?

Metadata

Snapshots can contain embedded metadata:

{
  "timestamp": "2024-01-15T10:30:00Z",
  "artworkId": "sketch-001",
  "parameters": { "...": "..." },
  "dimensions": { "width": 1920, "height": 1080 }
}

Video Export

Record animations as MP4.

Flow

   Start Recording       Draw Loop        Stop Recording
         │                  │                   │
         ▼                  ▼                   ▼
   ┌──────────┐       ┌──────────┐        ┌──────────┐
   │ Configure│──────>│  Record  │───────>│  Encode  │
   │ Encoder  │       │  Frames  │        │ to MP4   │
   └──────────┘       └──────────┘        └──────────┘

VideoExporter API

Method Description
configure(opts) Configure
startRecording() Start Recording
addFrame(canvas) Add Frame
stopRecording() Stop & Encode

Options

Option Type Default Description
fps number 30 Frames per Second
bitrate number 5000000 Bitrate (bps)
codec string 'avc1.42001E' Video Codec
format 'mp4' | 'webm' 'webm' Container Format

Codec Support

Codec Quality Compat Description
vp8 Good Excellent WebM Standard
vp9 Very Good Good WebM New
avc1 Very Good Excellent H.264 (MP4)

SequencePlayer

Plays snapshots as a slideshow.

Concept

A "sequence" is a playlist with snapshots. Each entry has display duration, optional transition, and parameter restore.

SequencePlayer API

Method Description
loadSequence(playlist) Load Playlist
play() Start Playback
pause() Pause
stop() Stop
next() Next Image
previous() Previous Image

Playlist Format

{
  "name": "My Sequence",
  "items": [
    {
      "snapshotPath": "snapshot-001.png",
      "duration": 5000,
      "transition": "fade",
      "parameters": { "...": "..." }
    }
  ],
  "loop": true
}

Transitions

Transition Description
none Hard Cut
fade Fade In/Out
crossfade Blend
slide Slide In

ExhibitionRunner

Automated operation for galleries.

The Problem

In an exhibition, the artwork runs for days without supervision:

  • What if it crashes?
  • What if someone touches the USB cable?
  • How do you change artworks?

The Solution

ExhibitionRunner manages multiple artworks and handles all edge cases:

┌─────────────────────────────────────────────────────────┐
│                   ExhibitionRunner                       │
│  ┌─────────────────────────────────────────────────┐    │
│  │                 Scheduler                        │    │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐           │    │
│  │  │Artwork 1│ │Artwork 2│ │Artwork 3│           │    │
│  │  │ 10 min  │ │ 15 min  │ │ 10 min  │           │    │
│  │  └─────────┘ └─────────┘ └─────────┘           │    │
│  └─────────────────────────────────────────────────┘    │
│  ┌─────────────────────────────────────────────────┐    │
│  │               HealthMonitor                      │    │
│  │  • Heartbeat Check                              │    │
│  │  • Auto-Restart on Crash                        │    │
│  │  • Log Rotation                                 │    │
│  └─────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────┘

ExhibitionRunner API

Method Description
loadSchedule(schedule) Load Schedule
start() Start Exhibition
stop() Stop Exhibition
setEmergencyMode(on) Emergency Stop
getStatus() Current Status

Schedule Format

{
  "name": "Main Exhibition",
  "artworks": [
    {
      "path": "./artworks/waves/",
      "duration": 600,
      "parameters": { "speed": 0.5 }
    },
    {
      "path": "./artworks/particles/",
      "duration": 900
    }
  ],
  "options": {
    "loop": true,
    "restartOnCrash": true,
    "healthCheckInterval": 5000
  }
}

Health Monitoring

Check Interval Action
Heartbeat 5s Restart if Missing
Memory 60s Warn at >80%
Framerate 1s Warn at <15 FPS

Fallback Behavior

Event Reaction
Artwork Crashes Restart + Skip after 3x
All Artworks Crash Show Emergency Slide
USB Error Reload Context

ExhibitionPackageBuilder

Creates standalone exhibition packages.

Package Structure

exhibition-package/
├── index.html            # Entry Point
├── manifest.json         # Playlist + Settings
├── artworks/
│   ├── artwork-1/
│   │   ├── bundle.js
│   │   └── assets/
│   └── artwork-2/
├── snapshots/
│   └── emergency.png     # Fallback Image
└── launcher/
    ├── launcher.exe      # Windows
    ├── launcher.app      # macOS
    └── launcher.sh       # Linux

Builder API

Method Description
addArtwork(path, opts) Add Artwork
setManifest(manifest) Set Manifest
build(outputPath) Build Package
validate() Validate Package

Build Options

Option Description
minify Minify Code
includeLauncher Include Launcher
offlineAssets Bundle all Assets
signCode Code Signing (macOS)