Chromatic Wave

A soft wave travels down through the type; where it crosses, the letters ripple and split into RGB fringes, then settle back to white

Installation

$ pnpm dlx shadcn@latest add @remocn/chromatic-wave

Usage

// src/Root.tsx
import { Composition } from "remotion";
import { ChromaticWave } from "@/components/remocn/chromatic-wave";
 
const ChromaticWaveScene = () => (
  <ChromaticWave headline="MUSIC" kicker="APPLES" />
);
 
export const RemotionRoot = () => (
  <Composition
    id="ChromaticWave"
    component={ChromaticWaveScene}
    durationInFrames={100}
    fps={30}
    width={1920}
    height={1080}
  />
);

Three copies of the type are displaced by the same traveling wave at three different depths — one per color channel — and summed back together with screen blending. Where the copies still coincide the sum is white; where the depths pull them apart, red, green and blue fringes appear. The component paints its own background (default black) because the reassembly is only exact over black.

Props

PropTypeDefaultDescription
headline
string"MUSIC"The large center line
kicker
string"APPLES"The small tracked line, repeated above and below the headline
headlineFontFamily / kickerFontFamily
stringHelvetica stackFonts of the two lines
headlineFontSize / kickerFontSize
number174 / 52Font sizes in comp pixels
kickerTracking
number32Letter spacing of the kicker lines
headlineBaselineY / kickerBaselines
number / [number, number]601 / [444, 670]Baselines of the three lines in comp pixels
textCenterX
number960Horizontal center of the type
fill
string"#ffffff"Color of the type before the split
background
string"#000000"Painted stage background. Keep it dark — the channel reassembly is only exact over black
width / height
number1920 / 1080Coordinate space of the composition
bandHeight / bandCopies / bandPitch
number147.1 / 7 / 750Geometry of the traveling distortion bands
mapStartY / mapEndY / mapTravelFrames
number31 / 1560 / 150The bands' travel. Deliberately linear — an ease reads as the ripple hesitating inside the word
waveHeight / waveWidth / waveSpeed
number28 / 272 / 1The sine ripple on each band's edges
turbulentAmount / turbulentSize
number130 / 163Turbulent displacement breaking the wave's regular rhythm
evolutionPerSecond
number50How fast the turbulence field pans
mapBlurRadius / mapBlurIterations
number13 / 6Blur on the displacement map — without it the map's edges tear the output
glassDisplacement / maxDisplacementPx
number100 / 39Displacement strength, and the pixel span it maps to
glassPasses
number3How many depth passes — also how many channels split
channelOrder
("red" | "green" | "blue")[]["blue", "green", "red"]Which channel rides which depth, shallowest first
className
stringOptional className passed to the wrapper

Inspired by 5 Clean Text Animations by Mapal.