Flash
Full-frame flash with a near-instant attack and an exponential decay, fired at `delay`.
Installation
npx shadcn add https://www.reelcn.dev/r/flash.jsonFiles land in src/reelcn/ with the items it builds on. Dependencies: remotion.
Usage
<Flash delay={24} strength={0.8} />Props
PropTypeDescription
delaynumberFrames to wait before entering.
durationnumberEnter duration in frames. Defaults to 0.6s. Some items reuse
duration for an unrelated local timing. See that item's own prop docs.exitnumber | booleanExit at the end of the parent `<Sequence>`.
false keeps it on screen, a number sets the exit length in frames.motionMotionPersonalityOverride the theme's motion personality.
posterbooleanRenders fully entered, with no exit: for a still frame or thumbnail. Defaults to
false.holdFramesnumberDelays the start of the exit window by this many frames, for a minimum on-screen hold. Defaults to
0.colorstringFlash color. Defaults to the theme foreground.
strengthnumberPeak opacity, 0-1. Default
0.9.attacknumberFrames from
delay to full strength. Default 2.blendModeMixBlendModeHow the flash blends with the frame below, e.g.
screen to brighten rather than cover. Default "normal".decayFramesnumberFrames from the peak until about 1% is left. Wins over
duration. Defaults to 0.6s.styleCSSProperties
classNamestring
Built from
Use
- Hitting a beat, a drop or a hard cut
- Camera-flash moments and reveals
Avoid
- A slow, warm glow over footage. Use
light-leak
Guides
Components take their colors from a theme, their timing from motion props and their layout from the canvas.
Source
registry/items/flash.tsx
/**
* @title Flash
* @category overlays
* @description Full-frame flash with a near-instant attack and an exponential decay, fired at `delay`.
* @duration 20
* @use Hitting a beat, a drop or a hard cut
* @use Camera-flash moments and reveals
* @avoid A slow, warm glow over footage. Use `light-leak`
* @tags flash, strobe, beat, hit, cut
* @example
* <Flash delay={24} strength={0.8} />
*/
import type React from "react";
import { AbsoluteFill } from "remotion";
import { type MotionProps, useMotion, useTheme } from "./core";
export type FlashProps = MotionProps & {
/** Flash color. Defaults to the theme foreground. */
color?: string;
/** Peak opacity, 0-1. */
strength?: number;
/** Frames from `delay` to full strength. */
attack?: number;
/** How the flash blends with the frame below, e.g. `screen` to brighten rather than cover. */
blendMode?: React.CSSProperties["mixBlendMode"];
/** Frames from the peak until about 1% is left. Wins over `duration`. Defaults to 0.6s. */
decayFrames?: number;
style?: React.CSSProperties;
className?: string;
};
/** `duration` is the decay: frames from the peak until about 1% is left. Defaults to 0.6s. */
export function Flash({
color,
strength = 0.9,
attack = 2,
blendMode = "normal",
decayFrames,
style,
className,
...motion
}: FlashProps) {
const theme = useTheme();
const m = useMotion(motion);
const attackFrames = Math.max(Math.round(attack), 1);
const since = m.frame - m.delay;
const decayFramesResolved = decayFrames ?? m.enterFrames;
const decay = (since - attackFrames) / Math.max(decayFramesResolved, 1);
const level =
since < 0
? 0
: since < attackFrames
? (since + 1) / (attackFrames + 1)
: // e^-4.6 ≈ 0.01, so the flash has all but gone when `duration` runs out.
decay >= 1
? 0
: Math.exp(-4.6 * decay);
return (
<AbsoluteFill
className={className}
style={{
background: color ?? theme.colors.foreground,
opacity: strength * level * (1 - m.exit),
mixBlendMode: blendMode,
pointerEvents: "none",
...style,
}}
/>
);
}