Smoke-like fluid dynamics drive real text layout on Canvas 2D.
Report a Bug · Request a Feature
- Fluid Simulation — Multi-frequency trigonometric velocity field with semi-Lagrangian advection, diffusion, and emitter-based density injection
- ASCII Smoke Rendering — Smoke density mapped to a brightness-sorted character palette for organic, typographic vapor
- Fluid-Aware Text Layout — Body text flows dynamically around high-density smoke regions using real-time obstacle carving
- Interactive — Move your mouse to inject smoke; click to send shockwaves through the field
- Touch Support — Full touch event handling for mobile/tablet interaction
- Zero Dependencies for Rendering — Pure Canvas 2D, no WebGL, no external rendering libraries
- Type-Safe — Full TypeScript with strict mode
| State | Preview |
|---|---|
| Normal | ![]() |
| After Click (Shockwave) | ![]() |
| Category | Technology |
|---|---|
| Language | TypeScript 5.6+ |
| Build Tool | Vite 6 |
| Rendering | Canvas 2D API |
| Text Layout | @chenglou/pretext |
| Fonts | Inter, Playfair Display, Georgia (Google Fonts) |
- Node.js 18+ and npm
- A modern browser with Canvas 2D support
# Clone the repository
git clone https://github.com/Poojan38380/aether.git
cd aether
# Install dependencies
npm install# Start the dev server (with hot reload)
npm run devOpen http://localhost:5173 in your browser.
# Type-check and build for production
npm run build
# Preview the production build locally
npm run previewThe output is written to dist/.
aether/
├── public/
│ ├── favicon.svg # SVG favicon
│ ├── after-click.png # Screenshot: shockwave state
│ └── home-page-normal-state.png # Screenshot: default state
├── src/
│ ├── main.ts # Entry point — canvas setup, input handling, render loop
│ ├── fluid.ts # Fluid simulation (advection, diffusion, emission, shockwaves)
│ ├── obstacles.ts # Obstacle carving — convert density → blocked intervals
│ └── palette.ts # Character palette building — brightness measurement & matching
├── index.html # HTML shell + loading screen styles
├── package.json
├── tsconfig.json
└── vite.config.ts
- Fluid Simulation (
fluid.ts) — A grid-based velocity field advects density using semi-Lagrangian tracing. Four orbiting emitters inject density. Mouse clicks create shockwave rings. - Character Palette (
palette.ts) — At startup, every character in the charset is measured for width (via pretext) and brightness (via offscreen canvas pixel scan). Entries are sorted by brightness for fast lookup. - Smoke Rendering (
main.ts::drawSmokeAscii) — Each frame, the density grid is sampled. For each cell, the best-matching character is selected by brightness and width, then drawn on the canvas. - Text Layout (
main.ts::drawTextAroundSmoke) — Body text is laid out line-by-line using pretext. For each line row, high-density columns become blocked intervals. Available slots are carved, and text is placed in the widest slot.
| Metric | Target |
|---|---|
| Grid Size | Up to 250 × 100 cells |
| Frame Rate | 60 FPS on modern desktop |
| Palette Size | ~200 entries (3 weights × 2 styles × ~35 chars) |
| Startup Time | < 2s (includes font loading + palette measurement) |
| Bundle Size | < 50 KB gzipped (excluding fonts) |
- Core fluid simulation (advection, diffusion, emission)
- ASCII smoke rendering with brightness-matched palette
- Fluid-aware text layout with obstacle carving
- Mouse interaction (smoke injection + shockwaves)
- Touch support
- FPS counter + grid stats overlay
- Responsive canvas with DPR scaling
- Graceful resize handling (density preservation)
- Draggable obstacles that text flows around
- Configurable text content and font families
- Color theme presets
- Performance scaling for mobile (adaptive grid)
- Export/share fluid states
Contributions are welcome! Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
This project is licensed under the MIT License — see the LICENSE file for details.
- @chenglou/pretext — Instant, DOM-free text measurement and layout
- Google Fonts — Inter, Playfair Display, Georgia
- The creative coding and generative art community for inspiring fluid typography experiments
- Author: Poojan Goyani
- Buy Me a Coffee: ☕ buymeacoffee.com/poojan38380
⭐ If you find this project interesting, consider giving it a star! It helps others discover it and motivates further development.

