【问题标题】:How to properly launch an animation one time when the element on view with React?当使用 React 查看元素时如何正确启动动画?
【发布时间】:2021-09-02 15:10:23
【问题描述】:

我是 React 的新手,当我的元素进入视口时,我尝试启动 CSS @keyframes 动画。

为此,我将 Intersection Observer 与 useOnScreen 挂钩:https://usehooks.com/useOnScreen/

我的 JSX:

import React, {useEffect, useRef, useState} from 'react'

import './landing.scss'

function useOnScreen(options){
    const ref = React.useRef(); 
    const [visible, setVisible] = React.useState(false);

    React.useEffect(() => {
        const observer = new IntersectionObserver(([entry]) => {
            setVisible(entry.isIntersecting);
        }, options);

        if (ref.current) {
            observer.observe(ref.current);
        }

        return () => {
            if (ref.current) {
                observer.unobserve(ref.current);
            }
        }

    }, [ref, options])

    return [ref, visible];
}

const Landing = () => {
    const [ref, visible] = useOnScreen();

    return(
        <>
        <div className="titleBox">
            <h2 style={{ animationDuration: `0.5s`, animationIterationCount: 1, animationName: visible ? "showTopText" : ``, animationDelay: "0.3s", animationTimingFunction: "ease" }}>My text</h2>
        </div>
        </>
    )
}

我的scss:

@keyframes showTopText {
    0% {top: 100%;}
    100% {top: 0;}
}

.titleBox{
    width: 100%;
    height: 64px;
    overflow: hidden;
    position: relative;

    h2{
        font-size: 56px;
        line-height: 64px;
        width: 100%;
        font-weight: normal;
        position: absolute;
    }
}

我的主要问题是每次元素返回屏幕时动画都会重复,并且我的文本加载到 top: 0%; 并在动画开始时消失到 top: 100%;

我该如何解决这个问题?

【问题讨论】:

    标签: css reactjs sass


    【解决方案1】:

    我终于在 Stack Overflow 上找到了可以让我做我想做的事的东西。 我使用 react-in-viewport 并做了这样的事情:

    const TitleSection2 = (props) => {
        const { inViewport, forwardedRef, enterCount } = props;
        if (inViewport && enterCount === 1) {
            return (
                <div ref={forwardedRef} className="titleBoxSection2">
                    <div className="line1">
                        <h2 className="visible">First line</h2>
                    </div>
                    <div className="line2">
                        <h2 className="visible">second line.</h2>
                    </div>
                </div>
            )
        }
        return (
            <div ref={forwardedRef} className="titleBoxSection2">
                <div className="line1">
                    <h2 className="notVisible">First line</h2>
                </div>
                <div className="line2">
                    <h2 className="notVisible">second line.</h2>
                </div>
            </div>
        );
    }
    
    const ViewportTitleSection2 = handleViewport(TitleSection2);
    

    使用这样的 SCSS:

    .titleBoxSection2{
        width: 100%;
        height: 128px;
            
        .line1{
            width: 100%;
            height: 64px;
            overflow: hidden;
            position: relative;
    
            h2.visible{
                font-size: 56px;
                line-height: 64px;
                width: 100%;
                font-weight: normal;
                position: absolute;
                animation: showTopText 0.5s;
                animation-delay: 0.3s;
                animation-fill-mode: forwards;
                animation-timing-function: ease;
                top: 100%;
            }
    
            h2.notVisible{
                font-size: 56px;
                line-height: 64px;
                width: 100%;
                font-weight: normal;
                position: absolute;
            }
        }
    
        .line2{
            width: 100%;
            height: 64px;
            overflow: hidden;
            position: relative;
    
            h2.visible{
                font-size: 56px;
                line-height: 64px;
                width: 100%;
                font-weight: normal;
                position: absolute;
                animation: showTopText 0.5s;
                animation-delay: 0.8s;
                animation-fill-mode: forwards;
                animation-timing-function: ease;
                top: 100%;
            }
    
            h2.notVisible{
                font-size: 56px;
                line-height: 64px;
                width: 100%;
                font-weight: normal;
                position: absolute;
            }
        }
    }
    

    我认为这不是最好的方法,但对我来说效果很好。 也许它可以帮助别人。 不要犹豫,纠正我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 2014-03-11
      • 1970-01-01
      • 1970-01-01
      • 2014-02-23
      相关资源
      最近更新 更多