Morphing Modal

A bento card lifts off the grid and blooms into a full-screen modal driven by a single heavy spring

Installation

$ pnpm dlx shadcn@latest add @remocn/morphing-modal

Usage

// src/Root.tsx
import { Composition } from "remotion";
import { MorphingModal } from "@/components/remocn/morphing-modal";

const MorphingModalScene = () => (
  <MorphingModal
    from={{ left: 460, top: 260, width: 360, height: 200 }}
    to={{ left: 80, top: 60, width: 1120, height: 600 }}
    morphAt={30}
  />
);

export const RemotionRoot = () => (
  <Composition
    id="MorphingModal"
    component={MorphingModalScene}
    durationInFrames={180}
    fps={30}
    width={1280}
    height={720}
  />
);

Props

PropTypeDefaultDescription
from
{ top, left, width, height }Source rect of the card before it blooms
to
{ top, left, width, height }Target rect of the modal. Defaults to a near-fullscreen sheet.
borderRadiusFrom
number24Border radius of the source card in pixels
borderRadiusTo
number0Border radius of the modal in pixels
morphAt
number30Frame at which the morph spring fires
background
string"#050505"Page background color
cardColor
string"#0a0a0a"Card / modal surface color
textColor
string"#fafafa"Heading color in source and modal
mutedColor
string"#71717a"Body copy color
sourceTitle
string"Compose video"Heading shown on the source card
sourceBody
string"Click to start a new project"Body copy shown on the source card
modalTitle
string"New project"Heading shown after the morph completes
modalBody
stringBody copy shown after the morph completes
source
ReactNodeOverride the default source card content
modal
ReactNodeOverride the default modal content
speed
number1Playback speed multiplier
className
stringOptional className passed to the root container