Как получить несколько ссылок с массивом в React и useRef hook? - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь создать анимированный текст в React (машинопись) с помощью GSAP.

Текстовая переменная - это строка, которая разбивается на массив строк, форма которых создает отдельные div для каждой буквы. Чтобы анимировать это с помощью GSAP, каждый элемент должен иметь свою собственную ссылку - на данный момент работает только последняя буква, так как назначается только одна ссылка.

Как создать отдельные ссылки для каждого элемента и передать их в gsap ? Где-то видел, что я должен передать обратный вызов в качестве ссылок, но я не уверен, как это сделать.

const TextAnimator: FC<TextAnimatorTypes> = ({ text }) => {
    const animatedLetter = useRef(null);

    const letterArray = text.split('');
    const letterElements = [];
    for (let i = 0; i < letterArray.length; i++) {
        letterElements.push(<div ref={animatedLetter} className={styles.letter}>{letterArray[i] === ' ' ? '\xa0' : letterArray[i]}</div>);
    }

    useEffect(() => {
        const random = (min: number, max: number) => {
            return (Math.random() * (max - min)) + min;
        };

        gsap.from(animatedLetter.current, {
            duration: 2.5,
            opacity: 0,
            x: 0,
            y: random(-200, 200),
            z: random(500, 1000),
            scale: .1,
            delay: 0.2,
            yoyo: true,
            repeat: -1,
            repeatDelay: 4,
            ease: Power1.easeOut
        });
    }, []);

    return (
        <div className={styles.box}>
            <p className={styles.animatedText}>
                {letterElements}
            </p>
        </div>
    );
};

1 Ответ

0 голосов
/ 23 марта 2020

Я нашел обходной путь, но все же предпочел бы хук useRef, если кто-то знает способ сделать это ...

const TextAnimator: FC<TextAnimatorTypes> = ({ text }) => {
    const letterArray = text.split('');
    const letterElements = [];
    const elementIds: string[] = [];
    for (let i = 0; i < letterArray.length; i++) {
        letterElements.push(<div className={styles.letter}
                                 id={letterArray[i] + i}>{letterArray[i] === ' ' ? '\xa0' : letterArray[i]}</div>);
        elementIds.push(letterArray[i] + i);
    }

    const random = (min: number, max: number) => {
        return (Math.random() * (max - min)) + min;
    };

    useEffect(() => {
        for (let i = 0; i < elementIds.length; i++) {
            const element = document.getElementById(elementIds[i]);
            gsap.from(element, {
                duration: 2.5,
                opacity: 0,
                x: random(-500, 500),
                y: random(-500, 500),
                z: random(-500, 500),
                scale: .1,
                delay: i * .02,
                yoyo: true,
                repeat: -1,
                repeatDelay: 10,
                ease: Power1.easeOut
            });
        }
    }, [elementIds]);

    return (
        <div className={styles.box}>
            <p className={styles.animatedText}>
                {letterElements}
            </p>
        </div>
    );
};
...