Kinetic Morph Text
Letters lift, rotate, and reshape into the next phrase with delicate outline trails
$ pnpm dlx shadcn@latest add @remocn/kinetic-morph-textUsage
Separate phrases with | or a newline. The first phrase flies into place;
after a readable pause, its letters lift and rotate into the next phrase.
Identical letters travel to their new positions. Other letters stretch and
soften into replacement glyphs, while additional characters enter and excess
characters leave. The final phrase stays on screen.
import { KineticMorphText } from "@/components/remocn/kinetic-morph-text";
export const TitleScene = () => (
<KineticMorphText text="Hello | Make it move | Shape what's next" />
);The soft morph combines squash/stretch and a local blur/threshold blend of native glyphs; it does not interpolate font outlines. Contour trails sample earlier poses and disappear when the letters settle. All motion is driven by the Remotion frame, including when scrubbing backward.
Timing
At the defaults, the first entrance takes 54 frames, followed by a 42-frame hold. Each subsequent phrase adds another 54-frame transition and 42-frame hold. The three-phrase sequence finishes moving at frame 246; its full duration including the final hold is 288 frames at 30 fps.
Use the duration helper when changing the phrase count, timing, or speed. It returns frames at 30 fps; scale the result for another composition frame rate. The docs preview updates its duration automatically when the copy, timing, or speed changes, so every phrase remains included.
import { Composition } from "remotion";
import {
KineticMorphText,
getKineticMorphTextDuration,
} from "@/components/remocn/kinetic-morph-text";
const props = {
text: "Think | Make | Move | Repeat",
transitionFrames: 48,
holdFrames: 36,
speed: 1,
};
export const Root = () => (
<Composition
id="KineticMorphText"
component={KineticMorphText}
defaultProps={props}
durationInFrames={getKineticMorphTextDuration(props)}
fps={30}
width={1280}
height={720}
/>
);With loop, the sequence starts on the readable first phrase, skips the initial
entrance, and uses its final transition to return to that phrase. One complete
cycle has the same duration as the non-looping sequence. A single phrase stays
still in loop mode.
Tuning the motion
Reduce spread and rotation for quieter movement. Set morph={0} for a clean
glyph crossfade during the flight and trails={0} to remove the outlines.
The font is Arial with Helvetica and sans-serif fallbacks, so no font download
is needed. The longest phrase determines a shared font size that fits within
82% of the composition width. Empty entries are ignored; empty input renders
only the background. Spaces, punctuation, repeated letters, and grapheme
clusters are preserved.
<KineticMorphText
text="Create | Iterate | Ship"
spread={140}
rotation={80}
morph={0.65}
trails={0.3}
color="#ded4ff"
backgroundColor="#171324"
/>Props14
| Prop | Type | Default |
|---|---|---|
| text | string"Hello | Make it move | Shape what's next" Phrases separated by pipes or newlines | |
| fontSize | number100 Maximum font size; automatically reduced to fit the longest phrase | |
| fontWeight | number600 CSS font weight | |
| color | string"#b4f4d9" Letter and outline color | |
| backgroundColor | string"#a800b7" Full-frame background; accepts transparent | |
| spread | number180 Flight radius in pixels, capped to fit the composition | |
| rotation | number110 Maximum letter rotation in degrees | |
| morph | number0.75 Soft shape-blend strength from 0 to 1 | |
| trails | number0.45 Outline echo opacity from 0 to 1 | |
| transitionFrames | number54 Entrance and transition duration at 30 fps | |
| holdFrames | number42 Readable pause per phrase at 30 fps | |
| loop | booleanfalse Start on the first phrase and cycle back to it | |
| speed | number1 Playback multiplier; 0 freezes the animation | |
| className | string— Optional class name on the full-frame root | |
- textstring
Phrases separated by pipes or newlines
Default
"Hello | Make it move | Shape what's next" - fontSizenumber
Maximum font size; automatically reduced to fit the longest phrase
Default
100 - fontWeightnumber
CSS font weight
Default
600 - colorstring
Letter and outline color
Default
"#b4f4d9" - backgroundColorstring
Full-frame background; accepts transparent
Default
"#a800b7" - spreadnumber
Flight radius in pixels, capped to fit the composition
Default
180 - rotationnumber
Maximum letter rotation in degrees
Default
110 - morphnumber
Soft shape-blend strength from 0 to 1
Default
0.75 - trailsnumber
Outline echo opacity from 0 to 1
Default
0.45 - transitionFramesnumber
Entrance and transition duration at 30 fps
Default
54 - holdFramesnumber
Readable pause per phrase at 30 fps
Default
42 - loopboolean
Start on the first phrase and cycle back to it
Default
false - speednumber
Playback multiplier; 0 freezes the animation
Default
1 - classNamestring
Optional class name on the full-frame root