19 interactive canvas-based media art pieces where creatures and forces disturb flowing text. Built with @chenglou/pretext for high-performance text layout on Canvas 2D.
Move your mouse to control each creature/force and watch the text react.
| # | Path | Concept |
|---|---|---|
| 1 | / |
Dragon — A pixel-art dragon slithers across text, pushing characters aside |
| 2 | /effects/blackhole/ |
Black Hole — Gravitational lensing warps text, with accretion disk and Hawking radiation |
| 3 | /effects/pacman/ |
Pac-Man — Pac-Man eats characters; eaten letters become ghosts that follow |
| 4 | /effects/alien/ |
Alien — A tentacle creature with FABRIK IK reaches for and grabs text |
| 5 | /effects/cat/ |
Cat — A cute cat scratches at text; letters tear apart and scatter |
| 6 | /effects/fire/ |
Fire — Cursor is a torch; text ignites, burns to ash, and regenerates |
| 7 | /effects/rain/ |
Rain — Characters fall like rain; cursor umbrella deflects them; ripples on impact |
| 8 | /effects/magnet/ |
Magnet — Cursor is N/S magnet; click to flip polarity; chars attract or repel |
| 9 | /effects/vine/ |
Vine — Vines grow from cursor, tendrils wrap text, flowers bloom when idle |
| 10 | /effects/freeze/ |
Freeze — Cursor radiates cold; text crystallizes with frost; click to shatter |
| 11 | /effects/music/ |
Music — Characters play pentatonic tones via Web Audio; visual note stems and waveforms |
| 12 | /effects/gravity/ |
Gravity — 3 planet clusters orbit; cursor disrupts with tidal forces |
| 13 | /effects/typewriter/ |
Typewriter — Text types itself onto sepia paper; cursor erases with correction tape |
| 14 | /effects/constellation/ |
Constellation — Stars twinkle; cursor connects them into constellations; click to lock |
| 15 | /effects/wind/ |
Wind — Mouse movement creates wind; text sways like grass; dandelion seeds drift |
| 16 | /effects/glitch/ |
Glitch — RGB split, pixel sorting, VHS tracking, CRT scanlines near cursor |
| 17 | /effects/kingkong/ |
King Kong — Giant ape climbs through text |
| 18 | /effects/lightning/ |
Lightning — Bolts strike randomly and from cursor; hit letters burn and fall |
| 19 | /effects/sakura/ |
Sakura — Cherry blossom petals swirl in the wind; cursor makes text bloom pink and scatter petals |
# 1. Clone the repo
git clone https://github.com/khj68/pretext-example.git
cd pretext-example
# 2. Install dependencies
npm install
# 3. Start the dev server
npx vite
# 4. Open in your browser
# http://localhost:5173/ → Dragon (main)
# http://localhost:5173/effects/fire/ → Fire
# http://localhost:5173/effects/blackhole/ → Black Hole
# ... (see effects/ directory for all)Requirements: Node.js 18+ and npm
All five pieces share the same core pattern:
@chenglou/pretext measures and lays out text entirely on the GPU-side Canvas — no DOM reflow, no layout thrashing. Each character becomes an independent physics object.
import { prepareWithSegments, layoutWithLines } from '@chenglou/pretext'
const prepared = prepareWithSegments(text, '15px Georgia')
const { lines } = layoutWithLines(prepared, maxWidth, lineHeight)
// Each character gets its own position, velocity, and spring-back force
for (const line of lines) {
for (const ch of line.text) {
chars.push({ char: ch, baseX: x, baseY, x, y, vx: 0, vy: 0 })
x += ctx.measureText(ch).width
}
}Each piece has a different entity that follows the cursor — a dragon spine, a black hole center, Pac-Man, an alien body, or a cat.
Nearby characters are displaced by forces (push, gravity, scratch), then spring back to their original positions with damping:
// Displacement force
char.vx += Math.cos(angle) * force
// Spring restoration + damping
char.vx += (char.baseX - char.x) * 0.06
char.vx *= 0.88
char.x += char.vx- IK Spine Chain — 110-joint chain where each joint maintains fixed spacing from the previous one
- Sinusoidal Slithering — sine wave applied perpendicular to the spine for snake-like motion
- Body Width Profile — segment-by-segment thickness (neck → shoulder → torso → tail taper)
- Pixel Art Rendering — grayscale shading from center (bright) to edge (dark)
- Gravitational Lensing — stars shift tangentially near the event horizon; brightness amplifies (Einstein ring)
- Spaghettification — characters stretch along the radial axis toward the black hole
- Accretion Disk — orbiting particles with 3D tilt, Doppler brightness boost, and trail effects
- Frame Dragging — tangential force simulating Kerr black hole rotation
- Hawking Radiation — particles emitted from the event horizon boundary
- Directional Mouth — per-pixel angle check against movement direction for mouth cutout
- Character → Ghost Transition — eaten chars get pulled into Pac-Man's mouth, then spawn as classic ghosts
- Ghost FIFO Cap — max 4 ghosts; oldest removed when exceeded
- Swarm AI — ghosts orbit Pac-Man with index-based phase offsets and mutual repulsion
- FABRIK IK — Forward And Backward Reaching Inverse Kinematics for 10 tentacles × 20 segments
- Target Seeking — tentacle tips search for nearby characters using random sampling + angle filtering
- Bioluminescent Body — pulsating organic shape with independently glowing patches
- AABB Culling — bounding box optimization to skip distant characters (critical for 10 tentacles)
- 3-Phase Scratch — butt wiggle (wind-up) → arcing slash with visible claws → return
- Text Tearing — scratched characters render as two offset copies, creating a torn-apart look
- Claw Marks — 3-line scratch marks persist and fade on the canvas
- Cute Face — :3 mouth (dual quadratic curves), double eye highlights, blush circles
- 3-Stage Burn Lifecycle — normal → burning → ash → regenerating → normal
- Blazing Cursor — 6-layer fire system (heat haze, trail, flames, sparks, core, flame tongues)
- Fire Spread — burning chars ignite neighbors probabilistically
- Ash Physics — burned chars drift upward with rotation; regenerate with golden glow
- Falling Characters — gravity + terminal velocity, settling into text positions
- Umbrella Cursor — semicircle canopy with handle, tilts based on mouse velocity
- Ripple System — expanding circles on impact, pushing nearby settled chars upward
- Wet Effect — recently impacted chars glow blue, fading over time
- Coulomb Force — inverse-square attraction/repulsion based on char polarity
- Polarity Toggle — click to flip N/S; stuck chars explosively release
- Field Lines — 24 bezier curves emanating from horseshoe magnet cursor
- Sticky Threshold — opposite-polarity chars lock into vibrating orbit
- Bezier Spine Growth — vine follows mouse path with tapering thickness
- Tendril Branching — curved offshoots seek and wrap nearby characters
- Bloom Animation — 5-petal flowers appear when mouse idles; leaves flutter down
- Withering Cycle — old vines brown and fade, releasing wrapped characters
- Progressive Crystallization — chars transition from sepia to ice blue
- Hexagonal Frost — crystal particles form around freezing characters
- Click Shatter — radial pulse resets frozen chars with sparkle particles
- Frost Propagation — frozen chars spread cold to neighbors
- Web Audio Synthesis — sine tones on pentatonic scale mapped to char Y position
- Note Visualization — stems, flags, and colored glow per activated character
- Conductor Baton Cursor — rotates based on mouse direction
- Waveform Display — oscilloscope near cursor from recent audio
- N-Body Simulation — 3 planet clusters with elliptical orbits
- Tidal Disruption — cursor rips chars from clusters when gravity exceeds threshold
- Orbital Trails — fading paths showing planet trajectories
- Lagrange Points — glowing L1 indicators between planet pairs
- Auto-Typing — chars reveal sequentially with impact bounce and ink splatter
- Correction Tape — cursor erases nearby typed chars; they re-type on leave
- Paper Texture — sepia paper rectangle with grain dots on dark desk background
- Ink Ribbon Aging — fresh chars crisp, older chars fade to light sepia
- Star Twinkling — oscillating alpha with random phase offsets and brightness classes
- Proximity Lines — chars near cursor and each other connect with fading white lines
- Click Lock — current constellation captured in gold, fading over 3 seconds
- Nebula + Milky Way — atmospheric background gradients
- Mouse-Driven Wind — cursor velocity becomes wind vector field
- Grass Sway — chars lean with skew transform; lower chars sway more
- Uprooting — strong wind tears chars loose; they tumble with rotation
- Dandelion Seeds — uprooted chars spawn fluffy drifting seed particles
- RGB Channel Split — additive blending of offset red/green/blue passes
- Pixel Sorting — row chars near cursor sort by char code, creating streaks
- VHS Tracking — random horizontal bands shift sections of text
- CRT Effects — scanlines, barrel distortion, static noise, full-screen flash
├── index.html # Dragon — main entry (/)
├── main.js # Dragon logic
├── effects/ # Each effect in its own directory
│ └── {name}/
│ ├── index.html # Effect page
│ └── {name}.js # Effect logic
├── docs/ # Design docs & highlights
│ ├── IDEAS.md
│ ├── dragon.md
│ └── ...
├── vite.config.js # Multi-page build (auto-discovers effects/)
└── package.json # Dependencies (pretext + vite)
- @chenglou/pretext — Zero-DOM text measurement & layout
- Canvas 2D — All rendering (no WebGL)
- Vite — Dev server & bundler
MIT