reelcn
GitHubBack to landing

Flash

Full-frame flash with a near-instant attack and an exponential decay, fired at `delay`.

Flash, white
Flash, white thumbnail, 16:9

Installation

npx shadcn add https://www.reelcn.dev/r/flash.json

Files 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

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,
      }}
    />
  );
}

On this page