123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- import { watchEffect, nextTick } from 'vue'
- import { fuseModelsLoaded, SceneType } from '@/store'
- import { fuseModel } from './'
- import { initialSDK, initialed as fuseInitialed, sdk as fuseSDK } from '@/sdk'
- import { asyncTimeout } from '@/utils'
- import type { ModelType } from './'
- export async function modelSDKFactory (
- type: ModelType,
- dom: HTMLDivElement | HTMLIFrameElement
- ): Promise<ModelExpose> {
- if (type === fuseModel) {
- if (!fuseInitialed) {
- await initialSDK({ layout: dom })
- }
- return exposeFactory(fuseModel)
- } else {
- const iframe = dom as HTMLIFrameElement
- const win = await new Promise<Window | null>((resolve, reject) => {
- const loadedHandler = () => {
- resolve(iframe.contentWindow)
- cleanup()
- }
- const errorHandler = (err: any) => {
- reject(err)
- cleanup()
- }
- const cleanup = () => {
- iframe.removeEventListener('load', loadedHandler)
- iframe.removeEventListener('error', errorHandler)
- }
- iframe.addEventListener('load', loadedHandler)
- iframe.addEventListener('error', errorHandler)
- })
- if (!win) {
- throw new Error('场景加载失败')
- }
- return await exposeFactory(type, win)
- }
- }
- const findObjectAttr = <T, K extends keyof T>(data: T, key: K): Promise<T[K]> => {
- return new Promise<T[K]>(resolve => {
- const query = () => {
- if (key in data) {
- resolve(data[key])
- } else {
- setTimeout(query, 6)
- }
- }
- query()
- })
- }
- const fuseLoaded = new Promise<void>(resolve => {
- const stop = watchEffect(() => {
- if (fuseModelsLoaded.value) {
- resolve()
- nextTick(() => stop())
- }
- })
- })
- export interface ModelExpose {
- getView: () => Promise<{ image: Blob, flyData: string }>
- setView: (flyData: string) => void
- }
- export async function exposeFactory(type: ModelType, win?: any): Promise<ModelExpose> {
- const sceneType = type === fuseModel ? fuseModel : type.type
- const platforms: {[key in any]: {getSDK: () => Promise<any>, expose: ModelExpose}} = {
- [fuseModel]: {
- getSDK: async () => {
- await fuseLoaded
- return fuseSDK
- },
- expose: {
- async getView() {
- const dataURL = await sdk.screenshot(260, 160)
- const res = await fetch(dataURL)
- const image = await res.blob()
- const pose = sdk.getPose()
- return {
- image,
- flyData: JSON.stringify(pose)
- }
- },
- async setView(flyData: string) {
- const pose = JSON.parse(flyData)
- sdk.comeTo({ dur: 300, ...pose })
- }
- }
- },
- [SceneType.SWKK]: {
- getSDK: async () => {
- const sdk = await findObjectAttr(win , '__sdk')
- if (!sdk.Scene.loaded) {
- await new Promise(reoslve => sdk.Scene.on('loaded', reoslve))
- }
- return sdk
- },
- expose: {
- async getView() {
- const pose = sdk.Camera.getPose()
- const images = await sdk.Camera.screenshot(
- [{ width: 260, height: 160, name: '2k' }],
- true
- )
- return {
- image: images[0].data,
- flyData: JSON.stringify(pose)
- }
- },
- async setView(flyData: string) {
- const pose = JSON.parse(flyData)
- console.log('===>?', pose)
- sdk.Camera.setPose({ dur: 300, ...pose })
- }
- }
- },
- [SceneType.SWSS]: {
- getSDK: async () => {
- await findObjectAttr(win, 'laserLoaded')
- return await findObjectAttr(win, '__sdk')
- },
- expose: {
- async getView() {
- const dataURL = await sdk.scene.screenshot(260, 160)
- const res = await fetch(dataURL)
- const image = await res.blob()
- const pose = await sdk.scene.getPose()
- const mode = sdk.customMap.mode
- return {
- image,
- flyData: JSON.stringify({ pose, mode })
- }
- },
- async setView(flyData: string) {
- const { pose, mode } = JSON.parse(flyData)
- sdk.customMap.mode = mode
- sdk.scene.setPose(pose, 300)
- }
- }
- }
- }
- platforms[SceneType.SWKJ] = platforms[SceneType.SWKK]
- platforms[SceneType.SWMX] = {
- getSDK: async () => findObjectAttr(win , '__sdk'),
- expose: platforms[fuseModel].expose
- }
- if (!(sceneType in platforms)) {
- throw new Error('不支持该类型场景!')
- }
- const sdk: any = await Promise.race([
- asyncTimeout(10000)
- .then(() => Promise.reject(new Error('加载超时'))),
- platforms[sceneType].getSDK()
- ])
- return platforms[sceneType].expose
- }
|