Theme Flip

A cursor clicks a theme toggle in a product window and the whole UI floods from light to dark.

Installation
$ pnpm dlx shadcn@latest add @remocn/theme-flip

Usage

tsx
// src/Root.tsx
import { Composition } from "remotion";
import { ThemeFlip } from "@/components/remocn/theme-flip";
 
const ThemeFlipScene = () => (
  <ThemeFlip
    fromSrc="/screens/light.png"
    toSrc="/screens/dark.png"
    origin={{ x: 1340, y: 33 }}
  />
);
 
export const RemotionRoot = () => (
  <Composition
    id="ThemeFlip"
    component={ThemeFlipScene}
    durationInFrames={112}
    fps={30}
    width={1280}
    height={720}
  />
);

The camera pushes in on a theme toggle, a cursor clicks it, and the new theme floods out from the click point across the window before the camera pulls back. With reverse it clicks again and flips back. Use the built-in mock, or pass from and to nodes, or fromSrc and toSrc images, with an origin in screenshot pixels. It has two looks built in, set by startTheme.

The ground is a live gradients.sh shader (GshGround), installed with the component as @remocn/gsh. Pick another look with the ground preset prop.

Props16

PropTypeDefault
from
React.ReactNode—

Custom starting UI as a React node.

to
React.ReactNode—

Custom final UI as a React node.

fromSrc
string—

Starting screenshot URL.

toSrc
string—

Final screenshot URL.

startTheme
"light" | "dark""light"

Theme the built-in mock starts in.

origin
{ x: number; y: number }—

Click point and flood center in screenshot pixels.

showToggle
booleantrue

Draw a floating toggle at origin over custom content.

showCursor
booleantrue

Show the cursor that clicks the toggle.

reverse
booleanfalse

Click again after a hold and flip back to the first theme.

screenshotWidth
numberMOCK_W

Natural width of the screenshot in pixels.

screenshotHeight
numberMOCK_H

Natural height of the screenshot in pixels.

accent
string"#3B5BFD"

Accent color of the mock UI.

speed
number1

Playback speed multiplier for the whole timeline.

zoom
numberZOOM

Camera zoom on the toggle around the click. 1 means no push-in.

ground
GshPresetId—

Shader preset id for the animated background.

groundParams
Partial<GradientParams>—

Partial shader parameters that override the ground preset.

  • fromReact.ReactNode

    Custom starting UI as a React node.

  • toReact.ReactNode

    Custom final UI as a React node.

  • fromSrcstring

    Starting screenshot URL.

  • toSrcstring

    Final screenshot URL.

  • startTheme"light" | "dark"

    Theme the built-in mock starts in.

    Default"light"

  • origin{ x: number; y: number }

    Click point and flood center in screenshot pixels.

  • showToggleboolean

    Draw a floating toggle at origin over custom content.

    Defaulttrue

  • showCursorboolean

    Show the cursor that clicks the toggle.

    Defaulttrue

  • reverseboolean

    Click again after a hold and flip back to the first theme.

    Defaultfalse

  • screenshotWidthnumber

    Natural width of the screenshot in pixels.

    DefaultMOCK_W

  • screenshotHeightnumber

    Natural height of the screenshot in pixels.

    DefaultMOCK_H

  • accentstring

    Accent color of the mock UI.

    Default"#3B5BFD"

  • speednumber

    Playback speed multiplier for the whole timeline.

    Default1

  • zoomnumber

    Camera zoom on the toggle around the click. 1 means no push-in.

    DefaultZOOM

  • groundGshPresetId

    Shader preset id for the animated background.

  • groundParamsPartial<GradientParams>

    Partial shader parameters that override the ground preset.