# Dissolve text

Text that dissolves in through Bayer thresholds by character, word or line, in any order, settling solid or into a dithered texture, and can dissolve back out.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. The dithercn agent skill, for building any dither on the engine, is at [/.well-known/agent-skills/dithercn/SKILL.md](/.well-known/agent-skills/dithercn/SKILL.md).

<ComponentPreview src="examples/dissolve-text-demo.tsx" size="lg" controls="dissolveControls">
  <DissolveTextDemo />
</ComponentPreview>

## Installation [#installation]

<InstallBlock name="dissolve-text" />

## Usage [#usage]

```tsx
import { DissolveText } from "@/components/dithercn/dissolve-text";

export function Headline() {
  return (
    <DissolveText as="h2" accent="blue" className="text-6xl font-semibold">
      Arrives one dot at a time
    </DissolveText>
  );
}
```

Each character is masked by a 4×4 Bayer matrix that fills in level by level, from no dots to solid, so the letters build up out of the dither. By default it plays once when the text scrolls into view, one character after another. Use the replay button on the preview to see it again.

`direction` sets the order: `start` (reading order), `end`, `center` (from the middle out), `edges` (from both ends in) or `random`, a shuffle that is the same on every visit. `accent` gives each unit a colour while it arrives, fading to the text colour over twice the `duration`.

`fill` sets what the letters settle into. `solid` ends as plain text. `gradient` stops at a dither level (`level`, 0.625 by default). `dotted` and `hatched` end in the style kit's textures, which suit large, heavy type.

## Examples [#examples]

### Hatched poster type [#hatched-poster-type]

`fill="hatched"` and `direction="center"` on a heavy display face, with the line below following from the middle out.

<ComponentPreview src="examples/dissolve-text-hatched.tsx" size="lg">
  <DissolveTextHatched />
</ComponentPreview>

### Word by word [#word-by-word]

`by="word"` reveals whole words, which reads better for a paragraph. An 8×8 matrix with 2px cells gives a finer grain at body sizes, and the heading arrives in green.

<ComponentPreview src="examples/dissolve-text-words.tsx">
  <DissolveTextWords />
</ComponentPreview>

### Dissolving out and in [#dissolving-out-and-in]

Set `show={false}` and the text dissolves back out. Here a timer hides the word, swaps it, and shows the next one in a random order. Each letter arrives white and settles into the ink colour.

<ComponentPreview src="examples/dissolve-text-cycle.tsx">
  <DissolveTextCycle />
</ComponentPreview>

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` (required) | `string` |  | The text. |
| `as` | `"h1" \| "h2" \| "h3" \| "h4" \| "p" \| "span" \| "div"` | `"span"` | The element to render. |
| `by` | `"char" \| "word" \| "line"` | `"char"` | Dissolve each character, each word, or the whole text at once. |
| `direction` | `"start" \| "end" \| "center" \| "edges" \| "random"` | `"start"` | The order units dissolve in. |
| `trigger` | `"mount" \| "in-view"` | `"in-view"` | Play when mounted, or when the text first scrolls into view. |
| `show` | `boolean` | `true` | false dissolves the text out. true brings it back. |
| `color` | `DitherColor` | `the text colour` | Text colour: a palette name or any CSS colour. |
| `accent` | `DitherColor \| "none"` | `"none"` | Colour each unit has while it arrives, fading to the text colour. |
| `fill` | `"solid" \| "gradient" \| "dotted" \| "hatched"` | `"solid"` | What the letters settle into. |
| `level` | `number` | `0.625` | Gradient only: the coverage the letters settle at, 0 to 1. |
| `duration` | `number` | `600` | Milliseconds for one character, word or line. |
| `stagger` | `number` | `28 per character, 90 per word` | Milliseconds between one unit and the next. |
| `delay` | `number` | `0` | Milliseconds before the first unit starts. |
| `speed` | `number` | `1` | Multiplies every timing. 2 plays twice as fast. |
| `matrix` | `"bayer2" \| "bayer4" \| "bayer8"` | `"bayer4"` | The threshold pattern the letters fill in through. |
| `cell` | `number` | `--dither-cell` | Size of one dither cell in CSS pixels. |

## Notes [#notes]

* The text stays real text, one inline element per character or word, so it can be selected, copied and indexed. While it is dissolved out, it is hidden from assistive technology.
* The animation is plain CSS keyframes that step a `mask-image` through the matrix's levels with an ease-out timing. A text that plays on mount needs no JavaScript to run.
* With reduced motion turned on, the text appears and disappears instantly. A textured `fill` still applies.
* Text waiting for `in-view` stays hidden until it scrolls into view. Without JavaScript it is shown as normal text.