better bounding box camera change logic

This commit is contained in:
Yeicor
2024-02-28 19:47:39 +01:00
parent f5cf3d0edf
commit 2b2cbb517e
3 changed files with 53 additions and 37 deletions

View File

@@ -118,9 +118,7 @@ function onModelLoad() {
} }
// props.viewer.elem may not yet be available, so we need to wait for it // props.viewer.elem may not yet be available, so we need to wait for it
watch(() => props.viewer?.elem, (elem) => { props.viewer.onElemReady((elem) => elem.addEventListener('load', onModelLoad))
elem.addEventListener('load', onModelLoad);
});
</script> </script>
<template> <template>

View File

@@ -176,40 +176,48 @@ function toggleShowBoundingBox() {
updateBoundingBox(); updateBoundingBox();
} }
let hasListeners = false; let viewerFound = false
let firstLoad = true; watch(() => props.viewer, (viewer) => {
watch(() => props.viewer?.elem, (elem) => { if (!viewer) return;
if (hasListeners) return; if (viewerFound) return;
hasListeners = true; viewerFound = true;
elem.addEventListener('mouseup', selectionListener); let hasListeners = false;
elem.addEventListener('mousedown', selectionMoveListener); // Avoid clicking when dragging let firstLoad = true;
elem.addEventListener('load', () => { // props.viewer.elem may not yet be available, so we need to wait for it
if (firstLoad) { viewer.onElemReady((elem) => {
toggleShowBoundingBox(); if (hasListeners) return;
firstLoad = false; hasListeners = true;
} else { elem.addEventListener('mouseup', selectionListener);
updateBoundingBox(); elem.addEventListener('mousedown', selectionMoveListener); // Avoid clicking when dragging
} elem.addEventListener('load', () => {
}); if (firstLoad) {
let isWaiting = false; toggleShowBoundingBox();
let lastBoundingBoxUpdate = performance.now(); firstLoad = false;
elem.addEventListener('camera-change', () => {
// Avoid updates while dragging (slow operation)
if (isWaiting) return;
if (performance.now() - lastBoundingBoxUpdate < 1000) return;
isWaiting = true;
let waitingHandler: () => void;
waitingHandler = () => {
if (mouseDownAt === null) {
updateBoundingBox();
isWaiting = false;
lastBoundingBoxUpdate = performance.now();
} else { } else {
// If the mouse is still down, wait a little more updateBoundingBox();
setTimeout(waitingHandler, 100);
} }
}; });
setTimeout(waitingHandler, 100); // Wait for the camera to stop moving let isWaiting = false;
let lastCameraChange = 0
elem.addEventListener('camera-change', () => {
// Avoid updates while dragging (slow operation)
lastCameraChange = performance.now();
if (isWaiting) return;
isWaiting = true;
let waitingHandler: () => void;
waitingHandler = () => {
// Ignore also inertia
let stillMoving = performance.now() - lastCameraChange < 100;
if (!stillMoving) {
updateBoundingBox();
isWaiting = false;
} else {
// If the mouse is still down, wait a little more
setTimeout(waitingHandler, 100);
}
};
setTimeout(waitingHandler, 100); // Wait for the camera to stop moving
});
}); });
}); });

View File

@@ -6,7 +6,7 @@ import {settings} from "../misc/settings";
import {onMounted} from "vue"; import {onMounted} from "vue";
import {$scene, $renderer} from "@google/model-viewer/lib/model-viewer-base"; import {$scene, $renderer} from "@google/model-viewer/lib/model-viewer-base";
import Loading from "../misc/Loading.vue"; import Loading from "../misc/Loading.vue";
import {ref} from "vue"; import {ref, watch} from "vue";
import {ModelViewerElement} from '@google/model-viewer'; import {ModelViewerElement} from '@google/model-viewer';
import type {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene"; import type {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
import {Hotspot} from "@google/model-viewer/lib/three-components/Hotspot"; import {Hotspot} from "@google/model-viewer/lib/three-components/Hotspot";
@@ -117,7 +117,17 @@ function onCameraChangeLine(lineId: number) {
} }
} }
defineExpose({elem, scene, renderer, addLine3D, removeLine3D}); function onElemReady(callback: (elem: ModelViewerElement) => void) {
if (elem.value) {
callback(elem.value);
} else {
watch(() => elem.value, (elem) => {
if (elem) callback(elem);
});
}
}
defineExpose({elem, onElemReady, scene, renderer, addLine3D, removeLine3D});
</script> </script>
<template> <template>