# Gooey Morph
URL: https://remocn.dev/docs/typography/gooey-morph

Bars fly in Tetris-style, land as a row, and melt into a word through a gooey blur-and-threshold morph

- Install: `npx shadcn@latest add @remocn/gooey-morph`
- Vibe: playful
- Natural length: 76f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/gooey-morph
```

## Usage

```tsx
// src/Root.tsx
import { Composition } from "remotion";
import { GooeyMorph } from "@/components/remocn/gooey-morph";

const GooeyMorphScene = () => (
  <GooeyMorph word="HELLO" fontFamily="'Bodoni Moda', Georgia, serif" />
);

export const RemotionRoot = () => (
  <Composition
    id="GooeyMorph"
    component={GooeyMorphScene}
    durationInFrames={120}
    fps={30}
    width={1920}
    height={1080}
  />
);
```

The melt works by blurring the alpha channel and pushing it through a
near-vertical threshold: where two shapes sit close, their blurred edges add up,
cross the threshold, and paint a solid neck between them. Everything that
should fuse lives inside the component's single filtered group — nearby
elements outside it never join the goo.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `word` | `string` | `"HELLO"` | The word the bars melt into |
| `fill` | `string` | `"#ffffff"` | Fill color of the bars and the word |
| `fontFamily` | `string` | `"sans-serif"` | Font family of the word — heavy display faces melt best |
| `fontSize` | `number` | `237` | Font size in comp pixels |
| `tracking` | `number` | `0` | Letter spacing of the word |
| `wordCenterX / wordBaselineY` | `number` | `961.4 / 601.3` | Horizontal center and baseline of the word in comp pixels |
| `width / height` | `number` | `1920 / 1080` | Coordinate space of the composition |
| `barWidth / barHeight` | `number` | `213 / 181` | Size of each bar in comp pixels |
| `barStartPositions` | `[number, number][]` | `4 scattered points` | Where each bar starts, as `[x, y]` centers |
| `barRestPositions` | `[number, number][]` | `4 points in a row` | Where each bar lands before the melt |
| `barEntryFrames` | `number[]` | `[8, 0, 4, 13]` | Per-bar entry frames — deliberately non-monotonic so the build reads as Tetris, not a wave |
| `barTravelFrames` | `number` | `30` | Length of one bar's L-shaped move: horizontal into the column, then vertical into the row |
| `morphStartFrame / morphPeakFrame / morphEndFrame` | `number` | `50 / 63 / 76` | The melt window. Blur and displacement are zero outside it |
| `blurRadius` | `number` | `6` | Peak goo blur radius |
| `blurIterations` | `number` | `6` | Box blur passes folded into the equivalent Gaussian sigma |
| `alphaInputBlack / alphaInputWhite` | `number` | `0.4588 / 0.5098` | Alpha threshold range — the narrower, the harder the goo edge |
| `displaceAmount` | `number` | `20` | Peak turbulent displacement of the goo edge, in pixels |
| `displaceSize` | `number` | `19` | Feature size of the displacement noise |
| `displaceComplexity` | `number` | `1` | Noise octaves |
| `displaceEvolutionPerSecond` | `number` | `50` | How fast the noise field pans, per second |
| `className` | `string` | — | Optional className passed to the wrapper |

Inspired by [5 Clean Text Animations](https://www.youtube.com/watch?v=Nmi7cE2wT54) by Mapal.

## Use when
- A title reveal should feel liquid and organic — shapes fuse and hand their mass to the word instead of crossfading.
- You want a two-act entrance with a built-in rhythm: a kinetic build (bars flying in off-beat) and a payoff (the melt).
- The word is short and set in a heavy display face — the goo needs solid masses to fuse.
- Everything that should fuse can live inside this one component — the morph only affects its own SVG group.

## Don't use when
- You need a plain text entrance without the shape build-up — use `soft-blur-in` or `mask-reveal-up`.
- The text is long or thin-stroked — the blur-threshold eats thin strokes and long words don't match the four-bar row.
- The style is crisp and geometric rather than liquid — use `kinetic-center-build`.