오늘은 parallax scroll에 대해 공부해보자.
먼저 리액트에서 + ts로 구현해볼것인데
useState, useEffect의 대한 공부가 필요하고 clean up함수의 대한 이해가 필요하다.
자 구현하면서 차근차근 설명해보겠다.
const [position, setPosition] = useState<number>(0);
function onScroll() {
setPosition(window.scrollY);
}
console.log(window.scrollY);
useEffect(() => {
window.addEventListener("scroll", onScroll);
return () => {
window.removeEventListener("scroll", onScroll);
};
}, []);
먼저 이 함수들을 이해해보자.
useState로 스크롤의 값을 우리는 관리 할 것이다.
또한 유즈이펙트로 윈도우에 스크롤 이벤트를 걸어 콜백함수를 등록했다.
콜백함수의 내용은 position state의 값을 setState를 통해 변경해 업데이트한다.
useEffect에서 리턴문으로 클린업함수를 쓴 이유는 무엇일까?
우리는 컴포넌트 자체에서 변화가 일어난다 .
컴포넌트가 언마운트 되어도 window에 이벤트를 걸어놨기때문에 반복적으로 함수가 호출 될 것이다.
그렇기 때문에 메모리 누수가 발생 할 수 있는 부분이다.
return () => {
window.removeEventListener("scroll", onScroll);
};
위 코드를 등록하면 컴포넌트가 언마운트 되기 직전에 이벤트가 제거된다.
위와같이 코드를 작성했다면 준비는 끝났다.
<div className="bg bg1" style={{ backgroundPositionY: position / 2 }}>
<div
style={{ fontSize: "30px", color: "white", lineHeight: "300px" }}
>
welcome
</div>
</div>
<div className="bg bg2" style={{ backgroundPositionY: position / -2 }}>
<div
style={{ fontSize: "30px", color: "white", lineHeight: "300px" }}
>
good
</div>
</div>
위와 같이 인라인스타일에서 우리는 변화를 줄 것이다.
function onScroll() {
setPosition(window.scrollY);
} 이 함수로 우리는 state의 값을 지속적으로 변경해 업데이트하고 새롭게 랜더링한다.
마운트 언마운트가 지속적으로 이루어지는 과정이다.
이 시점에서 useEffect의 콜백함수가 지속적으로 호출된다 .
backgroundPositionY: position / 2 (position은 우리가 스크롤한 값 무조건 양수) 양수기 때문에
우리가 중학교때 x,y함수좌표를 보면 y축의 양수는 위쪽방향 y축의 음수는 아랫방향인걸 기억할것이다.
즉 스크롤할때마다 위와같이 설정하면 위로 백그라운드 이미지가 올라간다.
backgroundPositionY: position / -2
음수에 양수를 곱했기때문에 -y축으로 이동
이미지가 아래쪽으로 이동한다
위와 같은 방식과 아주 비슷하다.
transform: translateX(${-position}px)
,
위와 같은 코드를 해석해보길 바란다.
-x축이기때문에 << 으로 이동
양수 x축이면 >>이동이기때문에
<p>
className="des2"
style={{
transform: `translateX(${-position}px)`,
}}
</p> // 스크롤 할 때 마다 <<방향으로 이동한다
<p>
className="des2"
style={{
transform: `translateX(${position}px)`,
}}
</p> // 스크롤 할 때 마다 >>방향으로 이동한다
<p
style={{
opacity: position - 811,
}}
</p>
위 코드를 해석하면 내가 내린 스크롤 y의 값이 812를 초과하는순간 저 p태그를 보여준다는것이다.
그렇다면 서서히 p태그가 나오게하려면?
opacity: (position - 500) / 50, 이런식으로 연산을 하면 된다.
포지션이 500일땐 opacity가 0일것이고 550일때 (550 -500) / 50 = 1
즉 550이 되어야 1이 충족되는것이기때문에 소수점자리로 천천히 나오게 될것이다.