diff --git a/http/poem.html b/http/poem.html index e5a5079..00cdd2c 100644 --- a/http/poem.html +++ b/http/poem.html @@ -200,7 +200,7 @@ audio.play(); audio.classList.add("playing"); button.classList.add("playing"); - startAutoScroll(emToPx(0.5) * 20 / 12); + startAutoScroll(0.5); } else { audio.pause(); @@ -213,16 +213,36 @@ let scrollAnimationHandle = null; - function startAutoScroll(speed) { + function scrollMaxValue() { + const body = document.body; + const html = document.documentElement; + const documentHeight = Math.max( + body.scrollHeight, + body.offsetHeight, + html.clientHeight, + html.scrollHeight, + html.offsetHeight + ); + const windowHeight = window.innerHeight; + return documentHeight - windowHeight; + }; + + function startAutoScroll(emsPerTick) { stopAutoScroll(); - const startY = window.scrollY; - const startTime = performance.now(); - function step() { - const currentTime = performance.now(); - const elapsed = (currentTime - startTime) / 1000; - const newY = Math.min(startY + (elapsed * speed), window.scrollMaxY); - window.scrollTo({ top: newY }); - if (newY < window.scrollMaxY) { + let lastTime = null; + let scrollFraction = 0; + function step(currentTime) { + const deltaTime = lastTime == null ? 0 : currentTime - lastTime; + lastTime = currentTime; + const elapsedSeconds = deltaTime / 1000; + const pixelsPerSecond = emToPx(emsPerTick) / 12 * 20; + const maxY = scrollMaxValue(); + let newY = Math.min(window.scrollY + (elapsedSeconds * pixelsPerSecond), maxY); + scrollFraction += newY % 1; + newY += Math.floor(scrollFraction); + scrollFraction %= 1; + window.scrollTo({ top: Math.floor(newY) }); + if (newY < maxY) { scrollAnimationHandle = requestAnimationFrame(step); } } @@ -234,9 +254,6 @@ cancelAnimationFrame(scrollAnimationHandle); } } - - window.addEventListener("wheel", stopAutoScroll, { passive: true }); - window.addEventListener("touchmove", stopAutoScroll, { passive: true });