• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    해결됨

안녕하세요 '현재 활성시킬 씬 결정하기' 강좌편에서 문의가 있습니다.

20.07.19 16:51 작성 조회수 142

0

안녕하세요 다름이 아니라 해당 '현재 활성시킬 씬 결정하기' 에서 코드를 입력하고 있는데 원하는 위치 스크롤 보다 400픽셀 앞에서 currentScene 변수가 변경하고 있어서 질문 드립니다. 아무리 확인해도 문제가 되는 부분이 없는거 같은데 확인 부탁드립니다.

index. html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>AirMug Pro</title>
    <link
      href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;900&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="css/main.css" />
  </head>
  <body id="">
    <div class="contaner">
      <nav class="global-nav">
        <div class="global-nav-links">
          <a href="#" class="global-nav-item">Room</a>
          <a href="#" class="global-nav-item">Ideas</a>
          <a href="#" class="global-nav-item">Stores</a>
          <a href="#" class="global-nav-item">Contact</a>
        </div>
      </nav>
      <nav class="local-nav">
        <div class="local-nav-links">
          <a href="#" class="product-name">AirMug Pro</a>
          <a href="#">개요</a>
          <a href="#">제품사양</a>
          <a href="#">구입하기</a>
        </div>
      </nav>
      <section class="scroll-section" id="scroll-section-0">
        <h1>AirMug Pro</h1>
        <div class="sticky-elem main-message">
          <p>온전히 빠져들게 하는<br />최고급 세라믹</p>
        </div>
        <div class="sticky-elem main-message">
          <p>주변 맛을 느끼게 해주는<br />주변 맛 허용 모드</p>
        </div>
        <div class="sticky-elem main-message">
          <p>온중일 편안한<br />맞춤형 손잡이</p>
        </div>
        <div class="sticky-elem main-message">
          <p>새롭게 입가를<br />찾아온 매혹</p>
        </div>
      </section>
      <section class="scroll-section" id="scroll-section-1">
        <p class="description">
          <strong>
            보통 스크롤 영역
          </strong>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Ullam, soluta
          quia? Soluta repellat consequatur aliquam sit deleniti atque qui nemo,
          molestiae, veritatis repudiandae, earum tempora mollitia dolores? Ipsa
          a ea ab nostrum ullam beatae, natus, nulla recusandae praesentium
          corporis magni, atque impedit error aliquid consequatur. Culpa
          cupiditate velit molestias sapiente! Aspernatur molestiae facilis
          repudiandae, fugiat nulla, hic culpa esse impedit eos, quam sapiente?
          Laboriosam ut perferendis atque velit sint, non mollitia? Provident
          cum obcaecati ex illo asperiores accusantium harum voluptas doloremque
          inventore possimus eum tenetur tempora ipsam debitis natus nulla
          similique veritatis recusandae, voluptatum accusamus quia adipisci
          perspiciatis. Itaque architecto eius veritatis rem quae facere illo
          ipsum error, explicabo nesciunt eos quibusdam dolorem magni impedit,
          magnam amet voluptates fugit assumenda deserunt consequuntur numquam.
          Quasi hic nisi molestias enim fugiat vel eveniet modi quisquam
          suscipit? Recusandae voluptates expedita exercitationem excepturi
          velit repellat error similique porro deleniti architecto tenetur
          quaerat corporis culpa, libero, neque facilis ullam eius reiciendis
          itaque et fugiat eum! Magnam totam at commodi nesciunt, quae dolores,
          praesentium labore, maxime perspiciatis iure omnis sed assumenda
          laborum harum. Dolor, voluptatem id. Eos qui, quidem assumenda sit
          asperiores quia beatae consequuntur necessitatibus dignissimos
          architecto, aspernatur facere ut porro cum repellat. Tempora, minima?
        </p>
      </section>
      <section class="scroll-section" id="scroll-section-2">
        <div class="sticky-elem main-message">
          <p>
            <small>
              편안한 촉감
            </small>
            입과 하나 되다
          </p>
        </div>
        <div class="sticky-elem desc-message">
          <p>
            편안한 목넘김을 완성하는 디테일한 여러 구성 요소들, 우리는 이를
            하나하나 새롭게 살피고 재구성하는 과정을 거쳐 새로운 수준의 머그,
            AirMug Pro를 만들었습니다. 입에 뭔가 댔다는 감각은 어느새 사라지고
            오롯이 당신과 음료만 남게 되죠.
          </p>
          <div class="pin"></div>
        </div>
        <div class="sticky-elem desc-message">
          <p>디자인 앤 퀄리티 오브 스웨덴,<br />메이드 인 차이나</p>
          <div class="pin"></div>
        </div>
      </section>
      <section class="scroll-section" id="scroll-section-3">
        <p class="mid-message">
          <strong>Retina 머그</strong><br />
          아이디어를 광활하게 펼칠<br />
          아름답고 부드러운 음료 공간.
        </p>
        <!-- <canvas class="image-blend-canvas" width="1920" height="1080"></canvas> -->
        <p class="canvas-caption">
          Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet at
          fuga quae perspiciatis veniam impedit et, ratione est optio porro.
          Incidunt aperiam nemo voluptas odit quisquam harum in mollitia.
          Incidunt minima iusto in corporis, dolores velit. Autem, sit dolorum
          inventore a rerum distinctio vero illo magni possimus temporibus
          dolores neque adipisci, repudiandae repellat. Ducimus accusamus
          similique quas earum laborum. Autem tempora repellendus asperiores
          illum ex! Velit ea corporis odit? Ea, incidunt delectus. Sapiente
          rerum neque error deleniti quis, et, quibusdam, est autem voluptate
          rem voluptas. Ratione soluta similique harum nihil vel. Quas inventore
          perferendis iusto explicabo animi eos ratione obcaecati.
        </p>
      </section>
      <footer class="footer">
        2020, 1분코딩
      </footer>

      <script src="js/main.js"></script>
    </div>
  </body>
</html>

main.js

(() => {
  let yOffset = 0; // window.pageYOffset 대신 쓸 변수
  let prevScrollHeight = 0; // 현재 스크롤 위치(yOffSet)보다 이전에 위치한 스킄롤 섹션들의 스크롤 높이값의 합
  let currentScene = 0; // 현재 활성화된 (눈앞에 보고 있는) 씬(scroll-section)

  const sceneInfo = [
    {
      // 0
      type: "sticky",
      heightNum: 5, // 브라우저 높이의 5배로 scrollHeght 세팅
      scrollHeight: 0,
      objs: {
        container: document.querySelector("#scroll-section-0"),
      },
    },
    {
      // 1
      type: "normal",
      heightNum: 5, // 브라우저 높이의 5배로 scrollHeght 세팅
      scrollHeight: 0,
      objs: {
        container: document.querySelector("#scroll-section-1"),
      },
    },
    {
      // 2
      type: "sticky",
      heightNum: 5, // 브라우저 높이의 5배로 scrollHeght 세팅
      scrollHeight: 0,
      objs: {
        container: document.querySelector("#scroll-section-2"),
      },
    },
    {
      // 3
      type: "sticky",
      heightNum: 5, // 브라우저 높이의 5배로 scrollHeght 세팅
      scrollHeight: 0,
      objs: {
        container: document.querySelector("#scroll-section-3"),
      },
    },
  ];

  /**
   * 각 씬 마다의 섹션 높이값 지정
   */
  function setLayout() {
    // 각  스크롤 섹션의 높이 저장
    for (let i = 0; i < sceneInfo.length; i++) {
      sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight;
      sceneInfo[
        i
      ].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`;
    }
  }

  /**
   * 현재 보고 있는 화면에서 스크롤 높이 구하기
   */
  function scrollLoop() {
    prevScrollHeight = 0;
    for (let i = 0; i < currentScene; i++) {
      prevScrollHeight = prevScrollHeight + sceneInfo[i].scrollHeight;
    }

    if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) {
      currentScene++;
    }

    if (yOffset < prevScrollHeight) {
      if (currentScene === 0) {
        // 브라우저 바운스 효과로 인한 마이너스가 되는것을 방지 (모바일)
        return;
      }
      currentScene--;
    }

    console.log(currentScene);
  }

  window.addEventListener("resize", setLayout);
  window.addEventListener("scroll", () => {
    yOffset = window.pageYOffset;
    scrollLoop();
  });
  setLayout();
})();

main.css

@charset 'utf-8';

html {
  font-family: "Noto Sans KR", sans-serif;
  font-size: 14px;
}

body {
  overflow-x: hidden;
  color: rgb(29, 29, 31);
  letter-spacing: -0.05em;
  background: white;
  margin: 0;
}

p {
  line-height: 1.6;
}
a {
  color: rgb(29, 29, 31);
  text-decoration: none;
}
.global-nav {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 44px;
  padding: 0 1rem;
}
.local-nav {
  position: absolute;
  top: 45px; /* .global-nav 보다 1px 위에 */
  left: 0;
  width: 100%;
  height: 52px;
  border-bottom: 1px solid #ddd;
}
.global-nav-links,
.local-nav-links {
  display: flex;
  align-items: center;
  max-width: 1000px;
  height: 100%;
  margin: 0 auto;
}
.local-nav-links a:not(.product-name) {
  margin-left: 2em;
}
.local-nav-links .product-name {
  margin-right: auto;
  font-size: 1.4rem;
  font-weight: bold;
}
.local-nav-links a {
  font-size: 0.8rem;
}
.global-nav-links {
  justify-content: space-between;
}

/*  */
.scroll-section {
  position: relative;
  border: 3px solid red;
  padding-top: 50vh;
}
#scroll-section-0 h1 {
  position: relative;

  font-size: 4rem;
  text-align: center;
}
.main-message {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 5px 0;
  height: 3em;
  font-size: 2.5rem;
}
.main-message p {
  font-weight: bold;
  text-align: center;
  line-height: 1.2;
}
/*  */
.main-message small {
  display: block;
  margin-bottom: 0.5em;
  font-size: 1.2rem;
}
#scroll-section-2 .main-message {
  font-size: 3.5rem;
}
.description {
  font-size: 2rem;
  max-width: 1000px;
  padding: 0 1rem;
  font-size: 1.2rem;
  color: #888;
}
.description strong {
  float: left;
  margin-right: 0.2em;
  font-size: 3rem;
  color: rgb(29, 29, 31);
}
.desc-message {
  font-weight: bold;
  width: 50%;
}
.pin {
  width: 1px;
  height: 100px;
  background-color: rgb(29, 29, 31);
}

.mid-message {
  padding: 0 1rem;
  font-size: 2rem;
  color: #888;
  max-width: 1000px;
  margin: 0 auto;
}
.mid-message strong {
  color: rgb(29, 29, 31);
}
.canvas-caption {
  color: #888;
  padding: 0 1rem;
  font-size: 1.2rem;
  max-width: 1000px;
  margin: 0 auto;
}

.footer {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 7rem;
  color: white;
  background-color: darkorange;
}

@media (min-width: 1024px) {
  #scroll-section-0 h1 {
    font-size: 9vw;
  }
  .main-message {
    font-size: 4vw;
  }
  .description {
    margin: 0 auto;
  }
  .description strong {
    font-size: 6rem;
  }
  #scroll-section-2 .main-message {
    font-size: 6vw;
  }
  .main-message small {
    font-size: 1.5vw;
  }
  .desc-message {
    width: 20%;
  }
  .mid-message {
    font-size: 4vw;
  }
  .canvas-caption {
    font-size: 2rem;
  }
}

/*  */
.sticky-elem {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}
#show-scene-0 #scroll-section-0 .sticky-elem,
#show-scene-1 #scroll-section-1 .sticky-elem,
#show-scene-2 #scroll-section-2 .sticky-elem,
#show-scene-3 #scroll-section-3 .sticky-elem {
  display: block;
}

답변 2

·

답변을 작성해보세요.

1

index.html에 default.css를 연결하는 부분이 빠져있습니다^^

<link rel="stylesheet" href="css/default.css" />
<link rel="stylesheet" href="css/main.css" />

.scroll-section에는 기본적으로 padding-top: 50vh; 이 적용되어있는데,
default.css의 31번째 줄을 보시면
모든 section에 box-sizing: border-box; 를 세팅하는 부분이 있거든요.
그 부분이 적용이 안되어서
box-sizing이 기본값인 content-box로 적용되어 padding-top: 50vh가 scroll-section의 높이에 더해져서
그 부분이 반영된 거랍니다.
차이가 400px이라고 하셨으니 아마 사용하고 계신 기기의 브라우저 높이가 800px 정도 되는 것 같네요~


0

피드벡 감사합니다. ㅠㅠㅠㅠ