41 lines
1.5 KiB
TypeScript
41 lines
1.5 KiB
TypeScript
// resources/js/composables/usePauseOffscreen.ts
|
|
import { onMounted, onUnmounted, type Ref } from 'vue';
|
|
|
|
export function usePauseOffscreen(
|
|
videoRef: Ref<HTMLVideoElement | HTMLVideoElement[] | undefined>,
|
|
) {
|
|
let observer: IntersectionObserver | null = null;
|
|
|
|
onMounted(() => {
|
|
observer = new IntersectionObserver(
|
|
(entries) => {
|
|
for (const entry of entries) {
|
|
const video = entry.target as HTMLVideoElement;
|
|
if (entry.isIntersecting) {
|
|
// Play whenever a video becomes visible — covers both
|
|
// scrolling a post into view and navigating to a new
|
|
// carousel slide (autoplay only fires once, on initial
|
|
// mount, so it can't handle the latter on its own).
|
|
video.play().catch(() => {
|
|
// Autoplay can still be blocked by the browser;
|
|
// leave it paused and let the user hit play.
|
|
});
|
|
} else if (!video.paused) {
|
|
video.pause();
|
|
}
|
|
}
|
|
},
|
|
{ threshold: 0.25 }, // play/pause around the 25% visible mark
|
|
);
|
|
|
|
const els = Array.isArray(videoRef.value)
|
|
? videoRef.value
|
|
: [videoRef.value];
|
|
els.forEach((el) => el && observer!.observe(el));
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
observer?.disconnect();
|
|
});
|
|
}
|