mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 22:24:17 +01:00
88 lines
2.8 KiB
Vue
88 lines
2.8 KiB
Vue
<script lang="ts">
|
|
</script>
|
|
|
|
<script setup lang="ts">
|
|
import {settings} from "../misc/settings";
|
|
import {onMounted} from "vue";
|
|
import {$scene, $renderer} from "@google/model-viewer/lib/model-viewer-base";
|
|
import Loading from "../misc/Loading.vue";
|
|
import {ref} from "vue";
|
|
import {ModelViewerElement} from '@google/model-viewer';
|
|
import type {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
|
|
import type {Renderer} from "@google/model-viewer/lib/three-components/Renderer";
|
|
|
|
ModelViewerElement.modelCacheSize = 0; // Also needed to avoid tree shaking
|
|
|
|
const emit = defineEmits<{ load: [] }>()
|
|
|
|
const props = defineProps({
|
|
src: String
|
|
});
|
|
|
|
const elem = ref<ModelViewerElement | null>(null);
|
|
const scene = ref<ModelScene | null>(null);
|
|
const renderer = ref<Renderer | null>(null);
|
|
defineExpose({elem, scene, renderer});
|
|
|
|
onMounted(() => {
|
|
elem.value.addEventListener('load', () => {
|
|
if (elem.value) {
|
|
// Delete the initial load banner
|
|
let banner = elem.value.querySelector('.initial-load-banner');
|
|
if (banner) banner.remove();
|
|
// Set the scene
|
|
scene.value = elem.value[$scene] as ModelScene;
|
|
renderer.value = elem.value[$renderer] as Renderer;
|
|
// Emit the load event
|
|
emit('load')
|
|
}
|
|
});
|
|
});
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<model-viewer ref="elem" style="width: 100%; height: 100%" :src="props.src" alt="The 3D model(s)" camera-controls
|
|
camera-orbit="30deg 75deg auto" max-camera-orbit="Infinity 180deg auto"
|
|
min-camera-orbit="-Infinity 0deg 5%" disable-tap :exposure="settings.exposure"
|
|
:shadow-intensity="settings.shadowIntensity" interaction-prompt="none" :autoplay="settings.autoplay"
|
|
:ar="settings.arModes.length > 0" :ar-modes="settings.arModes" :skybox-image="settings.background"
|
|
:environment-image="settings.background">
|
|
<slot></slot> <!-- Controls, annotations, etc. -->
|
|
<loading class="annotation initial-load-banner"></loading>
|
|
</model-viewer>
|
|
<!-- TODO: Transparent SVG overlay that can draw 2D lines attached to the 3D model(s) -->
|
|
<!-- https://modelviewer.dev/examples/annotations/index.html -->
|
|
<div class="overlay-svg-wrapper">
|
|
<svg class="overlay-svg" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
|
|
<!--<line x1="0" y1="0" x2="100%" y2="100%" stroke="black" stroke-width="2"/>-->
|
|
</svg>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* This keeps child nodes hidden while the element loads */
|
|
:not(:defined) > * {
|
|
display: none;
|
|
}
|
|
|
|
/* This is the SVG overlay that will be used for line annotations */
|
|
.overlay-svg-wrapper {
|
|
position: relative;
|
|
top: -100%;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 0;
|
|
pointer-events: none;
|
|
z-index: 1;
|
|
}
|
|
|
|
.overlay-svg {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100dvh;
|
|
pointer-events: none;
|
|
}
|
|
</style> |