javascriptcssautoscroll

autoscroll (like movie credits) but the user can takeover by simply scrolling


I am looking into creating a website which will serve as a a digital leaflet for a musical theatre. The idea is to have an autoscrolling credits list as landingpage. I've looked at examples on codepen to see how this effect is been achieved. But I would also like the user to interact and scroll themselves if they want to. When they stop scrolling the credits will turn back to autoscroll. I didn't find any example who tackles this issue. Does someone of you know a script (JS, or plain css…) that can help me with this?


Solution

  • In your auto scroll routine before changing position check if previous position is the same as current scrolling position, if it's not - the user scrolled it:

    let el = document.documentElement,
        footer = document.getElementById("status").querySelectorAll("td"),
        scroll_position = 0,
        scroll_speed = 0,
        scroll_delta = 1.12,
        scroller,
        status = "stopped";
    
    el.addEventListener("click", scroll);
    
    info();
    
    function scroll(e)
    {
      if (e.type == "click")
      {
        window.cancelAnimationFrame(scroller);
        scroll_position = el.scrollTop; //make sure we start from current position
        scroll_speed++; //increase speed with each click
        info("auto scroll");
      }
      //if previous position is different, this means user scrolled
      if (scroll_position != el.scrollTop)
      {
        scroll_speed = 0;
        info("stopped by user");
        return;
      }
    
      el.scrollTop += scroll_delta * scroll_speed; //scroll to new position
      scroll_position = el.scrollTop; //get the current position
    
      //loop only if we didn't reach the bottom
      if (el.scrollHeight - el.scrollTop - el.clientHeight > 0)
      {
        scroller = window.requestAnimationFrame(scroll); //loop
      }
      else
      {
        el.scrollTop = el.scrollHeight; //make sure it's all the way to the bottom
        scroll_speed = 0;
        info("auto stopped");
      }
    }
    
    function info(s)
    {
      if (typeof s === "string")
        status = s;
    
      footer[1].textContent = el.scrollTop;
      footer[3].textContent = scroll_speed;
      footer[5].textContent = status;
    
    }
    
    //generate html demo sections
    for(let i = 2, section = document.createElement("section"); i < 6; i++)
    {
      section = section.cloneNode(false);
      section.textContent = "Section " + i;
      document.body.appendChild(section);
    }
    
    //register scroll listener for displaying info
    window.addEventListener("scroll", info);
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body
    {
      font-family: "Roboto", Arial;
      user-select: none;
    }
    
    section
    {
      min-height: 100vh;
      font-size: 3em;
      font-weight: 500;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #fff;
    }
    
    section:nth-child(even)
    {
      background: #0b0d19;
    }
    
    section:nth-child(odd)
    {
      background: #131524;
    }
    
    #status
    {
      position: fixed;
      bottom: 0;
      color: #fff;
      margin: 0.5em;
    }
    
    #status td:first-of-type
    {
      text-align: end;
      padding-right: 0.4em;
    }
    #status td:last-of-type
    {
      font-weight: bold;
    }
    <section>
      Click to start Scrolling
    </section>
    
    <table id="status">
      <tr><td>position:</td><td></td></tr>
      <tr><td>speed:</td><td></td></tr>
      <tr><td>status:</td><td></td></tr>
    </table>