react로 IntersectionObserver를 사용하여 object가 화면 지정한 위치에 도착했을때 애니메이션이 작동되는것을 구현해 보았다.
//App.jsx
const array=[
{id:1,content:'a'},
{id:2,content:'b'},
{id:3,content:'c'},
]
const App = () => {
return (
<Styled.Container>
{array.map((arr, index) => {
return (
<Tag
arrayContent={arr.content}
/>
);
})}
</Styled.Container>
);
};
//Tag.jsx
const Tag = ({ arrayContent }) => {
return (
<div>
<Styled.Ptag>
{arrContent}
</Styled.Ptag>
</div>
);
};
먼저 array의 content를 화면에 뿌렸으며 한페이지에 1개의 content가 보이도록 style을 주었다.
(현재는 스크롤 할때마다 'a' => 'b'순으로 넘어간다.)
//Tag.jsx
const Tag = ({ arrContent }) => {
const element = useCallback((node) => {
const observer = new IntersectionObserver(
(entries, observer) => {
console.log(entries
},
{
threshold: 1,
rootMargin: "0px 0px -20px 0px",
}
);
observer.observe(node);
}, []);
return (
<div>
<Styled.Ptag
ref={element}
>
{arrContent}
</Styled.Ptag>
</div>
);
};
1.new IntersectionObserver를 사용하여 entries를 console로 확인한다.
2.observer의 option(threshold,rootMargin)을 넣어서 위치를 지정한다.
3.observer.observe(node)를 하여 ref를 관찰한다.
4.tag의 ref를 useCallback의 변수명으로 지정한다.
//App.jsx
const App = () => {
const [currentIndex, setCurrentIndex] = useState(-1);
return (
<Styled.Container>
{array.map((arr, index) => {
return (
<Tags
arrContent={arr.content}
setCurrentIndex={setCurrentIndex}
index={index}
isShow={index === currentIndex ? true : false}
/>
);
})}
</Styled.Container>
);
};
//Tag.jsx
const Tag = ({ arrContent, isShow, setCurrentIndex, index }) => {
const element = useCallback((node) => {
const observer = new IntersectionObserver(
(entries, observer) => {
setCurrentIndex(index);
},
{
threshold: 1,
rootMargin: "0px 0px -20px 0px",
}
);
observer.observe(node);
}, []);
return (
<div>
<Styled.Ptag
isShow={isShow}
ref={element}
style={{ transform: isShow && "scale(5)" }}
>
{arrContent}
</Styled.Ptag>
</div>
);
};
1.object가 원하는 위치에 다달했을때 setCurrentIndex(index)하여 state에 index를 넣는다.
2.state가 변하기 때문에 리렌더링된다.
3.App.jsx에서 index와 currentIndex 를 비교하여 같으면 true다르면 false를 보낸다.
4.isShow가 true일경우 scale이 커지게 style을 적용한다.