npm.io
0.3.0 • Published 3d ago

@dotmatter/react

Licence
MIT
Version
0.3.0
Deps
2
Size
32 kB
Vulns
0
Weekly
0

dotmatter

Turn any image or video into an interactive field of physical particles.

Ten effects — Particles, Dither, Halftone, ASCII, LED, Stitch, Scanline, Mosaic, Rings, Contour — all running on one shared WebGL2 particle simulation. Every dot, glyph, and cell is an independently simulated object with a home position, velocity, and spring: the cursor physically pushes them aside, they carry momentum, and they bounce back with a liquid overshoot.

Inspired by the interactive shader components popularized by Figma and Framer.

Live playground: dotmatter.treshnanda.tech

Using an AI coding agent? Point it at dotmatter.treshnanda.tech/llms.txt — a complete, standalone reference for the entire API written for LLMs (also at llms.txt in this repo).

Quick start

Install with your package manager of choice — @dotmatter/react pulls in the engine and effects automatically:

npm install @dotmatter/react
# or
pnpm add @dotmatter/react
# or
yarn add @dotmatter/react
# or
bun add @dotmatter/react
import { DotMatter } from "@dotmatter/react"
import { particleEffect } from "@dotmatter/shaders"

<DotMatter
  src="/portrait.jpg"
  effect={particleEffect}
  preset="soft-repel"
  alt="Portrait"
/>

That's it. The component renders an accessible <img> fallback, streams the image to the GPU, and animates the particle field at 60fps. Move the cursor across it.

Effects

Effect Import Look
Particles particleEffect Soft dots sized by luminance
Dither ditherEffect Ordered Bayer tiles, 1-bit editorial texture
Halftone halftoneEffect Print-style dots, tone as radius
ASCII asciiEffect Glyph ramp picked by brightness
LED ledEffect Glowing matrix pixels
Stitch stitchEffect Cross-stitch X marks
Scanline scanlineEffect Bar segments, CRT feel

Features

  • Real physics, not a warp. Cursor push with configurable force/radius, spring return with a slight overshoot bounce, momentum, damping.
  • Ambient motion. wave, breathe, flow, jitter — time-based forces composed with cursor interaction:
    <DotMatter ambient={{ mode: "wave", strength: 0.6, speed: 1, scale: 1.4 }} ... />
  • Universal color system. Every effect supports colorMode: 0 (source image colors) or 1 (custom tint); dither adds a two-tone ink palette.
  • Image adjustments. hue, saturation, exposure, contrast uniforms on every effect — they drive both color and the luminance-based geometry.
  • Transparency-aware. Transparent PNG regions allocate no particles — a logo becomes its own interactive silhouette.
  • Video sources. <DotMatter src="/clip.mp4" video ... /> streams frames straight to the GPU.
  • Any aspect ratio, responsive, SSR-safe. Static <img> fallback when WebGL2 is unavailable.

Custom effects

Effects are data — shaders plus typed uniforms on the shared physics:

import { defineEffect } from "@dotmatter/core"

export const myEffect = defineEffect({
  id: "my-effect",
  geometry: { type: "particles" },
  source: { vertex, fragment },
  uniforms: { /* typed, validated, presetable */ },
  presets: { default: { /* ... */ } },
})

Scroll reveal & particle text

// Particles assemble into place as the element scrolls into view
<DotMatter src={img} effect={particleEffect} scrollReveal="auto" alt="…" />

// Headlines as interactive particle fields (accessible text stays in the DOM)
import { DotMatterText } from "@dotmatter/react"
<DotMatterText text="HELLO" effect={particleEffect} />

prefers-reduced-motion is respected automatically, and rendering pauses when the element is offscreen or the tab is hidden.

Development

This repo uses pnpm workspaces (contributors need pnpm):

pnpm install
pnpm test        # full test suite
pnpm dev         # playground at localhost:5173
pnpm build

License

MIT Treshnanda

Keywords