Something went wrong. Try again.
a simple but full-featured web player for OpenSubsonic music servers (Navidrome, Gonic, Ampache, etc) devins.page/tinysub
svelte typescript javascript subsonic gonic navidrome
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657// SPDX-License-Identifier: CC0-1.0
export const scrollFade = (element: HTMLElement, enabled = true) => { const update = () => { const remaining = Math.max( 0, element.scrollHeight - element.clientHeight - element.scrollTop, ); element.style.setProperty("--scroll-fade-top", `${element.scrollTop}px`); element.style.setProperty("--scroll-fade-bottom", `${remaining}px`); };
let cleanup: (() => void) | undefined; const enable = () => { if (cleanup) return;
let frame: number | undefined; const scheduleUpdate = () => { if (frame !== undefined) return; frame = requestAnimationFrame(() => { frame = undefined; update(); }); };
const resizeObserver = new ResizeObserver(scheduleUpdate); const mutationObserver = new MutationObserver(scheduleUpdate); resizeObserver.observe(element); mutationObserver.observe(element, { childList: true, subtree: true }); element.addEventListener("scroll", scheduleUpdate, { passive: true }); update();
cleanup = () => { if (frame !== undefined) cancelAnimationFrame(frame); resizeObserver.disconnect(); mutationObserver.disconnect(); element.removeEventListener("scroll", scheduleUpdate); element.style.removeProperty("--scroll-fade-top"); element.style.removeProperty("--scroll-fade-bottom"); }; }; const disable = () => { cleanup?.(); cleanup = undefined; };
if (enabled) enable();
return { update(nextEnabled: boolean) { if (nextEnabled) enable(); else disable(); }, destroy: disable, };};