immich/web/src/lib/components/asset-viewer/intersection-observer.svelte
Jason Rasmussen 5617b57b26
refactor(web): asset store (#3528)
* refactor(web): asset store

* chore: remove TODO
2023-08-03 10:44:12 -05:00

77 lines
2.1 KiB
Svelte

<script lang="ts">
import { BucketPosition } from '$lib/stores/assets.store';
import { createEventDispatcher, onMount } from 'svelte';
export let once = false;
export let top = 0;
export let bottom = 0;
export let left = 0;
export let right = 0;
export let root: HTMLElement | null = null;
let intersecting = false;
let container: HTMLDivElement;
const dispatch = createEventDispatcher();
onMount(() => {
if (typeof IntersectionObserver !== 'undefined') {
const rootMargin = `${top}px ${right}px ${bottom}px ${left}px`;
const observer = new IntersectionObserver(
(entries) => {
intersecting = entries[0].isIntersecting;
if (!intersecting) {
dispatch('hidden', container);
}
if (intersecting && once) {
observer.unobserve(container);
}
if (intersecting) {
let position: BucketPosition = BucketPosition.Visible;
if (entries[0].boundingClientRect.top + 50 > entries[0].intersectionRect.bottom) {
position = BucketPosition.Below;
} else if (entries[0].boundingClientRect.bottom < 0) {
position = BucketPosition.Above;
}
dispatch('intersected', {
container,
position,
});
}
},
{
rootMargin,
root,
},
);
observer.observe(container);
return () => observer.unobserve(container);
}
// The following is a fallback for older browsers
function handler() {
const bcr = container.getBoundingClientRect();
intersecting =
bcr.bottom + bottom > 0 &&
bcr.right + right > 0 &&
bcr.top - top < window.innerHeight &&
bcr.left - left < window.innerWidth;
if (intersecting && once) {
window.removeEventListener('scroll', handler);
}
}
window.addEventListener('scroll', handler);
return () => window.removeEventListener('scroll', handler);
});
</script>
<div bind:this={container}>
<slot {intersecting} />
</div>