57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
// useSceneVisibility.ts
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
|
|
|
export function useSceneVisibility() {
|
|
const isIntersecting = ref(false); // Состояние видимости
|
|
let observer: IntersectionObserver | null = null;
|
|
let debounceTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
const startObserver = (element: HTMLElement) => {
|
|
observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (debounceTimeout) {
|
|
clearTimeout(debounceTimeout); // Очищаем предыдущий таймер
|
|
}
|
|
|
|
// Устанавливаем новый таймер
|
|
debounceTimeout = setTimeout(() => {
|
|
isIntersecting.value = entry.isIntersecting;
|
|
}, 100); // Задержка в 300 мс
|
|
});
|
|
},
|
|
{ threshold: 0.1 } // Порог видимости
|
|
);
|
|
|
|
if (element) {
|
|
observer.observe(element);
|
|
}
|
|
};
|
|
|
|
const stopObserver = () => {
|
|
if (observer) {
|
|
observer.disconnect();
|
|
observer = null;
|
|
}
|
|
|
|
if (debounceTimeout) {
|
|
clearTimeout(debounceTimeout); // Очищаем таймер при остановке наблюдателя
|
|
debounceTimeout = null;
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
// Инициализация наблюдателя при монтировании
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
// Очистка наблюдателя при размонтировании
|
|
stopObserver();
|
|
});
|
|
|
|
return {
|
|
isIntersecting,
|
|
startObserver,
|
|
stopObserver,
|
|
};
|
|
} |