Zoom

An entrance that scales elements up into place on load or when they scroll into view.

Design
Build
Ship
"use client"

import * as React from "react"
import { Zooms } from "@animate-ui/react/primitives/effects/zoom"
import { RepeatIcon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"

import { Button } from "@/components/ui/button"

const ITEMS = ["Design", "Build", "Ship"]

export default function ZoomDemo({
  delay = 0,
  initialScale = 0.5,
  scale = 1,
}: {
  delay?: number
  initialScale?: number
  scale?: number
}) {
  const [key, setKey] = React.useState(0)

  return (
    <div className="flex flex-col items-center gap-6">
      <div key={`${key}-${delay}-${initialScale}-${scale}`} className="flex gap-3">
        <Zooms holdDelay={100} delay={delay} initialScale={initialScale} scale={scale}>
          {ITEMS.map((item) => (
            <div
              key={item}
              className="flex h-20 w-24 items-center justify-center rounded-xl bg-accent text-sm font-medium"
            >
              {item}
            </div>
          ))}
        </Zooms>
      </div>
      <Button variant="outline" size="sm" onClick={() => setKey((k) => k + 1)}>
        <HugeiconsIcon icon={RepeatIcon} strokeWidth={2} />
        Replay
      </Button>
    </div>
  )
}

Installation

npm install @animate-ui/react motion
pnpm add @animate-ui/react motion
yarn add @animate-ui/react motion
bun add @animate-ui/react motion

Usage

import { Zoom, Zooms } from '@animate-ui/react/primitives/effects/zoom';

export function Hero() {
  return (
    <>
      <Zoom>
        <h1>Animated primitives for React</h1>
      </Zoom>

      {/* Staggered: each child starts 100ms after the previous one. */}
      <Zooms holdDelay={100}>
        <Card />
        <Card />
        <Card />
      </Zooms>
    </>
  );
}

With asChild, the animation is applied to your element instead of a wrapping div.

Animation

  • The element scales from initialScale (0.5 by default) to scale on a spring (stiffness 200, damping 20), overshooting by about 2% before it settles.
  • Under reduced motion, it doesn't scale: it fades in instead.
  • inView waits for the element to scroll into view, once by default.
  • <AnimateUIProvider tempo> paces the default spring.

API Reference

Zoom

PropTypeDefault
asChild?
booleanfalse
initialScale?
number0.5
scale?
number1
delay?
number0
transition?
Transition{ type: 'spring', stiffness: 200, damping: 20 }
inView?
booleanfalse
inViewOnce?
booleantrue
inViewMargin?
string'0px'
...props?
HTMLMotionProps<'div'>-

Zooms

Wraps each child in a Zoom, delaying each one a little more than the previous.

PropTypeDefault
children
React.ReactElement | React.ReactElement[]-
holdDelay?
number0
...props?
ZoomProps-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/18/2026

On this page