Я пытаюсь анимировать мои react-slick
слайды, когда они входят в область просмотра, обнаруживая, когда элементы слайда пересекаются с моим элементом root, используя IntersectionObserver
API.
Это работает, как и ожидалось.
Что не работает, так как, когда react-slick
возвращается из :last-slide
в :first-slide
, первый компонент реагирования, кажется, на мгновение теряет свое состояние до того, как «наверстать упущенное» - даже если он уже отрендерен.
Я продемонстрировал это в двух местах: один раз с использованием собственного API IntersectionObserver и один раз с использованием React Wrapper вокруг собственного API - react-intersection-observer
.
Полный код того, что у меня есть, ниже и в песочницах здесь:
Родной: https://codesandbox.io/s/react-slick-and-native-intersection-observer-cqtmv
React Wrapper: https://codesandbox.io/s/react-slick-and-react-intersection-observer-qvbum
const ReactSlickDemo = () => {
const useStyles = makeStyles(theme => ({
root: {
display: "flex",
justifyContent: "center",
flexWrap: "wrap",
"& > *": {
margin: theme.spacing(0.5)
}
},
container: {
padding: "40px",
background: "#419be0",
"& .slick-slide img": {
margin: "auto"
}
},
initFadeIn: {
"& *": {
opacity: 0,
"& img": {
opacity: 1
},
"& [class*=SWRecordHeader-images-]": {
opacity: 1
}
},
"& [class*=SWRecordHeader-inner-]": {
opacity: 1
}
},
runFadeIn: {
"& *": {
opacity: 1
}
},
initSlideUp: {
"& *": {
webkitTransform: "translateY(30px)",
transform: "translateY(30px)",
"& img": {
webkitTransform: "translateY(-30px)",
transform: "translateY(-30px)"
},
"& [class*=SWRecordHeader-images-]": {
webkitTransform: "unset",
transform: "unset"
}
}
},
runSlideUp: {
"& *": {
webkitTransform: "translateY(0px)",
transform: "translateY(0px)",
"& img": {
webkitTransform: "translateY(0px)",
transform: "translateY(0px)"
}
}
},
initTransition: {
"& *": {
webkitTransition: "all 0.6s ease-in-out",
transition: "all 0.6s ease-in-out"
}
}
}));
const classes = useStyles();
const Component = () => {
const [toggle, setToggle] = useState(false);
const el = useRef(null);
useEffect(() => {
console.log("effect!");
const node = el.current;
const options = {
threshold: 0.5
};
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting && !toggle) setToggle(true);
console.log(toggle);
});
}, options);
observer.observe(node);
return () => observer.unobserve(node);
}, [toggle, el]);
return (
<div
ref={el}
className={clsx(
classes.initTransition,
classes.initFadeIn,
classes.initSlideUp,
{
[classes.runFadeIn]: toggle,
[classes.runSlideUp]: toggle
}
)}
>
<img src="http://placekitten.com/g/400/200" alt="test" />
</div>
);
};
return (
<div className={classes.container}>
<Slider dots>
{[1, 2, 3, 4].map(item => (
<Component />
))}
</Slider>
</div>
);
};