JSFiddle - React, Tailwind, and code Playground

by suhyunified

HTML

<!DOCTYPE html>
<html lang="en">
  <link rel="stylesheet" href="./index.css" />
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="video-section">
      <div id="video-wrapper">
        <div class="title-wrapper">
          <h1 class="title first hidden transition-duration">
            완전히 차원이 다른<br />
            토스의 새로운 얼굴
          </h1>
        </div>
        <div class="title-wrapper second">
          <h1 class="title second-1">자유롭게,</h1>
          <h1 class="title second-2">유연하게,</h1>
          <h1 class="title second-3">대담하게.</h1>
        </div>
        <video id="video" type="video/mp4"></video>
      </div>
    </div>
  </body>
  <script>
    let loaded = false;
    const videoPlayBack = 380;
    const videoEnding = 3000;
    const videoElement = document.getElementById("video");
    const videoSection = document.getElementById("video-section");
    const firstTitle = document.querySelector(".title.first");
    const secondTitle1 = document.querySelector(".title.second-1");
    const secondTitle2 = document.querySelector(".title.second-2");
    const secondTitle3 = document.querySelector(".title.second-3");
    const secondTitleWrapper = document.querySelector(".title-wrapper.second");

    const startInitialAnimation = (element) => {
      element.classList.remove("hidden");
      setTimeout(() => {
        element.classList.remove("transition-duration");
        loaded = true;
      }, 2000);
    };

    const handleScroll = (video) => {
      if (!loaded) window.scrollTo(0, 0);

      videoElement.currentTime =
        (window.scrollY - videoSection.offsetTop) / videoPlayBack;

      const ANIMATION_GAP = 600;
      const firstTitleFadeOutStartY = 600;
      const firstTitleFadeOutEndY = firstTitleFadeOutStartY + ANIMATION_GAP;

      if (window.scrollY <= firstTitleFadeOutStartY) {
        firstTitle.style.opacity = 1;
      }...

CSS

* {
  margin: 0;
  padding: 0;
}


body {

  font-family: "Pretendard Variable", Pretendard, -apple-system, sans-serif;

  overflow-x: hidden;
}

#video-section {
  position: relative;
  background-color: black;
}

#video-wrapper {
  position: sticky;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

#video-wrapper video {
  width: 100%;
}

.title-wrapper {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  transform: translate(-50%, -50%);
}

h1.second-1,
h1.second-2,
h1.second-3 {
  opacity: 0;
  transform: translate(0, 70px);
}

.title {
  font-size: 65px;
  font-weight: 800;
  color: white;
  width: 100%;
  text-align: center;
  word-break: keep-all;
}

h1.transition-duration {
  transition: 2s ease-out;
}

h1.hidden {
  opacity: 0;
  transform: translate(0, 70px);
}

@media (max-width: 640px) {
  h1.title {
    font-size: 36px;
  }
}

@media (max-width: 934px) {
  #video-wrapper {
    align-items: normal;
    justify-content: center;
  }
  #video-wrapper video {
    width: auto;
    height: 100%;
  }
}