Text Cursor Proximity
A text component that animates the letters based on the cursor proximity
Installation
npx shadcn@latest add "https://fancycomponents.dev/r/text-cursor-proximity.json"
Understanding the component
The TextCursorProximity
splits its text into letters that respond to cursor movement by adjusting their CSS properties based on the distance between the letter and cursor position.
- Splitting text into individual letters
- Tracking cursor position relative to each letter
- Smoothly transitioning CSS values with motion's
useTransform
hook - Supporting multiple falloff patterns for the effect
How it works
The component calculates the distance between the cursor and each letter in real-time. When the cursor comes within the specified radius
of a letter, that letter's CSS properties (like scale, color, etc.) smoothly interpolate between two states. For this, we use the motion
library's useTransform
hook, which maps the CSS properties from the styles.*.from
state to the styles.*.to
state based on the proximity value (which ranges from 0 to 1).
- Default state: (defined in
styles.*.from
) - Target state (defined in
styles.*.to
)
You can interpolate any value that motion supports (which is actually any CSS value, even those that can't be animated by the browser, like mask-image
).
The closer the cursor gets to a letter, the closer that letter moves toward its target state.
Examples
Falloff
With the falloff
prop, you can control the type of falloff. It can be either linear
, exponential
, or gaussian
. The following demo showcases the exponential
one. The effects are best observed on a larger block of text.
Notes
It seems like interpolating on large number of letters simultaneously can be a bit slow, even when we're avoiding re-renders with state updates. If you're experiencing performance issues, try to limit the length of the text you're animating.
Props
Prop | Type | Default | Description |
---|---|---|---|
label* | string | - | The text to be displayed and animated |
styles* | Partial<{ [K in keyof CSSProperties]: { from: string | number, to: string | number } }> | - | CSS properties to animate and their from/to values |
containerRef* | React.RefObject<HTMLDivElement> | - | Reference to the container for mouse tracking |
radius | number | 50 | The radius of the proximity effect in pixels |
falloff | "linear" | "exponential" | "gaussian" | "linear" | The falloff pattern for the proximity effect |
className | string | - | Additional CSS classes for styling |