React中IntersectionObserver的threshold属性不生效的问题求助
React中IntersectionObserver的threshold属性不生效的问题求助
我在React项目里用IntersectionObserver给元素做滚动触发动画,明明把threshold设成了0.5(也就是期望元素一半进入视口时再触发动画),结果元素刚一出现在屏幕上动画就直接跑起来了,完全不符合预期。我实在搞不懂哪里出问题了,有没有大佬能帮忙分析下?(我把CSS也附上了,说不定样式这边有影响,我也拿不准)
(附效果演示:元素刚进入视口就触发了动画)
React组件代码
import { buttonHoverAnimation, rotateAnimation } from "../../animations/animations"; import backgroundImage from "../../assets/images/pexels.jpg"; import smileIcon from "../../assets/icons/smile.svg"; import "./ExploreCard.css"; import { useEffect, useRef } from "react"; import { slideAnimation } from "../../animations/animations"; type ExploreCardProps = { reverse?: boolean; }; function ExploreCard({ reverse }: ExploreCardProps) { const buttonHover = buttonHoverAnimation({}, {}, 30); const contentRef = useRef<HTMLDivElement>(null); const imageRef = useRef<HTMLDivElement>(null) // Handler Slide animation useEffect(() => { if (!contentRef.current) return; const animation = slideAnimation( contentRef.current, reverse ? [-1000, 0] : [1000, 0] ); const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { animation.play(); observer.unobserve(entries[0].target); } }, { threshold: 0.5 }); observer.observe(contentRef.current); return () => { observer.disconnect(); }; }); // Handle rotate animation , useEffect(() => { if (!imageRef.current) return; const animation = rotateAnimation(imageRef.current) const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { animation.play(); observer.unobserve(entries[0].target); } }, { threshold: 0.5 } ); observer.observe(imageRef.current); return () => { observer.disconnect(); }; }, []); return ( <div className={`explore-card ${reverse ? "reverse" : ""}`}> <div className="explore-image-wrapper" ref={imageRef}> <img src={backgroundImage} alt="Background-image" /> </div> <div className={`explore-card-popup ${reverse ? "reverse" : ""}`}> <h2>2X</h2> <p>Faster</p> </div> <div className={`explore-content-wrapper ${reverse ? "reverse" : ""}`}ref={contentRef}> <div className="explore-content-icon"> <img src={smileIcon} alt=":)" /> <p>QUICK</p> </div> <div className="explore-content-header"> <h1 className="explore-content-header-bold">HOME</h1> <h1 className="explore-content-header-italic">Refresh</h1> </div> <div className="explore-content-description"> Experience the ultimate expert support — Creating spaces where comfort and productivity thrive. </div> <div className="explore-content-button"> <button onMouseOver={buttonHover.handleMouseIn} onMouseOut={buttonHover.handleMouseOut} > <span>EXPLORE</span> <span>EXPLORE</span> </button> </div> </div> </div> ); } export default ExploreCard;
对应的CSS代码
@font-face { font-family: intern-light; src: url('../../assets/fonts/static/Inter_18pt-Thin.ttf'); } @font-face { font-family: intern-regular; src: url('../../assets/fonts/static/Inter_18pt-Light.ttf'); } @font-face { font-family: intern-bold; src: url('../../assets/fonts/static/Inter_24pt-Black.ttf'); } @font-face { font-family: intern-italic; src: url('../../assets/fonts/static/Inter_18pt-ThinItalic.ttf'); } .explore-card { display: flex; justify-content: center; align-items: center; width: 100%; position: relative; gap: 2vw; margin-top: 15vh; overflow: hidden; height: 50vh; } .explore-content-wrapper { width: 35%; display: flex; padding: 7%; display: inline-block; } .explore-content-icon > p{ font-family: intern-regular; margin-left: 10px; font-weight: 500; letter-spacing: 2px; } .explore-content-icon { display: flex; } .explore-content-icon > img { width: 30px; } .explore-image-wrapper { display: flex; height: 50vh; width: 25%; border-radius: 70px; overflow: hidden; position: relative; display: flex; justify-content: center; align-items: center; z-index: 2; } .explore-image-wrapper > img { width: 100%; height: 100%; object-fit: cover; display: block; } .explore-card-popup { top: 10%; left: 30%; border-radius: 50px; position: absolute; height: 34%; width: 13%; background-color: rgba(255, 255, 255, 0.7); backdrop-filter: blur(10px); display: flex; justify-content: center; align-items: center; flex-direction: column; -webkit-box-shadow: 0px 10px 50px -10px rgba(0, 0, 0, 0.75); -moz-box-shadow: 0px 10px 50px -10px rgba(0, 0, 0, 0.75); box-shadow: 0px 10px 50px -10px rgba(0, 0, 0, 0.75); z-index: 3; } .explore-card-popup > h2 { font-family: intern-regular; font-weight: 100; font-size: 30px; margin: 0; } .explore-card-popup > p { font-family: intern-light; font-size: 20px; font-weight: 600; margin-top: 0; letter-spacing: 2px; } .explore-content-header { display: flex; font-size: 60px; } .explore-content-header > h1 { margin-top: 5px; margin-right: 10%; margin-bottom: 5px; } .explore-content-header-bold { font-family: intern-regular; font-weight: 300; } .explore-content-header-italic { font-family: intern-italic; font-weight: 100; } .explore-content-description { font-family: intern-regular; font-size: 18px; letter-spacing: 2px; line-height: 30px; margin-bottom: 30px; } .explore-content-button > button { font-family: intern-regular; height: 1.3rem; font-size: 1.3rem; background: none; border: 0; cursor: pointer; display: flex; flex-direction: column; overflow: hidden; } .explore-content-button > button > span { position: relative; transition: transform 0.7s, opacity 0.7s; margin: 0; } .explore-card.reverse { flex-direction: row-reverse; } .explore-card-popup.reverse { left: 57%; }
备注:内容来源于stack exchange,提问作者Zura Gabichvadze
相关产品推荐
相关产品推荐

