# winchxyz/spiralist architecture

> Architecture diagram of the GitHub repository winchxyz/spiralist, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/winchxyz/spiralist
- Repository: https://github.com/winchxyz/spiralist

## Overview

Spiralist is a browser-based drawing studio: a user supplies a photo, adjusts its tone and drawing options, then generates a continuous-line artwork rendered with selected media and paper. Its distinct drawing engines support Artistic, Realistic, and Line art modes; additional workflows produce cinematic films, exports, and 3D-printable objects. The app coordinates the main drawing flow, while workers handle costly geometry and mesh operations. The map reflects README capabilities and sampled imports/documentation; several UI-to-subsystem connections are indicated only where supported by the available evidence.

Main entry points: [`js/app.js`](https://github.com/winchxyz/spiralist/blob/main/js/app.js) (App coordinator), [`js/lineart/index.js`](https://github.com/winchxyz/spiralist/blob/main/js/lineart/index.js) (Line art engine), [`js/film.js`](https://github.com/winchxyz/spiralist/blob/main/js/film.js) (Film studio), [`js/print3d/dialog.js`](https://github.com/winchxyz/spiralist/blob/main/js/print3d/dialog.js) (3D print controls)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_studio["Studio workflow"]
  node_app["App coordinator<br/>[app.js]"]
  node_photo["Photo and crop<br/>[imageio.js]"]
  node_tone["Tone field<br/>[tone.js]"]
end

subgraph group_drawing["Drawing engines"]
  node_paths["Line paths<br/>[spiral.js]"]
  node_maze["Maze path<br/>[maze.js]"]
  node_lineart["Line art engine<br/>[index.js]"]
  node_lineanalysis["Contour analysis<br/>[lines.js]"]
  node_lineworker["Line art worker<br/>[worker.js]"]
  node_linebuild["Styled line builder<br/>[styles.js]"]
  node_real["Realistic engine<br/>[index.js]"]
  node_realworker["Realistic worker<br/>[worker.js]"]
  node_media["Brushes and papers<br/>[materials.js]"]
  node_renderer["Artwork renderer<br/>[renderer.js]"]
  node_loupe["Paper loupe<br/>[loupe.js]"]
end

subgraph group_outputs["Creation outputs"]
  node_film["Film studio<br/>[film.js]"]
  node_desks["Desk scenes<br/>[desks.js]"]
  node_export["Artwork export<br/>[export.js]"]
  node_download["Download and share<br/>[download.js]"]
  node_printdialog["3D print controls<br/>[dialog.js]"]
  node_printworker["3D mesh worker<br/>[worker.js]"]
  node_products["Print products<br/>[products.js]"]
  node_printmesh["Mesh and files<br/>[mesh.js]"]
  node_toolpath["Print timelapse<br/>[toolpath.worker.js]"]
end

subgraph group_state["Local experience"]
  node_store[("Local persistence<br/>[store.js]")]
  node_offline["Offline cache<br/>[sw.js]"]
end

node_user(("Photo artist"))
node_models["Local model assets"]

node_user -->|"sets options"| node_app
node_user -->|"chooses photo"| node_photo
node_app -->|"loads and crops"| node_photo
node_app -->|"builds tone field"| node_tone
node_app -->|"builds line geometry"| node_paths
node_app -->|"builds maze path"| node_maze
node_app -->|"requests line art"| node_lineart
node_lineart -->|"extracts contours"| node_lineanalysis
node_lineart -->|"dispatches geometry"| node_lineworker
node_lineworker -->|"builds styled lines"| node_linebuild
node_app -->|"builds realistic line"| node_real
node_real -.->|"dispatches build"| node_realworker
node_app -->|"selects materials"| node_media
node_app -->|"renders artwork"| node_renderer
node_app -->|"tracks draw progress"| node_film
node_film -->|"composes film"| node_renderer
node_film -->|"selects desk scene"| node_desks
node_app -.->|"exports artwork"| node_export
node_export -.->|"renders export"| node_renderer
node_app -.->|"downloads or shares"| node_download
node_app -.->|"opens loupe"| node_loupe
node_app -.->|"opens print tools"| node_printdialog
node_printdialog -->|"dispatches mesh work"| node_printworker
node_printworker -->|"builds product"| node_products
node_printworker -->|"writes print files"| node_printmesh
node_printdialog -.->|"requests print preview"| node_toolpath
node_app -->|"persists choices"| node_store
node_app -.->|"registers offline support"| node_offline
node_lineart -.->|"loads local models"| node_models

click node_app "https://github.com/winchxyz/spiralist/blob/main/js/app.js"
click node_photo "https://github.com/winchxyz/spiralist/blob/main/js/imageio.js"
click node_tone "https://github.com/winchxyz/spiralist/blob/main/js/tone.js"
click node_paths "https://github.com/winchxyz/spiralist/blob/main/js/spiral.js"
click node_maze "https://github.com/winchxyz/spiralist/blob/main/js/maze.js"
click node_lineart "https://github.com/winchxyz/spiralist/blob/main/js/lineart/index.js"
click node_lineanalysis "https://github.com/winchxyz/spiralist/blob/main/js/lineart/lines.js"
click node_lineworker "https://github.com/winchxyz/spiralist/blob/main/js/lineart/worker.js"
click node_linebuild "https://github.com/winchxyz/spiralist/blob/main/js/lineart/styles.js"
click node_real "https://github.com/winchxyz/spiralist/blob/main/js/real/index.js"
click node_realworker "https://github.com/winchxyz/spiralist/blob/main/js/real/worker.js"
click node_media "https://github.com/winchxyz/spiralist/blob/main/js/materials.js"
click node_renderer "https://github.com/winchxyz/spiralist/blob/main/js/renderer.js"
click node_loupe "https://github.com/winchxyz/spiralist/blob/main/js/loupe.js"
click node_film "https://github.com/winchxyz/spiralist/blob/main/js/film.js"
click node_desks "https://github.com/winchxyz/spiralist/blob/main/js/desks.js"
click node_export "https://github.com/winchxyz/spiralist/blob/main/js/export.js"
click node_download "https://github.com/winchxyz/spiralist/blob/main/js/download.js"
click node_printdialog "https://github.com/winchxyz/spiralist/blob/main/js/print3d/dialog.js"
click node_printworker "https://github.com/winchxyz/spiralist/blob/main/js/print3d/worker.js"
click node_products "https://github.com/winchxyz/spiralist/blob/main/js/print3d/products.js"
click node_printmesh "https://github.com/winchxyz/spiralist/blob/main/js/print3d/mesh.js"
click node_toolpath "https://github.com/winchxyz/spiralist/blob/main/js/print3d/toolpath.worker.js"
click node_store "https://github.com/winchxyz/spiralist/blob/main/js/store.js"
click node_offline "https://github.com/winchxyz/spiralist/blob/main/sw.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_photo,node_tone toneBlue
class node_paths,node_maze,node_lineart,node_lineanalysis,node_lineworker,node_linebuild,node_real,node_realworker,node_media,node_renderer,node_loupe toneAmber
class node_film,node_desks,node_export,node_download,node_printdialog,node_printworker,node_products,node_printmesh,node_toolpath toneMint
class node_store,node_offline toneRose
class node_user,node_models toneIndigo
```

## Components

### Studio workflow

- [App coordinator](https://github.com/winchxyz/spiralist/blob/main/js/app.js): `js/app.js`
- [Photo and crop](https://github.com/winchxyz/spiralist/blob/main/js/imageio.js): `js/imageio.js`
- [Tone field](https://github.com/winchxyz/spiralist/blob/main/js/tone.js): `js/tone.js`

### Drawing engines

- [Line paths](https://github.com/winchxyz/spiralist/blob/main/js/spiral.js): `js/spiral.js`
- [Maze path](https://github.com/winchxyz/spiralist/blob/main/js/maze.js): `js/maze.js`
- [Line art engine](https://github.com/winchxyz/spiralist/blob/main/js/lineart/index.js): `js/lineart/index.js`
- [Contour analysis](https://github.com/winchxyz/spiralist/blob/main/js/lineart/lines.js): `js/lineart/lines.js`
- [Line art worker](https://github.com/winchxyz/spiralist/blob/main/js/lineart/worker.js): `js/lineart/worker.js`
- [Styled line builder](https://github.com/winchxyz/spiralist/blob/main/js/lineart/styles.js): `js/lineart/styles.js`
- [Realistic engine](https://github.com/winchxyz/spiralist/blob/main/js/real/index.js): `js/real/index.js`
- [Realistic worker](https://github.com/winchxyz/spiralist/blob/main/js/real/worker.js): `js/real/worker.js`
- [Brushes and papers](https://github.com/winchxyz/spiralist/blob/main/js/materials.js): `js/materials.js`
- [Artwork renderer](https://github.com/winchxyz/spiralist/blob/main/js/renderer.js): `js/renderer.js`
- [Paper loupe](https://github.com/winchxyz/spiralist/blob/main/js/loupe.js): `js/loupe.js`

### Creation outputs

- [Film studio](https://github.com/winchxyz/spiralist/blob/main/js/film.js): `js/film.js`
- [Desk scenes](https://github.com/winchxyz/spiralist/blob/main/js/desks.js): `js/desks.js`
- [Artwork export](https://github.com/winchxyz/spiralist/blob/main/js/export.js): `js/export.js`
- [Download and share](https://github.com/winchxyz/spiralist/blob/main/js/download.js): `js/download.js`
- [3D print controls](https://github.com/winchxyz/spiralist/blob/main/js/print3d/dialog.js): `js/print3d/dialog.js`
- [3D mesh worker](https://github.com/winchxyz/spiralist/blob/main/js/print3d/worker.js): `js/print3d/worker.js`
- [Print products](https://github.com/winchxyz/spiralist/blob/main/js/print3d/products.js): `js/print3d/products.js`
- [Mesh and files](https://github.com/winchxyz/spiralist/blob/main/js/print3d/mesh.js): `js/print3d/mesh.js`
- [Print timelapse](https://github.com/winchxyz/spiralist/blob/main/js/print3d/toolpath.worker.js): `js/print3d/toolpath.worker.js`

### Local experience

- [Local persistence](https://github.com/winchxyz/spiralist/blob/main/js/store.js): `js/store.js`
- [Offline cache](https://github.com/winchxyz/spiralist/blob/main/sw.js): `sw.js`

### Other components

- **Photo artist**
- **Local model assets**

## Connections

- Photo artist → App coordinator: sets options
- Photo artist → Photo and crop: chooses photo
- App coordinator → Photo and crop: loads and crops
- App coordinator → Tone field: builds tone field
- App coordinator → Line paths: builds line geometry
- App coordinator → Maze path: builds maze path
- App coordinator → Line art engine: requests line art
- Line art engine → Contour analysis: extracts contours
- Line art engine → Line art worker: dispatches geometry
- Line art worker → Styled line builder: builds styled lines
- App coordinator → Realistic engine: builds realistic line
- Realistic engine → Realistic worker: dispatches build
- App coordinator → Brushes and papers: selects materials
- App coordinator → Artwork renderer: renders artwork
- App coordinator → Film studio: tracks draw progress
- Film studio → Artwork renderer: composes film
- Film studio → Desk scenes: selects desk scene
- App coordinator → Artwork export: exports artwork
- Artwork export → Artwork renderer: renders export
- App coordinator → Download and share: downloads or shares
- App coordinator → Paper loupe: opens loupe
- App coordinator → 3D print controls: opens print tools
- 3D print controls → 3D mesh worker: dispatches mesh work
- 3D mesh worker → Print products: builds product
- 3D mesh worker → Mesh and files: writes print files
- 3D print controls → Print timelapse: requests print preview
- App coordinator → Local persistence: persists choices
- App coordinator → Offline cache: registers offline support
- Line art engine → Local model assets: loads local models
