diff options
| author | Fuwn <[email protected]> | 2024-02-09 05:14:43 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-02-09 05:14:43 -0800 |
| commit | 5abc4aa77a71ba306c4a4b48e6d35577962cf584 (patch) | |
| tree | 96b3f1e36913498c639f73bea9b77cf958ba2b74 /src/lib | |
| parent | feat(locale): localise hololive errors (diff) | |
| download | due.moe-5abc4aa77a71ba306c4a4b48e6d35577962cf584.tar.xz due.moe-5abc4aa77a71ba306c4a4b48e6d35577962cf584.zip | |
feat(lazy): lazy visibility component
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/Lazy.svelte | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/lib/Lazy.svelte b/src/lib/Lazy.svelte new file mode 100644 index 00000000..8bb180ac --- /dev/null +++ b/src/lib/Lazy.svelte @@ -0,0 +1,49 @@ +<script lang="ts"> + import { onMount, onDestroy } from 'svelte'; + + export let top = 0; + export let bottom = 0; + export let left = 0; + export let right = 0; + export let steps = 100; + export let threshold = 0.01; + export let once = false; + + let element: Element; + let percent: number = 0; + let visible = false; + let observer: IntersectionObserver; + + const intersectPercent = ( + entries: IntersectionObserverEntry[], + observer: IntersectionObserver + ) => { + for (let entry of entries) + if (entry.target === element) { + percent = Math.round(entry.intersectionRatio * 100); + visible = entry.intersectionRatio >= threshold; + + if (visible && once) observer.unobserve(element); + + break; + } + }; + + onMount(() => { + if ('IntersectionObserver' in window) { + let options = { + rootMargin: `${top}px ${right}px ${bottom}px ${left}px`, + threshold: Array.from({ length: steps }, (_, i) => i / (steps - 1)) + }; + + observer = new IntersectionObserver(intersectPercent, options); + observer.observe(element); + } + }); + + onDestroy(() => observer?.unobserve(element)); +</script> + +<div bind:this={element}> + <slot {visible} {percent} /> +</div> |