Animation on Scroll이 있는 헤더바 만들기
나는 상단에 고정되어 있는 헤더를 좋아한다. 그렇지만 헤더 때문에 body가 출력되는 공간이 줄어드는 것은 그닥 좋아하지 않는다. (열린 교회 닫힘) 그래서 이 2가지 취향을 반영하기 위해 아래로 스크롤 시 투명해지는 헤더를 만들었다.
사전에 알아야 될 지식들
우선, CSS-in-JS와 React Hook 개념을 어느정도 숙지해야 해당 포스팅을 따라가기 쉽다. 나는 CSS-in-JS를 위해 emotion을 사용했다.
스크롤 현재 위치를 어떻게 알까
if (window.pageYOffset > 0) {
// 스크롤이 아래로 내려갔을 때
} else {
// 스크롤이 가장 최상단에 있을 때
}
아무 페이지에서 개발자 모드를 켜서 console.log(window.pageYOffset)
을 실행해보면 숫자가 출력되는 것을 확인할 수 있다. window.pageYOffset
은 현재 스크롤의 위치를 나타내는 것으로, 0이면 스크롤이 최상단인 것이고 스크롤이 내려갈 수록 그 수가 점점 커진다.
스크롤 움직임을 어떻게 알까
window.addEventListener('scroll', (event) => {
console.log('Scrolling...');
});
click이나 mouseover 등의 이벤트를 감지할 때 target.addEventListener
를 사용한다. scroll도 마찬가지이다. 위 코드를 테스트하면 스크롤바가 움직일 때마다 Scrolling...이 출력되는 것을 확인할 수 있다.
Hook을 이용한 scroll 관리
스크롤이 움직이는 것을 아는 방법과 스크롤의 현재위치를 알아내는 데까지 해냈다. 그럼 이제 이것을 잘 활용해서 scroll이 아래로 내려갔는지, 아닌지 알아내는 state를 하나 만들자.
const [isScroll, setIsScroll] = useState(false);
isScroll
이 false면 scroll이 최상단에 있는 것이고, isScroll
이 true면 scroll이 조금이라도 아래에 내려온 것이다.
useEffect 이용하기
useEffect(() => {
window.addEventListener('scroll', () => {
window.pageYOffset > 0 ?
setIsScroll(true) : setIsScroll(false)
});
}, [isScroll]);
이 경우는 isScroll
을 기억하고 있다가 update 하는 경우이다. 따라서 useEffect(func, [isScroll])
꼴로 만들어주면 된다.
emotion으로 CSS 작성하기
isScroll
의 값에 따라 CSS 값을 조정해주면 스크롤 시 애니메이션을 추가해줄 수 있다. 따라서 props에 따라 값을 조정할 수 있는 emotion을 사용해준다. (당연히 styled-component도 가능)
isScroll에 따른 불투명도 설정
const Nav = styled.nav`
position: fixed; z-index: 1;
top: 0; right: 0; left: 0;
opacity: ${props => (props.isScroll ? "0.7" : "1")};
backdrop-filter: blur(30px);
padding: 0 20px;
background: #1c2022;
display: flex; align-items: center;
height: 40px;
transition: all 0.2s ease-in-out;
`;
opacity CSS 속성은 요소의 불투명도를 설정합니다. 불투명도는 요소 뒤쪽 콘텐츠가 숨겨지는 정도로, 투명도의 반대입니다.
opacity
는 불투명도를 설정하는 CSS 속성이다. 위와 같이 하면 isScroll
이 true일 때는 0.7이 되어 투명해지고, isScroll
이 false일 때는 1이 되어 불투명해진다.
코드를 모두 합치면!
import React, { useEffect, useState } from "react";
import styled from "@emotion/styled";
const Nav = styled.nav`
position: fixed;
top: 0; right: 0; left: 0;
z-index: 1;
opacity: ${props => (props.isScroll ? "0.7" : "1")};
backdrop-filter: blur(30px);
padding: 0 20px;
background: #1c2022;
display: flex;
align-items: center;
height: 40px;
transition: all 0.2s ease-in-out;
`;
const Navbar = () => {
const [isScroll, setIsScroll] = useState(false);
useEffect(() => {
window.addEventListener('scroll', () => {
window.pageYOffset > 0 ?
setIsScroll(true) : setIsScroll(false)
});
}, [isScroll]);
return (
<div>
<Nav isScroll={isScroll} />
</div>
);
};
export default Navbar;
해당 포스팅에서 언급한 스크롤 애니메이션에 필요한 최소한의 코드는 위와 같다. 여기에 이제 살을 붙이면 헤더바 뚝딱이다. 히히.
레퍼런스
- https://github.com/jus0k/scroll-hooks
- https://www.javascripttutorial.net/javascript-dom/javascript-scroll-events/
- https://ko.reactjs.org/docs/hooks-reference.html#usecallback
- https://developer.mozilla.org/ko/docs/Web/CSS/opacity
Author And Source
이 문제에 관하여(Animation on Scroll이 있는 헤더바 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@1998yuki0331/Animation-on-Scroll이-있는-헤더바-만들기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)