|
@@ -1,5 +1,6 @@
|
|
-import { models } from '@/store'
|
|
|
|
-import { toRaw, createVNode, watchEffect } from 'vue'
|
|
|
|
|
|
+import { models, taggings, isEdit, sysBus } from '@/store'
|
|
|
|
+import { toRaw, watchEffect, ref, watch } from 'vue'
|
|
|
|
+import { viewModeStack } from '@/env'
|
|
import {
|
|
import {
|
|
mount,
|
|
mount,
|
|
diffArrayChange,
|
|
diffArrayChange,
|
|
@@ -7,8 +8,10 @@ import {
|
|
arrayChildEffectScope
|
|
arrayChildEffectScope
|
|
} from '@/utils'
|
|
} from '@/utils'
|
|
|
|
|
|
-import type { SDK, SceneModel } from '.'
|
|
|
|
-import type { Model } from '@/api'
|
|
|
|
|
|
+import TaggingComponent from '@/components/tagging/list.vue'
|
|
|
|
+
|
|
|
|
+import type { SDK, SceneModel, SceneGuidePath } from '.'
|
|
|
|
+import { Model, Tagging } from '@/api'
|
|
|
|
|
|
const sceneModelMap = new WeakMap<Model, SceneModel>()
|
|
const sceneModelMap = new WeakMap<Model, SceneModel>()
|
|
export const getSceneModel = (model: Model | null) => model && sceneModelMap.get(toRaw(model))
|
|
export const getSceneModel = (model: Model | null) => model && sceneModelMap.get(toRaw(model))
|
|
@@ -24,7 +27,6 @@ const associationModels = (sdk: SDK) => {
|
|
|
|
|
|
const itemRaw = toRaw(item)
|
|
const itemRaw = toRaw(item)
|
|
const sceneModel = sdk.addModel(itemRaw)
|
|
const sceneModel = sdk.addModel(itemRaw)
|
|
- console.log(sceneModel)
|
|
|
|
sceneModelMap.set(itemRaw, sceneModel)
|
|
sceneModelMap.set(itemRaw, sceneModel)
|
|
|
|
|
|
sceneModel.bus.on('position', pos => item.position = pos)
|
|
sceneModel.bus.on('position', pos => item.position = pos)
|
|
@@ -43,9 +45,91 @@ const associationModels = (sdk: SDK) => {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const associationTaggings = (el: HTMLDivElement) => {
|
|
|
|
+ const getTaggings = () => taggings.value
|
|
|
|
+ const taggingVMs = new WeakMap<Tagging, ReturnType<typeof mount>>()
|
|
|
|
+
|
|
|
|
+ shallowWatchArray(getTaggings, (taggings, oldTaggings) => {
|
|
|
|
+ const { added, deleted } = diffArrayChange(taggings, oldTaggings)
|
|
|
|
+ for (const item of added) {
|
|
|
|
+ taggingVMs.set(toRaw(item), mount(el, TaggingComponent, { tagging: item }))
|
|
|
|
+ }
|
|
|
|
+ for (const item of deleted) {
|
|
|
|
+ const unMount = taggingVMs.get(toRaw(item))
|
|
|
|
+ unMount && unMount()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+const fullView = async (fn: () => void) => {
|
|
|
|
+ const popViewMode = viewModeStack.push(ref('full'))
|
|
|
|
+ await document.documentElement.requestFullscreen()
|
|
|
|
+ const driving = () => document.fullscreenElement || fn()
|
|
|
|
+
|
|
|
|
+ document.addEventListener('fullscreenchange', driving)
|
|
|
|
+ document.addEventListener('fullscreenerror', fn)
|
|
|
|
+
|
|
|
|
+ return () => {
|
|
|
|
+ popViewMode()
|
|
|
|
+ document.fullscreenElement && document.exitFullscreen()
|
|
|
|
+ document.removeEventListener('fullscreenchange', driving)
|
|
|
|
+ document.removeEventListener('fullscreenerror', fn)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export const isScenePlayIng = ref(false)
|
|
|
|
+export const playSceneGuide = async (sdk: SDK, paths: SceneGuidePath[], changeIndexCallback: (index: number) => void) => {
|
|
|
|
+ if (isScenePlayIng.value) {
|
|
|
|
+ throw new Error('导览正在播放')
|
|
|
|
+ }
|
|
|
|
+ isScenePlayIng.value = true
|
|
|
|
+
|
|
|
|
+ const sceneGuide = sdk.enterSceneGuide(paths)
|
|
|
|
+
|
|
|
|
+ sceneGuide.bus.on('changePoint', changeIndexCallback)
|
|
|
|
+
|
|
|
|
+ const quitHandler = () => (isScenePlayIng.value = false)
|
|
|
|
+ const clearHandler = isEdit.value ? null : await fullView(quitHandler)
|
|
|
|
+ if (!clearHandler) {
|
|
|
|
+ sysBus.on('leave', quitHandler, { last: true })
|
|
|
|
+ sysBus.on('save', quitHandler, { last: true })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sceneGuide.play()
|
|
|
|
+ const reces = [
|
|
|
|
+ new Promise(resolve => sceneGuide.bus.on('playComplete', resolve)),
|
|
|
|
+ new Promise<void>(resolve => {
|
|
|
|
+ const stop = watch(isScenePlayIng, () => {
|
|
|
|
+ if (!isScenePlayIng.value) {
|
|
|
|
+ resolve()
|
|
|
|
+ sceneGuide.pause()
|
|
|
|
+ stop()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }),
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ await Promise.race(reces)
|
|
|
|
+ isScenePlayIng.value = false
|
|
|
|
+ if (clearHandler) {
|
|
|
|
+ clearHandler()
|
|
|
|
+ } else {
|
|
|
|
+ sysBus.off('leave', quitHandler)
|
|
|
|
+ sysBus.off('save', quitHandler)
|
|
|
|
+ }
|
|
|
|
+ sceneGuide.clear()
|
|
|
|
+ sceneGuide.bus.off('changePoint')
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export const pauseSceneGuide = () => isScenePlayIng.value = false
|
|
|
|
|
|
|
|
|
|
export const setup = (sdk: SDK, mountEl: HTMLDivElement) => {
|
|
export const setup = (sdk: SDK, mountEl: HTMLDivElement) => {
|
|
- associationModels(sdk)
|
|
|
|
- mount(mountEl, () => createVNode('p', null, '123123'))
|
|
|
|
|
|
+ try {
|
|
|
|
+ associationModels(sdk)
|
|
|
|
+ } catch {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ associationTaggings(mountEl)
|
|
}
|
|
}
|