Theme Flip
A cursor clicks a theme toggle in a product window and the whole UI floods from light to dark.
$ pnpm dlx shadcn@latest add @remocn/theme-flipUsage
// 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
| Prop | Type | Default |
|---|---|---|
| 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.
Default
true - showCursorboolean
Show the cursor that clicks the toggle.
Default
true - reverseboolean
Click again after a hold and flip back to the first theme.
Default
false - screenshotWidthnumber
Natural width of the screenshot in pixels.
Default
MOCK_W - screenshotHeightnumber
Natural height of the screenshot in pixels.
Default
MOCK_H - accentstring
Accent color of the mock UI.
Default
"#3B5BFD" - speednumber
Playback speed multiplier for the whole timeline.
Default
1 - zoomnumber
Camera zoom on the toggle around the click. 1 means no push-in.
Default
ZOOM - groundGshPresetId
Shader preset id for the animated background.
- groundParamsPartial<GradientParams>
Partial shader parameters that override the ground preset.