mirror of
https://github.com/yeicor-3d/yet-another-cad-viewer.git
synced 2026-01-31 02:24:14 +01:00
Started migration of frontend to Vue
This commit is contained in:
26
src/App.vue
Normal file
26
src/App.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import ModelViewer from './ModelViewer.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModelViewer></ModelViewer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
12
src/ModelViewer.vue
Normal file
12
src/ModelViewer.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import ModelViewerWrapper from "./ModelViewerWrapper.vue";
|
||||
import ModelViewerOverlay from "./ModelViewerOverlay.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModelViewerWrapper/>
|
||||
<ModelViewerOverlay/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
7
src/ModelViewerOverlay.vue
Normal file
7
src/ModelViewerOverlay.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
// TODO: transparent SVG overlay that redirects and grabs some events
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
36
src/ModelViewerWrapper.vue
Normal file
36
src/ModelViewerWrapper.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import {settings} from "./settings";
|
||||
import {onMounted, ref} from "vue";
|
||||
import {ModelViewerElement} from '@google/model-viewer';
|
||||
import {OrientationGizmo} from "./orientation";
|
||||
import {$scene} from "@google/model-viewer/lib/model-viewer-base";
|
||||
import {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
|
||||
|
||||
let _ = ModelViewerElement // HACK: Keep the import from being removed by the bundler
|
||||
const viewer = ref(null);
|
||||
onMounted(() => {
|
||||
// TODO: Custom gizmo component inside Tools window
|
||||
// Gizmo installation
|
||||
let scene: ModelScene = viewer.value[$scene];
|
||||
console.log('Mounted ModelViewerWrapper', viewer, scene);
|
||||
let gizmo = new OrientationGizmo(scene);
|
||||
gizmo.install();
|
||||
|
||||
function updateGizmo() {
|
||||
gizmo.update();
|
||||
requestAnimationFrame(updateGizmo);
|
||||
}
|
||||
|
||||
updateGizmo();
|
||||
console.log('Mounted ModelViewerWrapper');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<model-viewer
|
||||
ref="viewer" style="width: 100%; height: 100%" :src="settings.preloadModel" alt="The 3D model(s)" camera-controls
|
||||
camera-orbit="30deg 75deg auto" max-camera-orbit="Infinity 180deg auto" min-camera-orbit="-Infinity 0deg auto"
|
||||
: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"></model-viewer>
|
||||
</template>
|
||||
49
src/app.ts
49
src/app.ts
@@ -1,49 +0,0 @@
|
||||
import {ModelViewerElement} from '@google/model-viewer';
|
||||
import {$scene} from "@google/model-viewer/lib/model-viewer-base";
|
||||
import {OrientationGizmo} from "./orientation";
|
||||
import {ModelScene} from "@google/model-viewer/lib/three-components/ModelScene";
|
||||
import {settings} from "./settings";
|
||||
|
||||
export class App {
|
||||
element: ModelViewerElement
|
||||
|
||||
install() {
|
||||
this.element = new ModelViewerElement();
|
||||
this.element.setAttribute('alt', 'The CAD Viewer is not supported on this browser.');
|
||||
this.element.setAttribute('camera-controls', '');
|
||||
this.element.setAttribute('camera-orbit', '30deg 75deg auto');
|
||||
this.element.setAttribute('max-camera-orbit', 'Infinity 180deg auto');
|
||||
this.element.setAttribute('min-camera-orbit', '-Infinity 0deg auto');
|
||||
this.element.setAttribute('interaction-prompt', 'none'); // Quits selected views from gizmo
|
||||
// this.element.setAttribute('auto-rotate', ''); // Messes with the gizmo (rotates model instead of camera)
|
||||
if (settings.autoplay) this.element.setAttribute('autoplay', '');
|
||||
if (settings.arModes) {
|
||||
this.element.setAttribute('ar', '');
|
||||
this.element.setAttribute('ar-modes', settings.arModes);
|
||||
}
|
||||
if (settings.shadowIntensity) {
|
||||
this.element.setAttribute('shadow-intensity', '1');
|
||||
}
|
||||
if (settings.background) {
|
||||
this.element.setAttribute('skybox-image', settings.background);
|
||||
this.element.setAttribute('environment-image', settings.background);
|
||||
}
|
||||
console.log('ModelViewerElement', this.element)
|
||||
document.body.appendChild(this.element);
|
||||
// Misc installation
|
||||
let scene: ModelScene = this.element[$scene];
|
||||
let gizmo = new OrientationGizmo(scene);
|
||||
gizmo.install();
|
||||
|
||||
function updateGizmo() {
|
||||
gizmo.update();
|
||||
requestAnimationFrame(updateGizmo);
|
||||
}
|
||||
|
||||
updateGizmo();
|
||||
}
|
||||
|
||||
replaceModel(url: string) {
|
||||
this.element.setAttribute('src', url)
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
html, body, model-viewer {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #000;
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
<meta charset="utf-8">
|
||||
<title>Yet Another CAD Viewer</title>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'/>
|
||||
<link rel="stylesheet" type="text/css" href="./index.css">
|
||||
<script type="module" src="./index.ts"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
19
src/index.ts
19
src/index.ts
@@ -1,7 +1,16 @@
|
||||
import {App} from "./app";
|
||||
import {settings} from "./settings";
|
||||
const app = new App()
|
||||
// @ts-ignore
|
||||
globalThis.__VUE_OPTIONS_API__ = process.env.NODE_ENV === "development"
|
||||
// @ts-ignore
|
||||
globalThis.__VUE_PROD_DEVTOOLS__ = process.env.NODE_ENV === "development"
|
||||
// @ts-ignore
|
||||
globalThis.__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ = process.env.NODE_ENV === "development"
|
||||
|
||||
app.install();
|
||||
// import {createApp} from 'vue/dist/vue.esm-browser.prod.js'
|
||||
// import {createApp} from 'vue/dist/vue.esm-browser.js'
|
||||
import {createApp} from 'vue'
|
||||
// @ts-ignore
|
||||
import App from './App.vue'
|
||||
|
||||
app.replaceModel(settings.preloadModel)
|
||||
const app = createApp(App)
|
||||
app.config.compilerOptions.isCustomElement = tag => tag === 'model-viewer'
|
||||
app.mount('body')
|
||||
@@ -8,7 +8,8 @@ export const settings = {
|
||||
preloadModel: logo,
|
||||
autoplay: true,
|
||||
arModes: 'webxr scene-viewer quick-look',
|
||||
shadowIntensity: 1,
|
||||
exposure: 1,
|
||||
shadowIntensity: 0,
|
||||
background: skyboxUrl,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user