123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- <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("")
- const setUrl = (newURL: string) => {
- if (newURL !== url.value) {
- setTimeout(() => {
- const hook = (iframeRef.value?.contentWindow as any)?.beforeDestroy
- if (hook) {
- try {
- hook()
- } catch(e) {
- console.error(e)
- }
- url.value = ""
- setTimeout(() => url.value = newURL, 300)
- } else {
- url.value = newURL
- }
- })
- }
- }
- watchEffect(() => {
- if (!scene.value) {
- return setUrl("");
- }
- 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}&app=${params.app}&modelId=${scene.value.num}&share=1#sign-model`,
- [SceneType.SWYDSS]: `/swss/index.html?m=${scene.value.num}`,
- [SceneType.SWYDMX]: `/swkk/spg.html?m=${scene.value.num}`,
- }
- setUrl(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 as any, 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' }
- )
- // 处理iframe 定制页面
- watch(
- () => [scene.value && scene.value.type, url.value],
- ([type], oldType, onCleanup) => {
- if (type === false) {
- // 手动渲染融合场景
- console.log("手动渲染!");
- setTimeout(() => {
- (window as any).viewer.setDisplay(true)
- }, 100)
- };
- const interval = setInterval(async () => {
- const doc = iframeRef.value?.contentWindow?.document!
- if (!doc || !doc.querySelector("div")) return;
- console.error(doc, doc.head)
- const target = doc.head
- clearInterval(interval);
- ;(window as any).iframeCreated && (window as any).iframeCreated(iframeRef.value);
- if (type === SceneType.SWSS) {
- const $style = document.createElement("style");
- $style.type = "text/css";
- var textNode = document.createTextNode(`
- .mode-tab > .model-mode-tab.strengthen {
- display: none !important;
- }
- `);
- $style.appendChild(textNode);
- target.appendChild($style);
- console.error(target, $style)
- }
- }, 16);
- onCleanup(() => clearInterval(interval));
- },
- {flush: 'post', immediate: true}
- )
- 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>
|