javascripthtmlanimationscrollscrollmagic

HTML/JS: Pause vertical scrolling and animate an element instead


I have a website that contains a <div> element with horizontal overflow. I want the div to scroll horizontally from left to right as the user scrolls the website vertically from top to bottom. During that stage, the main content should not move, only the div should scroll. Once the div has been scrolled completely to the right, the vertical scrolling of the website should continue normally. The same should also work backwards.

I tried using ScrollMagic with pinning, however I experience stutters when trying to pin the main content container:

https://codepen.io/oelrim/pen/ZEGWvOK

Is there some other plugin that can achieve what I want?


Solution

  • Try this:

    var scene = document.querySelector('#sec-2');
    var rect = document.querySelector('#rect');
    
    var startEffect = scene.getBoundingClientRect().top + window.scrollY;
    var effectLength = 500;
    
    scene.style.marginBottom = effectLength +'px';
    window.addEventListener('scroll', function(e){
      var effect = window.scrollY - startEffect;
    
    if(effect > 0 && effect < effectLength) {
      scene.style.marginTop = effect+'px';
      scene.style.marginBottom = effectLength-effect+'px';
      rect.style.left = effect * (scene.offsetWidth-rect.offsetWidth) /effectLength+'px';
    } else if (effect < 0) {
      scene.style.marginTop = 0;
      scene.style.marginBottom = effectLength+'px';
      rect.style.left = 0;
    } else {
      scene.style.marginTop = effectLength+'px';
      scene.style.marginBottom = 0;
      rect.style.left = (scene.offsetWidth-rect.offsetWidth)+'px';
    }
    
    });
    html, body {padding:0;margin:0}
    
    #sec-1 {
    height: 100vh;
    background: repeating-linear-gradient(yellow 0, yellow 10px, green 10px, green 20px);
    }
    #sec-2 {
    position: relative;
    height: 100vh;
    background: repeating-linear-gradient(red 0, red 10px, green 10px, green 20px);}
    #sec-3 {
      height: 100vh;
    background: repeating-linear-gradient(red 0, red 10px, blue 10px, blue 20px);}
    h1 {
    color: white;
    text-shadow:  2px 2px 3px black, -2px -2px 3px black;
    margin: 0;
    }
    #rect {
    position: absolute;
    width: 60px;
    height: 60px;
    background-color: white;
    top: calc(50% - 30px);
    left: 0;
    }
    <div id="sec-1">
    <h1>This is section 1</h1>
    </div>
    <div id="sec-2">
    <h1>This is section 2</h1>
    <div id="rect"></div>
    </div>
    <div id="sec-3">
    <h1>This is section 3</h1>
    </div>