# Kinetic Warp
URL: https://remocn.dev/docs/typography/kinetic-warp

A coarse mesh warp bends a whole word in staccato beats, one axis moving per keyframe

- Install: `npx shadcn@latest add @remocn/kinetic-warp`
- Vibe: playful
- Natural length: 100f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/kinetic-warp
```

## Usage

```tsx
// src/Root.tsx
import { Composition } from "remotion";
import { KineticWarp } from "@/components/remocn/kinetic-warp";

const KineticWarpScene = () => (
  <KineticWarp
    text={"REM\nOCN"}
    fontFamily="Passion One"
    fontUrl="https://fonts.googleapis.com/css2?family=Passion+One:wght@700&display=block"
  />
);

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

The component renders to a canvas, so the font must actually be loaded before the text is drawn — pass `fontUrl` for any webfont and the render is held (via `delayRender`) until it lands.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `text` | `string` | `"REM\nOCN"` | The text to warp. Split lines with `\n` |
| `textColor` | `string` | `"#FFFFFF"` | Fill color of the type |
| `fontFamily` | `string` | `"sans-serif"` | Font family drawn to the canvas |
| `fontUrl` | `string` | `""` | Stylesheet URL for the webfont. Empty string skips loading and uses a local font |
| `fontWeight` | `number` | `700` | CSS font-weight |
| `fontSize` | `number` | `107.1` | Layer-space font size, before `layerScale` |
| `leading` | `number` | `70` | Layer-space baseline-to-baseline distance, before `layerScale` |
| `tracking` | `number` | `-21` | Tracking in 1/1000 em |
| `layerScale` | `number` | `480` | Percent scale applied to the type after layout |
| `positionX` | `number` | `960` | Horizontal center of the text block in comp pixels |
| `positionY` | `number` | `540` | Vertical center of the text block in comp pixels |
| `compWidth` | `number` | `1920` | Canvas width in pixels |
| `compHeight` | `number` | `1080` | Canvas height in pixels |
| `meshRows` | `number` | `2` | Mesh cells vertically — the coarseness is the effect |
| `meshColumns` | `number` | `4` | Mesh cells horizontally |
| `colRestX` | `number` | `960` | Rest position of the moving column line |
| `colRightX` | `number` | `1255` | Column position at keyframes 2 and 3 |
| `colLeftX` | `number` | `678` | Column position at keyframes 4 and 5 |
| `rowRestY` | `number` | `540` | Rest position of the moving row line |
| `rowDownY` | `number` | `850` | Row position at keyframes 3 and 4 |
| `rowUpY` | `number` | `387` | Row position at keyframe 5 |
| `keyframeStride` | `number` | `20` | Frames between the six keyframes — motion ends at `5 * keyframeStride` |
| `easingBezier` | `[number, number, number, number]` | `[0.3, 0.74, 0.09, 1]` | Cubic bezier applied between keyframes |
| `resampleStep` | `number` | `4` | Destination pixels per resampled strip — lower is smoother and slower |
| `className` | `string` | — | Optional className passed to the wrapper |

Inspired by [How to Make Kinetic Warp Text Animation in After Effects](https://www.youtube.com/watch?v=IvTXbHLtod4) by P A N T E R.

## Use when
- A short, heavy display word needs a bold kinetic-typography moment where the whole word bends and snaps instead of individual letters animating.
- You want a rhythmic, beat-synced distortion — the mesh stops dead at every keyframe, so each pose lands like a drum hit (tune `keyframeStride` to the tempo).
- The type is a huge condensed display font filling the frame — the warp reads best when the word owns the canvas.

## Don't use when
- You need a text entrance — the word is fully visible from frame 0 and only distorts; use `tracking-in` or `soft-blur-in` for reveals.
- The text is long or small — the mesh bends quarters of the frame, so a paragraph turns to mush; use `per-character-rise` for body-size text motion.
- The vibe is corrupted or digital rather than elastic — use `rgb-glitch-text` for a glitch read.