One-Page-Scroll 구현하기

박효정·2023년 11월 6일

TIL

목록 보기
11/13

One Page Scroll을 구현해보며 이해해보자! 라는 마음에서 시작해보는 애니메이션 구현입니다요..


원 페이지 스크롤

말 그대로 하나의 페이지에서 스크롤 이벤트를 통해 애니메이션 효과를 주는 기능입니다. 좋아하는 애니메이션 중에 하나인데 이렇게 디자인을 하면 이목을 집중시키는 효과가 있습니다. (없다구요? 아녜요 이써요 무튼그럼)

//html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>One-Page-Scroll</title>
</head>
<body>
  <div class="wrap">
    <div class="container">안녕하세요?</div>
    <div class="container">원페이지스크롤 입니다.</div>
    <div class="container">어때요</div>
    <div class="container">괜찮나요?</div>
  </div>
  <script type="text/javascript" src="script.js"></script>
</body>
</html>

보여주려고 하는 텍스트나 이미지 등등을 섹션단위로 나누어서 구성해줍니다.

//css
html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  font-size: 3rem;
}

.wrap {
  position: relative;
  top: 0;
  width: 100%;
  height: 100%;
  transition: 0.5s;
}

.container {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  /* flex 로 정렬시키고 싶은 요소가 있으면 해당 요소의 부모 요소에 flex 걸기 */
}

.container:nth-child(1){background-color: lightblue;}
.container:nth-child(2){background-color: lightcoral;}
.container:nth-child(3){background-color: lightgreen;}
.container:nth-child(4){background-color: lightpink;}

이후에 빈틈이 없도록 margin, padding, border를 0으로 설정해줍니다. 그리고 모든 width 와 height 를 100% 로 지정해 화면에 꽉 차도록 설정합니다.
그리고 wrap 클래스에서 transition 을 설정하여 스크롤 이벤트가 발생할 때 애니메이션의 속도를 지정하여 넘어가는 느낌을 주는 것이 뽀인뜨 입니다.
또, 저는 텍스트를 각 div 에 넣어서 수직, 수평 정렬을 해주고 싶었기에 해당하는 요소를 감싸고 있는 바깥 요소에 flex 속성을 추가해주었습니다.

//javascript
const wrap = document.getElementsByClassName('wrap')[0];
const container = document.getElementsByClassName('container');
let page = 0;
const lastPage = container.length - 1;

window.addEventListener('wheel', (event) => {
  event.preventDefault(); // 새로고침 막기
  // deltaY -> 상하 스크롤량 반환 (읽기 전용 속성, 최신브라우저 지원 사파리X)
  if(event.deltaY > 0){
    page++;
  }
  if(event.deltaY < 0){
    page--;
  }
  if(page < 0){
    page = 0;
  }
  if(page > lastPage){
    page = lastPage;
  }
  console.log(event.deltaY);
  wrap.style.top = page * -100 + 'vh';
  // wrap 클래스에 있는 css top 속성값을 변경시키는 코드
  // 현재 보여지는 페이지에 따라서 +- 100vh 를 이동시킨다.
}, {passive: false}); // passive 디폴트 기능 제거 - 스크롤

여기서는 wrap 클래스, container 클래스가 가리키는 요소를 변수로 선언해주고 0으로 초기화된 페이지와 마지막 페이지(전체 컨테이너 개수 - 1) 로 스크롤 이벤트를 구현해줍니다.

여기서 새롭게 알게된 속성인 deltaY 는

상하 스크롤량 반환 - 최신브라우저 지원(사파리 예외), 읽기전용

인 특성을 가지고 있기에 이 코드에서는 스크롤 할 때의 얼마나 스크롤을 발생시키는 지를 감지할 수 있습니다. 따라서 0 초과의 스크롤량일 경우 아래로 내린 스크롤이고 0 미만일 경우는 위로 올린 스크롤이라고 볼 수 있습니다.
아래로 내린 스크롤이면 페이지를 증가시키고 위로 올린 스크롤이면 페이지를 감소시킵니다. 증감 처리가 된 페이지가 0보다 작거나 마지막 페이지보다 클 경우에는 각각 0과 마지막페이지로 매칭 시켜줍니다.

이렇게 몇 번째 페이지인지 파악하게 되면 wrap 변수(클래스 요소)의 css top 속성에서 100vh 를 빼거나 추가하여 기본 top: 0 에서 보여지는 위치를 바꾸어 줄 수 있습니다.
(만약에 top 을 100vh 으로 초기화하면 아래로 스크롤을 내릴 때 세번째 섹션을 보여줍니다.)

참고 블로그

결과

profile
코린이 일기장

0개의 댓글