123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- <template>
- <iframe class="external" :src="url" ref="iframeRef" v-if="url"></iframe>
- <div class="laser-layer" v-show="!url">
- <div class="scene-canvas" ref="fuseRef"></div>
- </div>
- </template>
- <script lang="ts">
- import { defineComponent, ref, watchEffect, computed, watch, onMounted, nextTick } from 'vue'
- import { SceneType } from '@/store'
- import { params, showModelsMapStack } from '@/env'
- import { fuseModel, modelProps } from './index'
- import { modelSDKFactory } from './platform'
- const typeChange = () => {
- const oldType = modelProps.type
- let stopWatch = null as unknown as () => void
- const typePromise = new Promise((_, reject) => {
- stopWatch = watchEffect(() => {
- if (modelProps.type !== oldType) {
- reject(new Error('当前模型未加载完已切换到下个'))
- stopWatch!()
- }
- })
- })
- return { typePromise, typeCleanup: stopWatch }
- }
- export const Model = defineComponent({
- name: 'model',
- setup() {
- const scene = computed(() => modelProps.type !== fuseModel && modelProps.type)
- const url = computed(() => {
- if (!scene.value) return;
- const type = scene.value.type
- const urls = {
- [SceneType.SWKK]: `/swkk/spg.html?m=${scene.value.num}`,
- [SceneType.SWKJ]: `/swkk/spg.html?m=${scene.value.num}`,
- [SceneType.SWSS]: `/swss/index.html?m=${scene.value.num}`,
- [SceneType.SWMX]: `index.html?caseId=${params.caseId}&modelId=${scene.value.num}&token=${params.token}#sign-model`
- }
- return urls[type]
- })
- const fuseRef = ref<HTMLDivElement>()
- const iframeRef = ref<HTMLIFrameElement>()
- watch(
- () => modelProps.type,
- async (type, oldType, onCleanup) => {
- const callback = modelProps.callback
- if (oldType === fuseModel) {
- onCleanup(showModelsMapStack.push(ref(new Map())))
- }
- await nextTick()
- const { typePromise, typeCleanup } = typeChange()
- const modelPromise = modelSDKFactory(type, type === fuseModel ? fuseRef.value! : iframeRef.value!)
- let result: any = null, error = null
- try {
- result = await Promise.race([typePromise, modelPromise])
- } catch (err: any) {
- error = err
- }
- typeCleanup()
- callback && callback(result, error)
- },
- { immediate: true, flush: 'post' }
- )
- return {
- iframeRef,
- fuseRef,
- url
- }
- }
- })
- export default Model
- </script>
- <style scoped lang="scss">
- .external,
- .laser-layer {
- position: absolute;
- z-index: 1;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- .scene-canvas {
- width: 100%;
- height: 100%;
- background-color: #ccc;
- }
- }
- .external {
- border: none;
- }
- </style>
|