mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2025-12-19 22:24:17 +01:00
fully working example and many fixes
This commit is contained in:
@@ -6,7 +6,8 @@ import {VContainer, VRow, VCol, VProgressCircular} from "vuetify/lib/components/
|
||||
<v-container>
|
||||
<v-row justify="center" style="height: 100%">
|
||||
<v-col align-self="center">
|
||||
<v-progress-circular indeterminate style="display: block; margin: 0 auto;"/>
|
||||
<v-progress-circular indeterminate style="display: block; margin: 0 auto;"></v-progress-circular>
|
||||
<slot/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
@@ -24,8 +24,10 @@ export class NetworkManager extends EventTarget {
|
||||
* Updates will be emitted as "update" events, including the download URL and the model name.
|
||||
*/
|
||||
async load(url: string) {
|
||||
if (url.startsWith("ws://") || url.startsWith("wss://")) {
|
||||
this.monitorWebSocket(url);
|
||||
if (url.startsWith("dev+")) {
|
||||
let baseUrl = new URL(url.slice(4));
|
||||
baseUrl.searchParams.set("api_updates", "true");
|
||||
this.monitorDevServer(baseUrl);
|
||||
} else {
|
||||
// Get the last part of the URL as the "name" of the model
|
||||
let name = url.split("/").pop();
|
||||
@@ -38,21 +40,20 @@ export class NetworkManager extends EventTarget {
|
||||
}
|
||||
}
|
||||
|
||||
private monitorWebSocket(url: string) {
|
||||
private monitorDevServer(url: string) {
|
||||
// WARNING: This will spam the console logs with failed requests when the server is down
|
||||
let ws = new WebSocket(url);
|
||||
ws.onmessage = (event) => {
|
||||
let eventSource = new EventSource(url);
|
||||
eventSource.onmessage = (event) => {
|
||||
let data = JSON.parse(event.data);
|
||||
console.debug("WebSocket message", data);
|
||||
let urlObj = new URL(url);
|
||||
urlObj.protocol = urlObj.protocol === "ws:" ? "http:" : "https:";
|
||||
urlObj.searchParams.delete("api_updates");
|
||||
urlObj.searchParams.set("api_object", data.name);
|
||||
this.foundModel(data.name, data.hash, urlObj.toString());
|
||||
};
|
||||
ws.onerror = () => ws.close();
|
||||
ws.onclose = () => setTimeout(() => this.monitorWebSocket(url), settings.monitorEveryMs);
|
||||
let timeoutFaster = setTimeout(() => ws.close(), settings.monitorOpenTimeoutMs);
|
||||
ws.onopen = () => clearTimeout(timeoutFaster);
|
||||
eventSource.onerror = () => { // Retry after a very short delay
|
||||
setTimeout(() => this.monitorDevServer(url), settings.monitorEveryMs);
|
||||
}
|
||||
}
|
||||
|
||||
private foundModel(name: string, hash: string | null, url: string) {
|
||||
|
||||
@@ -10,11 +10,11 @@ export const settings = {
|
||||
// @ts-ignore
|
||||
// new URL('../../assets/logo_build/img.jpg.glb', import.meta.url).href,
|
||||
// Websocket URLs automatically listen for new models from the python backend
|
||||
"ws://127.0.0.1:32323/"
|
||||
"dev+http://127.0.0.1:32323/"
|
||||
],
|
||||
displayLoadingEveryMs: 1000, /* How often to display partially loaded models */
|
||||
monitorEveryMs: 100,
|
||||
monitorOpenTimeoutMs: 100,
|
||||
monitorOpenTimeoutMs: 1000,
|
||||
// ModelViewer settings
|
||||
autoplay: true,
|
||||
arModes: 'webxr scene-viewer quick-look',
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {settings} from "../misc/settings";
|
||||
import {onMounted, inject, type Ref} from "vue";
|
||||
import {$scene, $renderer} from "@google/model-viewer/lib/model-viewer-base";
|
||||
import {inject, onMounted, type Ref, ref, watch} from "vue";
|
||||
import {VList, VListItem} from "vuetify/lib/components/index.mjs";
|
||||
import {$renderer, $scene} from "@google/model-viewer/lib/model-viewer-base";
|
||||
import Loading from "../misc/Loading.vue";
|
||||
import {ref, watch} from "vue";
|
||||
import {ModelViewerElement} from '@google/model-viewer';
|
||||
import type {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
|
||||
import {Hotspot} from "@google/model-viewer/lib/three-components/Hotspot";
|
||||
@@ -152,7 +149,13 @@ watch(disableTap, (value) => {
|
||||
: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>
|
||||
<div class="annotation initial-load-banner">
|
||||
Trying to load models from...
|
||||
<v-list v-for="src in settings.preload" :key="src">
|
||||
<v-list-item>{{ src }}</v-list-item>
|
||||
</v-list>
|
||||
<loading></loading>
|
||||
</div>
|
||||
</model-viewer>
|
||||
|
||||
<!-- The SVG overlay for fake 3D lines attached to the model -->
|
||||
@@ -202,4 +205,15 @@ watch(disableTap, (value) => {
|
||||
height: 100dvh;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.initial-load-banner {
|
||||
width: 300px;
|
||||
margin: auto;
|
||||
margin-top: 3em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.initial-load-banner .v-list-item {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user