# Paper Wobble
URL: https://remocn.dev/docs/effects/paper-wobble

Per-pose reshoot jitter that makes any content feel hand-placed on a desk

- Install: `npx shadcn@latest add @remocn/paper-wobble`
- Vibe: paper
- Natural length: 90f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/paper-wobble
```

## Usage

Wrap anything. The wrapper holds one offset for a whole stop-motion pose, then
snaps to the next — the wobble of a photo that was picked up and put back down.

```tsx
// src/Root.tsx
import { AbsoluteFill, Composition } from "remotion";
import { PaperWobble } from "@/components/remocn/paper-wobble";

const PaperWobbleScene = () => (
  <AbsoluteFill
    style={{
      background: "#f1eee7",
      alignItems: "center",
      justifyContent: "center",
      flexDirection: "column",
      gap: 40,
    }}
  >
    <PaperWobble seed="title">
      <h1 style={{ fontSize: 64, color: "#26242c" }}>Shot on a desk</h1>
    </PaperWobble>
    <PaperWobble seed="card">
      <YourCard />
    </PaperWobble>
  </AbsoluteFill>
);

export const RemotionRoot = () => (
  <Composition
    id="PaperWobble"
    component={PaperWobbleScene}
    durationInFrames={90}
    fps={30}
    width={1280}
    height={720}
  />
);
```

Give each wrapped block its own `seed` — two instances sharing a seed move in
lockstep, which reads as one rigid sheet rather than two objects on a desk.

Components that already carry their own jitter, like `paper-sticker`, do not
need this wrapper — doubling it up just doubles the shake.

The wrapper is `display: inline-block` and nothing else: no size, no
background, no positioning. If you pass a `transform` through `style`, it is
applied first and the jitter is appended, so your own positioning survives.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `children` (required) | `React.ReactNode` | — | The content to wobble |
| `seed` | `string` | `"wobble"` | Seed for the jitter — same seed, same motion |
| `amp` | `number` | `1.4` | Maximum offset in pixels on each axis |
| `rotAmp` | `number` | `0.35` | Maximum rotation in degrees |
| `step` | `number` | `3` | Frames per stop-motion pose — the tempo control |
| `className` | `string` | — | Passed through to the wrapper div |
| `style` | `React.CSSProperties` | — | Merged over the defaults; a transform here is composed before the jitter |

## Use when
- Any block should carry the stop-motion reshoot wobble — headlines, cards, or content that must feel hand-placed rather than laid out.
- Two or more elements should read as separate objects on a desk: give each its own `seed`.

## Don't use when
- The content should sit rock-still — UI simulations, code blocks being read.
- You want smooth floating motion rather than discrete poses — use `drift`.
- The component already jitters itself, like `paper-sticker`; wrapping it just doubles the shake.