출처: iEatWebsites  https://youtu.be/4OcAAj8aqS8

 

오늘은 애플 홈페이지 처럼 스크롤에 따라 이미지가 변하는 효과를 따라해봤다.

사실 프론트엔드에 관심을 갖게된 것도 애플 홈페이지를 보고 막연히 똑같이 만들어보고 싶다에서 시작한거다.

그만큼 관심이 많다.

따라해보긴 했는데 이건 퍼블리셔의 영역인가.. 프론트엔드의 영역인가.. 아님 둘다인가.. 아직 잘 모르겠다.

암튼 나중에 꼭 애플 홈페이지 같은 페이지를 만들고 싶다.

 

소스코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fancy Scrolling Animation</title>

    <style>
      html {
        height: 100vh;
      }

      body {
        background-color: #000;
        height: 400vh;
      }

      canvas {
        position: fixed;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        max-height: 100vh;
        max-width: 100vw;
      }

      div {
        position: relative;
        top: 600vh;
        width: 100%;
        height: 500vh;
      }

      div h1 {
        color: #fff;
        font-size: 80px;
        text-align: center;
        letter-spacing: 60px;
      }
    </style>
  </head>
  <body>
    <canvas class="airpods-scrolling"></canvas>

    <div>
      <h1>AIRPODS PRO</h1>
    </div>

    <script>
      const html = document.documentElement;
      const canvas = document.querySelector('.airpods-scrolling');
      const context = canvas.getContext('2d');

      const currentFrame = (index) =>
        `https://www.apple.com/105/media/us/airpods-pro/
        2019/1299e2f5_9206_4470_b28e_08307a42f19b/anim/sequence/
        large/01-hero-lightpass/${index.toString().padStart(4, '0')}.jpg`;

      const frameCount = 147;

      canvas.height = 770;
      canvas.width = 1158;

      const img = new Image();
      img.src = currentFrame(1);
      img.onload = () => {
        context.drawImage(img, 0, 0);
      };

      const updateImage = (index) => {
        img.src = currentFrame(index);
        context.drawImage(img, 0, 0);
      };

      window.addEventListener('scroll', () => {
        const scrollTop = html.scrollTop;
        const maxScrollTop = html.scrollHeight - window.innerHeight;
        const scrollFraction = scrollTop / maxScrollTop;
        const frameIndex = Math.min(frameCount - 1, Math.floor(scrollFraction * frameCount));

        requestAnimationFrame(() => updateImage(frameIndex + 1));
      });

      const preloadImages = () => {
        for (let i = 0; i < frameCount; i++) {
          const img = new Image();
          img.src = currentFrame(i);
        }
      };
      preloadImages();
    </script>
  </body>
</html>

 

구현결과

이걸 엄청 구현하고 싶었다. 따라해봤으니 이제 내껄로 만들어야지

+ Recent posts