# Illustrated Manuscript An interactive illuminated manuscript page featuring an animated dragon that follows your cursor, breathes fire on click, and causes text to flow around it in real-time. **[→ Live Demo](https://illustrated-manuscript.vercel.app/)** ## Overview This project renders a medieval manuscript page on Canvas, featuring a hand-painted dragon made of sprite segments. The dragon tracks the mouse cursor with chain-physics (20 body segments with angle constraints), and clicking makes it breathe fire. Text reflows around the dragon body and fire particles each frame using [Pretext](https://github.com/chenglou/pretext)'s `layoutNextLine` API — no DOM measurements, no CSS reflow. ### Features - **Real-time text exclusion** — text wraps around arbitrary moving shapes (dragon body + fire particles), re-laid out every frame via Pretext - **Chain-physics dragon** — 20-segment inverse-kinematics body, hand-painted sprites, wing flapping, idle rest pose - **Fire-breathing** — click to spawn particle bursts from the dragon's mouth; particles push and distort nearby text characters - **Illuminated drop cap** — hand-drawn initial letter in manuscript tradition - **Medieval aesthetic** — IM Fell English font, parchment tones, hand-painted sprites throughout ## Tech Stack - **[Pretext](https://github.com/chenglou/pretext)** — Pure JS/TS text measurement & layout engine by [Cheng Lou](https://x.com/_chenglou). Enables laying out text without DOM reflow, line by line with variable widths - **WebGL2 + 2D Canvas** — offscreen 2D Canvas compositing, uploaded to WebGL2 texture for display - **Vite** — build tool ## Project Structure ``` src/ config.js — constants, responsive layout calculations dragon.js — dragon physics, sprite rendering, fire particle system story.js — manuscript story text main.js — entry point: WebGL pipeline, input, text layout, render loop public/ dragon-sprites/ — 23 hand-painted dragon body part PNGs fire-sprites/ — 10 fire particle PNGs img/dropcap.png — illuminated drop cap (IM Fell English loaded via Google Fonts) ``` ## Getting Started ```bash npm install npm run dev ``` Open in browser. Desktop recommended — mobile support is limited. ## How It Works 1. **Text preparation**: story text is segmented and measured once via `prepareWithSegments()` 2. **Each frame**: dragon segments and fire particles generate exclusion rectangles 3. **Text layout**: for each line, available width ranges are computed by subtracting exclusion zones, then `layoutNextLine()` fills each range 4. **Fire text effect**: characters near fire particles are displaced, rotated, and color-shifted based on proximity 5. **Rendering**: everything composites on an offscreen 2D Canvas, then uploads to a WebGL2 fullscreen quad ## Credits Created by [River Marchand (@Riyvir)](https://x.com/Riyvir), Creative Director at [Neither/Nor](https://neithernor.studio/). Built with [Pretext](https://github.com/chenglou/pretext) by [Cheng Lou](https://x.com/_chenglou) — a pure JavaScript/TypeScript library for multiline text measurement & layout, enabling web UIs to bypass DOM measurements and reflow entirely. > *"This little illuminated dragon is very happy about Pretext."* — [@Riyvir](https://x.com/Riyvir/status/2038093450139279426) ## License ISC