Elastic Text
godui/elastic-textFreeComponent
Variable-font text whose weight springs up under an automatic spotlight or the pointer.
Install it
npx shadcn@latest add https://godui.design/r/elastic-text.jsonSource
1"use client";23import {4 animate,5 motion,6 useMotionValue,7 useReducedMotion,8 useSpring,9 useTransform,10} from "framer-motion";11import * as React from "react";12import { clamp, getTextContent, lerp } from "../lib/text-utils";1314/**15 * How the weight emphasis is driven:16 * - `auto` — a spotlight sweeps across the text on its own (default).17 * - `hover` — the emphasis follows the pointer while it's over the text.18 */19export type ElasticTextMode = "auto" | "hover";2021export type ElasticTextProps = React.HTMLAttributes<HTMLSpanElement> & {22 children: React.ReactNode;23 mode?: ElasticTextMode;24 /** Resting (lightest) font weight. */25 minWeight?: number;26 /** Peak (heaviest) font weight under the spotlight / pointer. */27 maxWeight?: number;28 /** Seconds for one full `auto` sweep across the text. */29 duration?: number;30 /** Repeat the `auto` sweep. */31 loop?: boolean;32 /** Start the `auto` sweep only once the text scrolls into view. */33 startOnView?: boolean;34 /** Pointer influence radius in px (`hover` mode). */35 radius?: number;36};3738const SPRING = { stiffness: 150, damping: 18, mass: 1 } as const;39const AUTO_SPREAD = 2.5;40const VIEW_THRESHOLD = 0.3;4142// Uses the theme sans font (Geist is a variable font with a `wght` axis); on a43// non-variable font the weight steps to the nearest available cut.44const CONTAINER_CLASS =45 "inline-block font-sans leading-[1.1] text-inherit [font-optical-sizing:auto] [font-variation-settings:'wght'_400]";46const SEGMENT_CLASS =47 "inline-block whitespace-pre [font-variation-settings:'wght'_var(--et-wght,400)] [will-change:font-variation-settings] motion-reduce:[will-change:auto]";4849type SegmentProps = {50 segment: string;51 index: number;52 minWeight: number;53 maxWeight: number;54 reducedMotion: boolean;55 mode: ElasticTextMode;56 spotlight: ReturnType<typeof useMotionValue<number>>;57 pointerX: ReturnType<typeof useMotionValue<number>>;58 pointerActive: ReturnType<typeof useMotionValue<number>>;59 getCenter: (index: number) => number;60 radius: number;61};6263function Segment({64 segment,65 index,66 minWeight,67 maxWeight,68 reducedMotion,69 mode,70 spotlight,71 pointerX,72 pointerActive,73 getCenter,74 radius,75}: SegmentProps) {76 const autoWeight = useTransform(spotlight, (position) => {77 const distance = Math.abs(index - position);78 const influence = clamp(1 - distance / AUTO_SPREAD, 0, 1);79 return lerp(minWeight, maxWeight, influence);80 });8182// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from godui
All 105 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | godui | Components | Free | 1 dep | |
| Agent Flowagent-flow | godui | Components | Free | 1 dep | |
| Agent Timelineagent-timeline | godui | Components | Free | 1 dep | |
| Animated Beamanimated-beam | godui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | godui | Components | Free | 1 dep | |
| Animated Tooltipanimated-tooltip | godui | Components | Free | 1 dep | |
| App Showcaseapp-showcase | godui | Components | Free | 1 dep | |
| Aurora Textaurora-text | godui | Components | Free | no deps |
