[HTML, CSS, JS]스크롤 애니메이션, 스크롤 내리면 스크롤 위치 퍼센트 보여주기

김범기·2024년 6월 27일
0

개요

스크롤 애니메이션 감을 다시 익히기 위해서 간단하게 익혀보는 시간을 가졌다.

만들기

html

html에는 아래처럼 구성을 했다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Scroll Loading</title>
  <link rel="stylesheet" href="./scroll_loading.css">
</head>
<body>
  <div>
    <div id="char_div">
      <h1 class="text-center">스크롤 로딩 화면 띄우기</h1>
      <p class="text-center">스크롤을 내리면 0% 에서 100%까지 변경됩니다.</p>
    </div>
    <div class="loading-div">
      <div class="loading-box">
        <div class="loading-color" id="loading_color"></div>
      </div>
      <p class="text-center" id="scroll_percentage">0%</p>
    </div>
  </div>
  <script src="./scroll_loading.js"></script>
</body>
</html>

여기서

char_div: 내가 스크롤을 내리면서 확인하게 될 내용들.
loading-div: 스크롤에 따른 위치를 %로 로딩바처럼 구현을 하는 곳.

으로 구현을 했다.

loading-div안에서 2가지로 div태그인 loading-box는 로딩의 시각화를, p태그인 scroll_percentage는 정확히 몇 퍼센트인지를 보여주기 위해 사용했다.

css

css는 아래처럼 구현을 했다.

특별한 것은 없고,
스크롤에 따른 로딩바처럼 보이게 하기 위해 .loading-div 안에서 작동하는 .loadin-box로 로딩화면이 보여질 박스의 틀을 구현해주고, .loading-color를 통해 %에 따라 로딩의 진척도를 시각적으로 보여주도록 했다.

linear-gradient를 통해서 더욱 로딩이 채워지는 느낌을 구현하고자 했다.

또한 스크롤을 움직이더라도 언제나 항상 같은 위치에 존재해야했기에 이번에는

position: fixed;

를 이용해서 진행했다.

또한 위치를 중앙으로 배치하기 위해 top과 left를 각 div의 크기 절반을 50% 에서 뺀 만큼을 주었다.

.text-center{
  text-align: center;
}
.letter{
  font-size: 2rem;
  font-weight: 800;
}
.loading-div{
  position: fixed;
  top: calc(50% - 2.5vh);
  left: calc(50% - 30vw);
}
.loading-box{
  width: 60vw;
  height: 5vh;
  border: 1px solid #000000;
}
.loading-color{
  height: 100%;
  width: 0%;
  background: linear-gradient(to right, #01ff41, #1f40ff);
}

JS

자바스크립트에서는 아래처럼 코드를 작성했다.

const char_div = document.getElementById("char_div")

const koreanLetters = '가나다라마바사아자차카타파하게네데레메베세에제체케테페헤기니디리미비시이지치키티피히고노도로모보소오조초코토포호구누두루무부수우주추쿠투푸후ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

for (let i = 0; i < koreanLetters.length; i++) {
  const letter = koreanLetters[i]
  const pTag = document.createElement('p')
  pTag.innerText = letter
  pTag.classList.add('letter')
  char_div.appendChild(pTag)
}

//스크롤 퍼센트값 계산
const scroll_percentage = document.getElementById('scroll_percentage')
const loading_color = document.getElementById('loading_color')

const scrollYPoistion = () => {
  const totalHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  const currentScroll = window.scrollY;
  let percent = Math.ceil((currentScroll / totalHeight) * 100);
  if(percent >= 100){
    percent = 100
  }
  console.log(percent)
  scroll_percentage.innerText = `${percent}%`
  loading_color.style.width = `${percent}%`
}

window.addEventListener("scroll", scrollYPoistion);

koreanLetters는 앞선 html코드에서 char_div 아래에 들어갈 내용이다.

그리고 스크롤 퍼센트 값을 계산하는 부분에서 잘 되었지만, 글자 수에 따라 즉, 전체 높이에 따라서 100%가 되지 않고, 99%가 되는 경우가 있었다.

이를 해결하기 위해 기존의

let percent = Math.floor((currentScroll / totalHeight) * 100);

대신

let percent = Math.ceil((currentScroll / totalHeight) * 100);

을 이용해서 진행하니 해결되었다.

스크롤 퍼센트값 계산

스크롤 퍼센트값 계산 부분을 더 들여다보면

//스크롤 퍼센트값 계산
const scroll_percentage = document.getElementById('scroll_percentage')
const loading_color = document.getElementById('loading_color')

const scrollYPoistion = () => {
  const totalHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  const currentScroll = window.scrollY;
  let percent = Math.ceil((currentScroll / totalHeight) * 100);
  if(percent >= 100){
    percent = 100
  }
  console.log(percent)
  scroll_percentage.innerText = `${percent}%`
  loading_color.style.width = `${percent}%`
}

window.addEventListener("scroll", scrollYPoistion);

scrollYPoistion()을 통해서 값을 계산하는 함수를 만들었다.

전체 웹페이지의 높이
document.documentElement.scrollHeight

현재 브라우저 창에 보이는 웹 페이지의 높이
document.documentElement.clientHeight

를 이용해서 totalHeight를 구했다. 왜 현재 브라우저 창에 보이는 웹 페이지의 높이를 뺐냐면, 스크롤은 내가 보고 있는 페이지 상단을 기준으로 하기 때문에, 그 아래의 높이는 더 필요가 없기 때문이다.

그리고 퍼센트 값을 구하기 위해 현재의 스크롤 위치를 currentScroll 변수에담고, 이를 이용해서

let percent = Math.ceil((현재스크롤 위치 / 전체길이(이건 아까말한 실 스크롤 길이)) * 100);

로 구했다.
또한 ceil을 이용했기에 혹시라도 있을 오류를 방지하기 위해 percet가 100 이상일 경우 100으로 정한다는 것을 한 번 더 명시했다.

완성

깃허브로 코딩보기

profile
반드시 결승점을 통과하는 개발자

0개의 댓글