aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-02-09 05:14:43 -0800
committerFuwn <[email protected]>2024-02-09 05:14:43 -0800
commit5abc4aa77a71ba306c4a4b48e6d35577962cf584 (patch)
tree96b3f1e36913498c639f73bea9b77cf958ba2b74 /src/lib
parentfeat(locale): localise hololive errors (diff)
downloaddue.moe-5abc4aa77a71ba306c4a4b48e6d35577962cf584.tar.xz
due.moe-5abc4aa77a71ba306c4a4b48e6d35577962cf584.zip
feat(lazy): lazy visibility component
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Lazy.svelte49
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>