javascripthtmlcssevent-listener

Fixing issues with window scrolling for a "sliding door" style animation controlled by a scroll event in javascript


I am a noob at webdev and I've been trying to learn by putting together some type of portfolio website. I've seen some examples of people who have cool effects on their landing pages and I want to do something similar.

Specifically I am trying to figure out how to create a "sliding door" effect. Meaning, upon my site loading, instead of the page scrolling I would like to have two divs slide apart, revealing the content inside. The amount that the doors get pulled back should be controlled by the amount the user has tried to scroll (mouse, gesture and scrollbar all should work). I've somewhat managed to achieve this, but I can't seem to figure out how to get the content on the page to remain static while the user scrolls to open the doors.

Maybe this is a simple thing and I should have read up on JS a bit more before starting this, but I have not been able to find anything online about it. At least not in noob-friendly format.

I have a demo I put together of what I have tried so far in this jsfiddle since I could not figure out snippets. I will put the javascript here as well:

window.addEventListener("scroll", handleScroll, {
  passive: false
});

let scrollPosition = 0;
const topCover = document.getElementById("top-cover");
const bottomCover = document.getElementById("bottom-cover");

function handleScroll(e) {

  e.preventDefault();

  scrollPosition = window.scrollY;
  const maxScroll = window.innerHeight / 2;

  if (scrollPosition < 0) scrollPosition = 0;

  topCover.style.transform = `translateY(-${scrollPosition}px)`;
  bottomCover.style.transform = `translateY(${scrollPosition}px)`;

  if (scrollPosition >= maxScroll) {
    cover.style.display = "none";
    window.removeEventListener('scroll', handleScroll)

  }
}

The two doors are the topCover and bottomCover divs, and they reveal upon scrolling down.

The problem here is that the content in the background still scrolls, so the user would have to scroll back up to the content after the doors go away. Additionally, this whole thing only works if there is enough content to overflow the page, since it depends on the scroll event. That is not a problem for my use case, but I still feel like it is a shortcoming of my approach. I tried using the wheel event instead, and that gave me a good result in preventing the background from scrolling (because the default action can be cancelled, while scrolling apparently can't), but the only way to have a smooth animation in that case is to scroll with gestures, since notched mouse wheels give insanely high deltaY values that made the effect really choppy. Even if I could think of a way to fix that, the wheel event doesn't account for the scrollbar moving the page, so it doesn't really work for me.

Any help with how to fix this issue would be much appreciated, I am not sure if I am just over complicating it. I would prefer to stick to just vanilla javascript and css for this if that is reasonable.


Solution

  • Hoping I understood your question correctly I have changed your fiddle. I think you can start from here.

    P.s. Especially for new ones in webdev Jquery for animations could be your answer ;-)

    JS:

    window.addEventListener("scroll", handleScroll, {
      passive: false
    });
    const topCover = document.getElementById("top-cover"),
          bottomCover = document.getElementById("bottom-cover"),
          content=document.getElementById("content");
          maxScroll = window.innerHeight / 2;
    function handleScroll(_e) {
      let scrollPosition = window.scrollY;
      if (scrollPosition < 0) scrollPosition = 0;
      if (scrollPosition < maxScroll) {
        topCover.style.height=bottomCover.style.height=`${maxScroll-scrollPosition}px`;
        content.style.marginTop=`${maxScroll}px`;
      } else {
        topCover.style.display=bottomCover.style.display="none";
        content.style.marginTop="initial";
        window.removeEventListener('scroll', handleScroll);
        window.scrollTo(0,0);
      }
    }