50 Project In 50 Days-Scroll Animation

ParkbossΒ·2025λ…„ 9μ›” 2일

50 Project In 50 Days

λͺ©λ‘ 보기
5/8
<!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>Scroll Animation</title>
  </head>
  <body>
    <h1>scroll to see the animtation</h1>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <div class="box"><h2>content</h2></div>
    <script src="script.js"></script>
  </body>
</html>

* {
  box-sizing: border-box;
}

body {
  background-color: #efedd6;
  font-family: 'Roboto', sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 0;
}
h1 {
  margin: 10px;
}
.box {
  background-color: steelblue;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 400px;
  height: 200px;
  margin: 10px;
  border-radius: 10px;
  box-shadow: 2px 4px 5px rgba(0, 0, 0, 0.3);
  transform: translateX(400%);
  transition: transform 0.4s ease;
}
.box:nth-of-type(even) {
  transform: translateX(-400%);
}
.box.show {
  transform: translateX(0);
}

.box h2 {
  font-size: 45px;
}


const boxes = document.querySelectorAll('.box');

window.addEventListener('scroll', checkBoxes);
checkBoxes();
function checkBoxes() {
  const triggerBottom = (window.innerHeight / 5) * 4;

  boxes.forEach((box) => {
    const boxTop = box.getBoundingClientRect().top;

    if (boxTop < triggerBottom) {
      box.classList.add('show');
    } else {
      box.classList.remove('show');
    }
  });
}

πŸ“Œ 이 μ½”λ“œμ˜ μ—­ν• 

πŸ‘‰ νŽ˜μ΄μ§€λ₯Ό μŠ€ν¬λ‘€ν•  λ•Œ λ°•μŠ€(.box)κ°€ 화면에 λ“€μ–΄μ˜€λ©΄ μ• λ‹ˆλ©”μ΄μ…˜μ²˜λŸΌ λ‚˜νƒ€λ‚˜κ²Œ ν•΄μ£ΌλŠ” μ½”λ“œμ˜ˆμš”.
(즉, μŠ€ν¬λ‘€ν•  λ•Œ λ°•μŠ€κ°€ μŠ¬λΌμ΄λ“œλ˜λ©΄μ„œ λ³΄μ΄λŠ” 효과 🎬)

πŸ”Ž μ½”λ“œ μ„€λͺ…
1. .boxλΌλŠ” μš”μ†Œλ“€ κ°€μ Έμ˜€κΈ°
const boxes = document.querySelectorAll('.box');

HTMLμ—μ„œ <div class="box"> 이런 λ°•μŠ€λ₯Ό μ „λΆ€ μ°Ύμ•„μ„œ boxes에 μ €μž₯.

μ—¬λŸ¬ κ°œλ‹ˆκΉŒ λ°°μ—΄ 같은 덩어리(NodeList) 둜 λͺ¨μ•„짐.

  1. 슀크둀 이벀트 κ°μ§€ν•˜κΈ°
    window.addEventListener('scroll', checkBoxes);

μ‚¬μš©μžκ°€ μŠ€ν¬λ‘€ν•  λ•Œλ§ˆλ‹€ checkBoxes() ν•¨μˆ˜λ₯Ό μ‹€ν–‰μ‹œν‚΄.

즉, 슀크둀 움직일 λ•Œλ§ˆλ‹€ λ°•μŠ€κ°€ 화면에 λ“€μ–΄μ™”λŠ”μ§€ 확인.

  1. μ²˜μŒμ—λ„ ν•œ 번 μ‹€ν–‰
    checkBoxes();

슀크둀 μ•ˆ 해도 처음 λ‘œλ”©λ  λ•Œ ν•œ 번 μ‹€ν–‰ β†’ 화면에 λ³΄μ΄λŠ” λ°•μŠ€λŠ” λ°”λ‘œ λ‚˜νƒ€λ‚˜λ„λ‘ 함.

  1. checkBoxes ν•¨μˆ˜
    function checkBoxes() {
    const triggerBottom = (window.innerHeight / 5) * 4;

window.innerHeight = ν˜„μž¬ ν™”λ©΄(λΈŒλΌμš°μ € μ°½)의 높이

/ 5 * 4 β†’ ν™”λ©΄ λ†’μ΄μ˜ 80% μœ„μΉ˜ 지점을 계산

즉, "ν™”λ©΄ μ•„λž˜μ—μ„œ 20% 남은 지점"을 기쀀점(triggerBottom)으둜 μ„€μ •

  1. λͺ¨λ“  λ°•μŠ€ ν™•μΈν•˜κΈ°
    boxes.forEach((box) => {
    const boxTop = box.getBoundingClientRect().top;

getBoundingClientRect().top = λ°•μŠ€μ˜ μœ—λΆ€λΆ„μ΄ ν™”λ©΄μ˜ μ–΄λ””μ―€ μžˆλŠ”μ§€ μ•Œλ €μ€Œ
(μˆ«μžκ°€ μž‘μœΌλ©΄ ν™”λ©΄ μœ„μͺ½, 크면 ν™”λ©΄ μ•„λž˜μͺ½μ— μžˆλ‹€λŠ” 뜻)

  1. 쑰건문으둜 클래슀 μΆ”κ°€/μ‚­μ œ
    if (boxTop < triggerBottom) {
    box.classList.add('show');
    } else {
    box.classList.remove('show');
    }

λ°•μŠ€μ˜ top μœ„μΉ˜κ°€ 기쀀점(triggerBottom)보닀 μœ„μͺ½μ— 있으면 β†’ 화면에 μΆ©λΆ„νžˆ λ“€μ–΄μ™”μœΌλ‹ˆ .show 클래슀 λΆ™μž„

아직 화면에 μ•ˆ λ“€μ–΄μ™”μœΌλ©΄ .show 클래슀 제거

πŸ‘‰ CSSμ—μ„œ .show에 μ• λ‹ˆλ©”μ΄μ…˜(μŠ¬λΌμ΄λ“œ/νŽ˜μ΄λ“œ λ“±)을 κ±Έμ–΄λ†“μ•˜κΈ° λ•Œλ¬Έμ—, μŠ€ν¬λ‘€ν•˜λ©΄μ„œ λ°•μŠ€κ°€ λ‚˜νƒ€λ‚˜λŠ” νš¨κ³Όκ°€ λ‚˜λŠ” 것!

πŸ–ΌοΈ λΉ„μœ λ‘œ μ„€λͺ…

화면을 λ¬΄λŒ€λΌκ³  μƒκ°ν•΄μš” 🎭

triggerBottom은 "λ¬΄λŒ€ μœ„λ‘œ 올라였기 직전 라인"

λ°•μŠ€(.box)κ°€ κ·Έ 라인을 λ„˜μ–΄μ„œλ©΄ μ‘°λͺ…이 μΌœμ§€κ³ (show 클래슀 μΆ”κ°€) κ΄€κ°μ—κ²Œ λ³΄μ΄λŠ” 것

λ¬΄λŒ€ 밖에 있으면 λ‹€μ‹œ μ‘°λͺ…이 꺼짐(show 제거)

profile
ur gonna figure it out. just like always have.

0개의 λŒ“κΈ€