10

Anticipation

Wind-up before the move.

In Disney animation, a character does not jump from standing. They crouch first. That crouch is anticipation: a short opposite move that tells the eye what is about to happen. Without it, the jump feels like a cut.

UI can borrow the same idea. Before a card pops or a control snaps into place, give it a tiny wind-up — a squash, a pull-back, a held breath — then fire the primary motion.

Replay both cards.

The left one leaps with no prep. The right one compresses for a beat, then springs. Same destination, but the second one feels physical because you saw the energy gather.

Keep it short

Anticipation only works if it is shorter than the action it introduces. A 120ms squash before a 400ms jump reads as intent. A 400ms squash before a 400ms jump reads as lag. If the wind-up is longer than the move, cut it.

Use anticipation on infrequent, deliberate actions: launching a sheet, a hero CTA that "takes off," a tile that jumps into a tray. Do not put it on every hover or every list row. Frequent interactions cannot afford ceremony.

Usage

import { motion } from "motion/react";

<motion.button
    animate={{
        y: [0, 6, -48, 0],
        scaleX: [1, 1.1, 0.94, 1],
        scaleY: [1, 0.85, 1.06, 1],
    }}
    transition={{
        duration: 0.75,
        times: [0, 0.22, 0.55, 1],
        ease: [0.65, 0, 0.35, 1],
    }}
>
    Jump
</motion.button>
@keyframes anticipate-jump {
    0% { transform: translateY(0) scale(1, 1); }
    22% { transform: translateY(6px) scale(1.1, 0.85); }
    55% { transform: translateY(-48px) scale(0.94, 1.06); }
    100% { transform: translateY(0) scale(1, 1); }
}

.jump {
    animation: anticipate-jump 750ms cubic-bezier(0.65, 0, 0.35, 1);
}

Animate transform only. The squash is just unequal scaleX / scaleY, which keeps the label readable and stays on the compositor.