TV Power Off

End a scene the way a tube does — the picture collapses into a glowing line, pinches to a phosphor dot, and the frame is left dead black

Installation
$ pnpm dlx shadcn@latest add @remocn/tv-power-off

Usage

Wrap a scene and, on the frame you point it at, its power is cut. The picture squashes toward the centre line while the light it loses is pushed into what is left, so the last few rows are a blown-out band rather than a squashed thumbnail. The band pinches to a dot, the dot decays, and the frame is black.

tsx
import { TvPowerOff } from "@/components/remocn/tv-power-off";
 
export const MyScene = () => (
  <TvPowerOff delay={25}>
    <Outro />
  </TvPowerOff>
);

Timing it

delay is counted from the start of the enclosing Sequence, so the scene plays untouched for delay frames and the collapse runs for the next durationInFrames. Budget both: a Sequence that ends before delay + durationInFrames cuts away mid-collapse.

The default 18 frames is a hard power cut. Stretch it toward 30 and the line hangs long enough to read as a tube giving up rather than being switched.

tsx
<TvPowerOff delay={60} durationInFrames={26}>
  <Scene />
</TvPowerOff>

Props6

PropTypeDefault
durationInFrames
number18

How long the whole collapse takes. The first 60% is the vertical squash, the next 22% pinches the line to a dot, and the rest is the dot decaying.

delay
number0

Frames of untouched scene before the collapse starts, counted from the enclosing Sequence.

gain
number1

How hard the picture brightens as it is squashed. At 1 the light lost to the collapse is pushed back into the remaining rows, which is what blows the line out to white. At 0 the picture simply shrinks.

afterglow
number1

Reach of the phosphor bleed — the glow that spills above and below the line, and the halo around the dot. At 0 the collapse is geometry only.

phosphor
string"#d8ecff"

Colour of that glow. The cool white of a monochrome tube by default; warm it toward amber for an older terminal.

children
React.ReactNode—

The scene being switched off.

  • durationInFramesnumber

    How long the whole collapse takes. The first 60% is the vertical squash, the next 22% pinches the line to a dot, and the rest is the dot decaying.

    Default18

  • delaynumber

    Frames of untouched scene before the collapse starts, counted from the enclosing Sequence.

    Default0

  • gainnumber

    How hard the picture brightens as it is squashed. At 1 the light lost to the collapse is pushed back into the remaining rows, which is what blows the line out to white. At 0 the picture simply shrinks.

    Default1

  • afterglownumber

    Reach of the phosphor bleed — the glow that spills above and below the line, and the halo around the dot. At 0 the collapse is geometry only.

    Default1

  • phosphorstring

    Colour of that glow. The cool white of a monochrome tube by default; warm it toward amber for an older terminal.

    Default"#d8ecff"

  • childrenReact.ReactNode

    The scene being switched off.

Notes

The squash is an integral, not a scale. Every output row averages the source rows that collapse into it, so text does not alias into stripes on the way down and the line keeps the horizontal colour of the columns above it — that is why the last frames of the band still carry the scene rather than a grey smear.

Once the collapse begins the frame behind the picture is opaque black, and it stays black after the dot is gone. That is a dead screen rather than a hole, so do not expect a backdrop to show through afterwards.

Nothing is carried between frames: progress is a pure function of the current frame, so parallel and server-side renders produce identical pixels.