typescript 如何动画溢出的文本滚动到文本的末尾时,悬停和动画回到原来的位置时,鼠标离开?

7bsow1i6  于 2023-06-30  发布在  TypeScript
关注(0)|答案(1)|浏览(120)

当鼠标悬停在一个有溢出文本的容器上时,我正在尝试动画滚动文本。现在,当鼠标悬停在容器上时,我让动画滚动到文本的末尾,但是当鼠标离开时,文本突然回到原来的位置。我希望它也动画回到原来的位置时,鼠标离开。

import {useEffect, useRef, useState} from 'react';
import classes from './test.module.css';

const Test = () => {
    const textRef = useRef(null);
    const containerRef = useRef(null);

    const [isHovered, setIsHovered] = useState(false);
    const [isOverflowing, setIsOverflowing] = useState(false);

    const onMouseEnter = () => {
        setIsHovered(true);
    };

    const onMouseLeave = () => {
        setIsHovered(false);
    };

    useEffect(() => {
        const textWidth = textRef.current.offsetWidth;
        const containerWidth = containerRef.current.offsetWidth;

        if (textWidth > containerWidth) {
            setIsOverflowing(true);
        }
    }, []);

    return (
        <div>
            <div ref={containerRef} className={classes.animated} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
                <h3 className={isHovered && isOverflowing ? classes.textAnimated : classes.text} ref={textRef}>
                    This is some very very very long text
                </h3>
            </div>
        </div>
    );
};

export default Test;
.animated {
    margin: 200px;
    position: relative;
    white-space: nowrap;
    max-width: 300px;
    width: 100%;
    overflow: hidden;
    background: #0c0c0c;
    display: inline-block;
    position: relative;
    border: 1px solid white;
}

.textAnimated {
    color: #fff;
    animation: textScroll 3s linear forwards;
    display: inline-block;
    position: relative;
}

.text {
    color: #fff;
    display: inline-block;
    position: relative;
}

@keyframes textScroll {
    0% {
        transform: translateX(0);
        left: 0;
    }
    10% {
        transform: translateX(0);
        left: 0;
    }
    90% {
        transform: translateX(calc(-100%));
        left: 100%;
    }
    100% {
        transform: translateX(calc(-100%));
        left: 100%;
    }
}
e4eetjau

e4eetjau1#

考虑使用transition而不是animationtransition对于两个状态之间的视觉插值很有用,就像悬停时的情况一样:

const {useEffect, useRef, useState} = React;

const Test = () => {
  const textRef = useRef(null);
  const containerRef = useRef(null);

  const [isOverflowing, setIsOverflowing] = useState(false);

  useEffect(() => {
    const textWidth = textRef.current.offsetWidth;
    const containerWidth = containerRef.current.offsetWidth;

    if (textWidth > containerWidth) {
      setIsOverflowing(true);
    }
  }, []);

  return (
    <div>
      <div ref={containerRef} className="animated">
        <h3 className={isOverflowing ? 'textAnimated' : 'text'} ref={textRef}>
          This is some very very very long text
         </h3>
       </div>
    </div>
  );
};

ReactDOM.createRoot(document.getElementById('app')).render(<Test/>);
.animated {
    margin: 200px;
    position: relative;
    white-space: nowrap;
    max-width: 100px;
    width: 100%;
    overflow: hidden;
    background: #0c0c0c;
    display: inline-block;
    position: relative;
    border: 1px solid white;
}

.textAnimated {
    color: #fff;
    display: inline-block;
    position: relative;
    left: 0;
    transition: transform 3s linear, left 3s linear;
}
.animated:hover .textAnimated {
  transform: translateX(-100%);
  left: 100%;
}

.text {
    color: #fff;
    display: inline-block;
    position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div id="app"></div>

相关问题