Distort Text

PreviousNext

A responsive text effect that scrambles nearby characters as the cursor moves across a paragraph.

Docs
paceuiui

Preview

Loading preview…
gsap/distort-text.tsx
"use client";

import { ComponentProps, useRef } from "react";

import { useGSAP } from "@gsap/react";
import gsap from "gsap";
import { ScrambleTextPlugin } from "gsap/ScrambleTextPlugin";
import { SplitText } from "gsap/SplitText";

gsap.registerPlugin(ScrambleTextPlugin);

type DistortTextProps = {
    distortChar?: string;
} & ComponentProps<"div">;

export const DistortText = ({ distortChar = ".:", ...props }: DistortTextProps) => {
    const wrapperRef = useRef<HTMLDivElement | null>(null);

    useGSAP(
        () => {
            const element = wrapperRef.current;
            if (!element) return;

            const splitText = SplitText.create(element, { type: "chars", charsClass: "char" });

            splitText.chars.forEach((char) => {
                gsap.set(char, { attr: { "data-content": char.innerHTML } });
            });

            element.onpointermove = (e) => {
                splitText.chars.forEach((char) => {
                    const rect = char.getBoundingClientRect();
                    const cx = rect.left + rect.width / 2;
                    const cy = rect.top + rect.height / 2;
                    const dx = e.clientX - cx;
                    const dy = e.clientY - cy;
                    const dist = Math.sqrt(dx * dx + dy * dy);
                    if (dist < 100) {
                        gsap.to(char, {
                            overwrite: true,
                            duration: 2 - dist / 100,
                            scrambleText: {
                                // @ts-ignore
                                text: char.dataset.content,
                                chars: distortChar,
                                speed: 0.5,
                            },
                            ease: "bounce",
                        });
                    }
                });
            };
        },
        { scope: wrapperRef },
    );

    return <div {...props} ref={wrapperRef} />;
};

Installation

npx shadcn@latest add @paceui/distort-text

Usage

import { DistortText } from "@/components/ui/distort-text"
<DistortText />