跳到主要内容
Example+

文字爆炸

ui

桃李春风一杯酒,江湖夜雨十年灯。

src

TSX
// npm install motion motion-plus
"use client";

import { useEffect, useRef, useState } from "react";
import { animate, delay, mix, wrap, type AnimationSequence } from "motion/react";
import { splitText } from "motion-plus";

const lines = [
    "桃李春风一杯酒,江湖夜雨十年灯。",
    "春风又绿江南岸,明月何时照我还?",
    "羌笛何须怨杨柳,春风不度玉门关。",
];

export default function Page() {
    const ref = useRef<HTMLDivElement>(null);
    const [index, setIndex] = useState(0);

    useEffect(() => {
        if (!ref.current) return;

        const { chars } = splitText(ref.current);

        const sequence: AnimationSequence = chars.map((char) => {
            const velocity = mix(200, 400, Math.random());
            const angle = 2 * Math.PI * Math.random();
            return [
                char,
                {
                    opacity: 0,
                    x: Math.cos(angle) * velocity,
                    y: Math.sin(angle) * velocity,
                    scale: 3,
                    color: `hsl(${Math.random() * 360} 100% 50%)`,
                },
                { type: "inertia", velocity, at: "<" },
            ];
        });

        const animation = animate(sequence, { delay: 0.5 });
        animation.finished.then(() => {
            delay(() => setIndex((i) => wrap(0, lines.length, i + 1)), 1);
        });

        return () => animation.stop();
    }, [index]);

    return (
        <div className="flex h-screen items-center justify-center overflow-hidden bg-black">
            <div ref={ref} className="text-4xl text-white">
                {lines[index]}
            </div>
        </div>
    );
}