Estoy pensando en crear un sitio web que sirva como folleto digital para un teatro musical. La idea es tener una lista de créditos de desplazamiento automático como página de destino. He mirado ejemplos en codepen para ver cómo se logra este efecto. Pero también me gustaría que el usuario interactúe y se desplace si lo desea. Cuando dejen de desplazarse, los créditos volverán a desplazarse automáticamente. No encontré ningún ejemplo que aborde este tema. ¿Alguien de ustedes conoce un script (JS, o css simple...) que pueda ayudarme con esto?
La forma más sencilla es configurar una función requestAnimationFrame() e incrementar el valor en consecuencia, luego establecer la posición de desplazamiento. Luego agregue el evento de la rueda para detectar cuándo un usuario se desplaza (sin embargo, no use el evento 'desplazamiento', ya se llama cuando cambia el valor scrollTop del cuerpo), tampoco olvide cancelar la función requestAnimationFrame() . El código sería algo como esto:
let body = document.body, starter = document.querySelector("h1"), scroll_counter = 0, scrolled, auto_scroll_kicked = false; starter.addEventListener("click", start_scrolling); function start_scrolling() { auto_scroll_kicked = true; body.offsetHeight > scroll_counter ? (scroll_counter += 1.12) : (scroll_counter = body.offsetHeight); document.documentElement.scrollTop = scroll_counter; scroller = window.requestAnimationFrame(start_scrolling); if (scroll_counter >= body.offsetHeight) { window.cancelAnimationFrame(scroller); } } window.addEventListener("wheel", (e) => { if (auto_scroll_kicked) { window.cancelAnimationFrame(scroller); scroll_counter = 0; } });Juega con el codepen si quieres: https://codepen.io/SaltyMedStudent/pen/QWqVwaR?editors=0010
Hay muchas opciones para usar: funciones de aceleración, etc., pero espero que esto sea suficiente por ahora.
En su rutina de desplazamiento automático antes de cambiar de posición, verifique si la posición anterior es la misma que la posición de desplazamiento actual, si no lo es, el usuario la desplazó:
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>