ASCII Shader TSX
Generate animated ASCII/dither visual effects as self-contained React TypeScript components. Combines the Glyph rendering engine (9 art styles, 8 dithering algorithms, 6 FX presets) with procedural animation techniques (noise fields, particles, value fields, feedback buffers).
Modes
| Mode | Input | Output |
|---|---|---|
| Generative | None (or config props) | Procedural animated ASCII backgrounds, noise fields, matrix rain, particles |
| Source | Image / video / webcam | Real-time ASCII/dither conversion with art styles and FX |
| Hybrid | Source + generative overlays | Image with animated FX layers (CRT, glitch, noise, matrix rain) |
Stack
Single self-contained .tsx file per component. Zero external dependencies beyond React.
| Concern | Approach |
|---|---|
| Rendering | Canvas 2D API (no WebGL) |
| Animation | requestAnimationFrame |
| Responsive | ResizeObserver + devicePixelRatio |
| Accessibility | prefers-reduced-motion, aria-hidden |
| TypeScript | Strict mode, fully typed props interface |
| Brightness | BT.709 luminance with sRGB linearization LUT |
| Dithering | Error diffusion + ordered (Bayer) |
Component Contract
Every generated component follows this structure:
interface Props {
// Effect-specific (varies per component)
charset?: string
colorMode?: 'grayscale' | 'matrix' | 'amber' | 'sepia' | 'cool-blue' | 'neon' | 'custom'
speed?: number
density?: number
// Source-mode only
src?: string | HTMLImageElement | HTMLVideoElement
// Universal
className?: string
style?: React.CSSProperties
}
export function AsciiEffect({ speed = 1, ...props }: Props) {
const canvasRef = useRef<HTMLCanvasElement>(null)
const animRef = useRef<number>(0)
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext('2d')!
// ... setup, ResizeObserver, animation loop ...
return () => { cancelAnimationFrame(animRef.current); ro.disconnect() }
}, [/* deps */])
return <canvas ref={canvasRef} aria-hidden="true" className={className} style={style} />
}
Workflow
Step 1: Determine Mode
- Generative: User wants an animated background, procedural effect, or decorative element with no image input
- Source: User provides/references an image, video, or webcam feed to convert to ASCII/dither
- Hybrid: Source with animated overlays (e.g., "add CRT effect to this image")
Step 2: Read the Right References
Based on what the user wants, read the minimum set of reference files needed:
| User wants | Read these references |
|---|---|
| ASCII text backgrounds | architecture.md + rendering.md + charsets.md |
| Dithered image | rendering.md + dithering.md + image-source.md |
| Halftone / dot patterns | styles.md § Halftone |
| Matrix rain / data rain | generative.md § Matrix Rain |
| CRT / retro TV effect | effects.md § CRT |
| Noise fields / plasma | generative.md § Noise + Procedural Fields |
| Glitch effects | effects.md § Glitch |
| Particle systems | generative.md § Particles |
| Braille art | styles.md § Braille + charsets.md |
| Terminal / phosphor look | styles.md § Terminal |
| Retro duotone palette | styles.md § Retro |
| Mouse-interactive | composition.md § Mouse Interaction |
| Multi-layer compositing | composition.md § Layering |
| Webcam → ASCII | image-source.md + rendering.md |
| Image → ASCII conversion | image-source.md + rendering.md + styles.md |
| Animated background (complex) | generative.md + effects.md + composition.md |
Always read architecture.md — it has the canvas hook and component patterns every component needs.
Step 3: Build the Component
Write a single .tsx file containing:
- Props interface — typed, with sensible defaults
- Inline utilities — brightness LUT, color modes, noise, dithering (whatever the component needs, inlined from reference docs — no imports from external modules)
- Canvas hook — setup, resize, animation loop, cleanup (from
architecture.md) - Render function — the actual drawing logic
- Default export — the React component
Step 4: Creative Direction
Every component should look distinct. The references provide building blocks — combine, modify, invent.
| Dimension | Options |
|---|---|
| Character set | Standard ' .:-=+*#%@', blocks ' ░▒▓█', detailed (68 chars), minimal ' ·░█', binary ' 01', braille (64 patterns), custom themed |
| Color mode | Grayscale, matrix green, amber, sepia, cool-blue, neon (HSL cycling), fullcolor (source RGB), custom hex |
| Art style | Classic (char mapping), halftone (5 shapes), braille, dotcross, line, particles, retro (5 duotones), terminal (green phosphor) |
| Dithering | None, Floyd-Steinberg, Bayer 8×8, Atkinson, JJN, Stucki, Sierra, Sierra-Lite |
| FX | None, noise (simplex 3D), intervals, beam, glitch, CRT (scanlines+phosphor+bloom), matrix rain |
| Animation | Static, slow drift, wavy, pulsing, flowing, reactive |
| Density | xs (8px), sm (10px), md (16px), lg (20px), xl (24px) |
References
| File | Contents |
|---|---|
references/architecture.md | Canvas hook, component template, ResizeObserver, cleanup, a11y, devicePixelRatio, performance |
references/rendering.md | BT.709 brightness, sRGB LUT, adjustBrightness, 8 color modes (implementations), char mapping, vignette, edge detection |
references/dithering.md | 8 algorithms: error diffusion framework, FS/Atkinson/JJN/Stucki/Sierra kernels, Bayer 8×8 ordered |
references/styles.md | 9 art style renderers: classic, halftone (5 shapes), braille (3 variants), dotcross, line, particles, retro (5 duotones), terminal, claude |
references/generative.md | Simplex noise 2D/3D, fBm, procedural value fields (plasma, rings, spiral, vortex, tunnel, sine fields), HSV color, particles, matrix rain |
references/effects.md | Pre-render FX (noise, intervals, beam, glitch with direction system), post-render FX (CRT, matrix rain), bloom, vignette, scanlines, grain, chromatic aberration, border glow |
references/charsets.md | All character sets (10 standard + 3 braille + 5 terminal), palette libraries from ascii-video, custom charset creation |
references/composition.md | Multi-layer compositing, canvas blend modes, masking, mouse interaction (attract/push), feedback buffer, BG dither, inverse dither |
references/image-source.md | Image/video/webcam loading, sampler canvas, grid downsampling, real-time processing loop |
Critical Patterns
Canvas Hook (Required in Every Component)
See references/architecture.md for the full pattern. Key points:
- Use
ResizeObserverfor responsive sizing - Handle
devicePixelRatiofor sharp rendering on HiDPI - Check
prefers-reduced-motionand render a single frame if true - Always clean up RAF and observer on unmount
- Use
willReadFrequently: trueon sampler canvas (source mode),falseon display canvas
BT.709 Brightness (From Glyph Engine)
Always use perceptually accurate brightness calculation. See references/rendering.md for the full implementation. The sRGB-to-linear LUT is critical for performance — pre-compute at module level.
Performance Guidelines
- Use
Float32Arrayfor brightness/value grids — not regular arrays - Pre-compute the sRGB linearization LUT (256 entries) at module scope
- For source mode: use a separate sampler canvas sized to grid resolution
- Cap grid dimensions:
cols = Math.floor(width / cellWidth), never more than ~400 cols - Minimize per-cell string allocations — use indexed char lookups
- For generative mode: vectorize math operations where possible
- Use
globalCompositeOperationfor blending instead of manual pixel math
Output Checklist
Before generating a component, verify:
- Single
.tsxfile, zero imports b