Search code examples
javascripthtmlcssanimate-on-scroll

Background video animates on scrolling frustration


I'm about to make a website that I want to have a video background that advances only on page scrolling. I had found a solution at the start of the year but no matter how much I search or keyword searches for it again and failed miserably.

I remember it involved creation in After Effects and saving each frame as jpg, and how to code it in html5/css/js.

Any help would be gratefully received.


Solution

  • making a div at top as bound element to check the distance when scrolling.

    inside function scrollVideo i am checking if the video has played before.

    using getBoundingClientRect().top:which returns value of a DOMRect object which is the smallest rectangle which contains the entire element, including its padding and border-width.Read More About it.

    getting percentScrolled with (window.scrollY - distanceFromTop) / (bound.scrollHeight - window.innerHeight). it may return a float value i.e. decimals. that's why i am performing math.min & math.max on it. getting currenTime with video.duration * percentScrolled & requesting animation on it.

    NOTE* video should be in webm format. i have'nt tested it in any other format.

    Actual Video Link

    const registerVideo = (bound, video) => {
      bound = document.querySelector(bound);
      video = document.querySelector(video);
      const scrollVideo = () => {
        if (video.duration) {
          const distanceFromTop = window.scrollY + bound.getBoundingClientRect().top;
          const rawPercentScrolled = (window.scrollY - distanceFromTop) / (bound.scrollHeight - window.innerHeight);
          const percentScrolled = Math.min(Math.max(rawPercentScrolled, 0), 1);
    
          video.currentTime = video.duration * percentScrolled;
        }
        requestAnimationFrame(scrollVideo);
      }
      requestAnimationFrame(scrollVideo);
    }
    
    
    registerVideo("#bound", "#bound video");
    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
      font-family: sans-serif;
      font-size: 1.4rem;
    }
    
    #bound {
      background: #d0d8db;
    }
    
    .scroll-bound {
      height: 500vh;
    }
    
    .content {
      height: 100vh;
      width: 100%;
      position: sticky;
      top: 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    
    video {
      width: 80%;
    }
    
    
    }
    <div id="bound" class="scroll-bound">
      <div class="content">
        <p>Video on Scroll</p>
        <video width="600" muted preload>
                    <source src="https://cdn.ananaspizza.de/file/malte-image-store/v9-webm.webm" type="video/webm">
                    <p>Your user agent does not support the HTML5 Video element.</p>
          </video>
      </div>
    </div>