123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <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 id="direction"></div>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { defineComponent, ref, watchEffect, computed, watch, nextTick } from 'vue'
- import { SceneType } from '@/store'
- import { params } 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 = ref("")
- watchEffect(() => {
- 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.SWSSMX]: `/swkk/spg.html?m=${scene.value.num}`,
- [SceneType.SWMX]: `index.html?caseId=${params.caseId}&modelId=${scene.value.num}&share=1#sign-model`
- }
- if (urls[type] !== url.value) {
- setTimeout(() => {
- const hook = (iframeRef.value?.contentWindow as any)?.beforeDestroy
- console.log(hook)
- if (hook) {
- hook()
- setTimeout(() => url.value = urls[type], 300)
- } else {
- url.value = urls[type]
- }
- })
- }
- })
- const fuseRef = ref<HTMLDivElement>()
- const iframeRef = ref<HTMLIFrameElement>()
- watch(
- () => [modelProps.type, url.value],
- async ([type, url], oldType, onCleanup) => {
- if (type !== fuseModel && !url) {
- return;
- }
- const callback = modelProps.callback
- 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">
- .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 {
- position: absolute;
- z-index: 1;
- border: none;
- top: calc(var(--editor-head-height) + var(--header-top));
- left: 0;
- height: calc(100% - (var(--editor-head-height) + var(--header-top)));
- width: 100%;
- }
- #direction {
- right: calc(var(--editor-menu-right) + var(--editor-toolbox-width)) !important;
- top: calc(var(--header-top) + var(--editor-head-height)) !important;
- margin: 10px;
- transition: top .3s ease, right .3s ease;
- }
- </style>
|