55 lines
1.4 KiB
Vue
55 lines
1.4 KiB
Vue
<script setup>
|
|
const props = defineProps({
|
|
canvasProps: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
},
|
|
cameraProps: {
|
|
type: Object,
|
|
default: () => ({}),
|
|
}
|
|
});
|
|
|
|
const container = ref(null);
|
|
const isIntersecting = ref(true);
|
|
let observer;
|
|
|
|
// Вычисляем renderMode на основе видимости
|
|
const renderMode = computed(() => (isIntersecting.value ? 'always' : 'never'));
|
|
const startObserver = () => {
|
|
observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
isIntersecting.value = entry.isIntersecting;
|
|
});
|
|
},
|
|
{ threshold: 0.1 } // Настройте порог видимости по вашему усмотрению
|
|
);
|
|
|
|
if (container.value) {
|
|
observer.observe(container.value);
|
|
}
|
|
}
|
|
onMounted(async () => {
|
|
await nextTick(); // Ждём завершения рендеринга
|
|
startObserver(); // Запускаем IntersectionObserver
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
if (observer) {
|
|
observer.disconnect();
|
|
}
|
|
});
|
|
</script>
|
|
<template>
|
|
<div ref="container" class="h-full">
|
|
<Suspense>
|
|
<TresCanvas v-bind="canvasProps" :render-mode="renderMode" :key="renderMode">
|
|
<ModelEnv />
|
|
<Suspense>
|
|
<slot />
|
|
</Suspense>
|
|
</TresCanvas>
|
|
</Suspense>
|
|
</div>
|
|
</template> |