Text Highlight
snap-cn/text-highlightFreeComponent
Animated emphasis on one span inside a static sentence — marker sweep, color shift, underline, strikethrough-replace, or shimmer.
Install it
npx shadcn@latest add https://snapcn.dev/r/text-highlight.jsonSource
1"use client";23import {4 Easing,5 getRemotionEnvironment,6 Img,7 interpolate,8 interpolateColors,9 spring,10 staticFile,11 useCurrentFrame,12 useVideoConfig,13} from "remotion";14import {15 parseColor,16 rgbToOklch,17 type SnapCnTheme,18 useSnapCnTheme,19 withAlpha,20} from "@/lib/snap-cn-ui";2122export type TextHighlightPreset =23 | "logo-wipe"24 | "marker"25 | "color"26 | "underline"27 | "strikethrough"28 | "shimmer";2930export interface TextHighlightSpringConfig {31 damping?: number;32 mass?: number;33 stiffness?: number;34}3536/**37 * Rewrite root-relative assets through staticFile only while rendering.38 *39 * A page serves `/logo/mark.png` from `public/`; a Remotion bundle does not —40 * it 404s, and `<Img>` turns that into a `cancelRender` that kills the whole41 * render rather than showing a broken image. Same helper as `logo-flicker`,42 * `logo-assemble` and `moodboard-reveal`; kept per-file on purpose, because a43 * registry component has to stand alone in whatever project copies it.44 */45function resolveSrc(src: string): string {46 const isLocal = src.startsWith("/") && !src.startsWith("//");47 if (isLocal && getRemotionEnvironment().isRendering) {48 return staticFile(src.replace(/^\/+/, ""));49 }50 return src;51}5253/** The lighter of two colours — a specular highlight follows the light, not the mode. */54function lighterOf(a: string, b: string): string {55 return (rgbToOklch(parseColor(a)).l ?? 0) >=56 (rgbToOklch(parseColor(b)).l ?? 0)57 ? a58 : b;59}6061/** Default line thickness for underline/strikethrough, derived from font size. */62export function defaultThickness(fontSize: number): number {63 return Math.max(2, Math.round(fontSize * 0.08));64}6566/**67 * Strikethrough timeline. The line draws over `drawDuration` frames (0–40% of68 * the emphasis window), then the old text crossfades into the replacement69 * over half that long (40–60%), then holds.70 */71export function strikethroughPhases(72 startAt: number,73 drawDuration: number,74): { drawStart: number; drawEnd: number; fadeStart: number; fadeEnd: number } {75 const drawEnd = startAt + drawDuration;76 return {77 drawStart: startAt,78 drawEnd,79 fadeStart: drawEnd,80 fadeEnd: drawEnd + drawDuration * 0.5,81 };82}8384/**85 * Apparent size of something travelling toward the camera. `travel` is 0 at rest86 * and 1 at the eye. Size goes as `1 / (1 - travel)`, so it creeps for most of the87 * trip and then blows up right at the end — which is the whole character of a88// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from snap-cn
All 24 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Answer Streamanswer-stream | snap-cn | Components | Free | 2 deps | |
| UI Caretcaret | snap-cn | Components | Free | 1 dep | |
| Follower Rushfollower-rush | snap-cn | Components | Free | 2 deps | |
| Product Herohero-launch | snap-cn | Components | Free | 2 deps | |
| UI Inputinput | snap-cn | Components | Free | 2 deps · 2 files | |
| Karaoke Captionskaraoke-captions | snap-cn | Components | Free | 2 deps | |
| Laptop Framelaptop-frame | snap-cn | Components | Free | 1 dep | |
| Logo Assemblelogo-assemble | snap-cn | Components | Free | 1 dep |
