@realsee/vreo 0.1.6 → 0.2.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +103 -16
  2. package/docs/assets/custom.css +4 -4
  3. package/docs/assets/search.js +1 -1
  4. package/docs/classes/Player.Controller.html +54 -0
  5. package/docs/classes/Player.Player-1.html +11 -11
  6. package/docs/classes/Player.VideoAgentMesh.html +142 -0
  7. package/docs/classes/Player.VideoAgentScene.html +1 -0
  8. package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
  9. package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
  10. package/docs/enums/Player.PanoEffectEnum.html +2 -2
  11. package/docs/enums/Player.PanoTagEnum.html +1 -1
  12. package/docs/enums/Player.VreoKeyframeEnum.html +14 -12
  13. package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
  14. package/docs/enums/fivePlugins.Rotation.html +1 -1
  15. package/docs/index.html +52 -19
  16. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -0
  17. package/docs/interfaces/Player.PlayerConfigs.html +4 -2
  18. package/docs/interfaces/Player.Vertex.html +1 -1
  19. package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -0
  20. package/docs/interfaces/Player.VreoKeyframe.html +1 -1
  21. package/docs/interfaces/Player.VreoUnit.html +1 -1
  22. package/docs/interfaces/Player.VreoVideo.html +1 -1
  23. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
  24. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +3 -3
  25. package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +1 -1
  26. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -1
  27. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -1
  28. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -1
  29. package/docs/interfaces/react.VreoActionCallbacks.html +15 -7
  30. package/docs/interfaces/react.VreoProviderProps.html +1 -0
  31. package/docs/modules/Player.html +17 -15
  32. package/docs/modules/custom.html +3 -0
  33. package/docs/modules/fivePlugins.html +2 -2
  34. package/docs/modules/react.html +1 -1
  35. package/docs/modules.html +1 -1
  36. package/lib/PlayController/createHTMLAudioElement.d.ts +1 -0
  37. package/lib/PlayController/createHTMLAudioElement.js +47 -0
  38. package/lib/PlayController/index.d.ts +38 -0
  39. package/lib/PlayController/index.js +300 -0
  40. package/lib/Player/App.js +8 -3
  41. package/lib/Player/Controller.d.ts +2 -0
  42. package/lib/Player/Controller.js +14 -0
  43. package/lib/Player/custom/SpatialScenePanel/index.d.ts +22 -0
  44. package/lib/Player/custom/SpatialScenePanel/index.js +279 -0
  45. package/lib/Player/index.d.ts +1 -1
  46. package/lib/Player/index.js +98 -11
  47. package/lib/Player/modules/Drawer/index.js +1 -1
  48. package/lib/Player/modules/PopUp/index.d.ts +2 -0
  49. package/lib/Player/modules/PopUp/index.js +43 -0
  50. package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +1 -0
  51. package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +6 -2
  52. package/lib/Player/modules/VideoAgent/VideoAgentScene.d.ts +4 -1
  53. package/lib/Player/modules/VideoAgent/VideoAgentScene.js +21 -6
  54. package/lib/Player/modules/VideoAgent/index.d.ts +2 -0
  55. package/lib/Player/modules/VideoAgent/index.js +1 -1
  56. package/lib/Player/modules/keyframes/BgMusic/index.d.ts +2 -0
  57. package/lib/Player/modules/keyframes/BgMusic/index.js +76 -0
  58. package/lib/Player/modules/keyframes/CameraMovement/index.js +41 -5
  59. package/lib/Player/modules/keyframes/InfoPanel/index.js +105 -23
  60. package/lib/Player/modules/keyframes/ModelVideo/index.js +47 -10
  61. package/lib/Player/modules/keyframes/PanoTextLabel/index.js +4 -12
  62. package/lib/Player/modules/keyframes/Prompter/index.js +4 -18
  63. package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +71 -12
  64. package/lib/Player/typings.d.ts +19 -1
  65. package/lib/fivePlugins/CameraMovementPlugin/index.js +104 -90
  66. package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +1 -0
  67. package/lib/react/index.d.ts +10 -2
  68. package/lib/react/index.js +1 -1
  69. package/lib/shared-utils/createTransMatrix.d.ts +1 -0
  70. package/lib/shared-utils/createTransMatrix.js +43 -0
  71. package/lib/typings/VreoUnit.d.ts +47 -7
  72. package/lib/typings/VreoUnit.js +15 -6
  73. package/package.json +6 -6
  74. package/resources/PlayController/createHTMLAudioElement.ts +53 -0
  75. package/resources/PlayController/index.ts +167 -0
  76. package/resources/Player/App.tsx +6 -1
  77. package/resources/Player/Controller.ts +12 -0
  78. package/resources/Player/custom/SpatialScenePanel/index.tsx +264 -0
  79. package/resources/Player/index.tsx +56 -2
  80. package/resources/Player/modules/Drawer/index.tsx +1 -1
  81. package/resources/Player/modules/PopUp/index.tsx +26 -0
  82. package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +5 -4
  83. package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +11 -2
  84. package/resources/Player/modules/VideoAgent/index.tsx +3 -2
  85. package/resources/Player/modules/keyframes/BgMusic/index.tsx +66 -0
  86. package/resources/Player/modules/keyframes/CameraMovement/index.tsx +7 -3
  87. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +109 -11
  88. package/resources/Player/modules/keyframes/ModelVideo/index.tsx +38 -5
  89. package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +2 -2
  90. package/resources/Player/modules/keyframes/Prompter/index.tsx +5 -15
  91. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +75 -12
  92. package/resources/Player/typings.ts +21 -1
  93. package/resources/fivePlugins/CameraMovementPlugin/index.ts +59 -48
  94. package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
  95. package/resources/react/index.tsx +12 -3
  96. package/resources/shared-utils/createTransMatrix.ts +12 -0
  97. package/resources/typings/VreoUnit.ts +56 -7
  98. package/stylesheets/custom/SpatialScenePanel.css +309 -0
  99. package/stylesheets/default.css +127 -9
@@ -9,7 +9,7 @@ export class VideoAgentScene {
9
9
  renderer = new THREE.WebGLRenderer({ alpha: true })
10
10
  container: HTMLElement
11
11
 
12
- constructor(container: HTMLElement, needRender = true) {
12
+ constructor(container: HTMLElement, needRender = true, options: { videoInstance?: HTMLVideoElement, audioInstance?: HTMLAudioElement } = {}) {
13
13
  this.container = container
14
14
  this.camera.position.set(0, 0, 10)
15
15
  this.camera.lookAt(0, 0, 0)
@@ -22,7 +22,7 @@ export class VideoAgentScene {
22
22
  this.renderer.setSize(state.width * window.devicePixelRatio, state.height * window.devicePixelRatio)
23
23
  domElement.setAttribute('style', `width: ${state.width}px;height: ${state.height}px;`)
24
24
 
25
- this.videoAgentMesh = new VideoAgentMesh(480, 270, 1, 1)
25
+ this.videoAgentMesh = new VideoAgentMesh(480, 270, 1, 1, options)
26
26
  if (needRender) {
27
27
  container.append(domElement)
28
28
  this.scene.add(this.videoAgentMesh)
@@ -31,10 +31,19 @@ export class VideoAgentScene {
31
31
  }
32
32
 
33
33
  run = () => {
34
+ const domElement = this.renderer.domElement
35
+
34
36
  // 视频开始 1s 不渲染:规避某些设备黑屏闪烁问题。视频前 2s 是最好是静默的。
35
37
  if (!(this.videoAgentMesh.paused || this.videoAgentMesh.freeze) && this.videoAgentMesh.currentTime > 1000) {
36
38
  this.renderer.render(this.scene, this.camera)
37
39
  }
40
+
41
+ // 兼容非视频场景
42
+ if (!this.videoAgentMesh.videoUrl?.endsWith('.mp4')) {
43
+ if (domElement.style.display !== 'none') domElement.style.display = 'none'
44
+ } else {
45
+ if (domElement.style.display !== 'block') domElement.style.display = 'block'
46
+ }
38
47
  requestAnimationFrame(this.run)
39
48
  }
40
49
 
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react'
2
2
  import { useController } from '../../hooks'
3
+ import { VideoAgentMeshOptions } from './VideoAgentMesh'
3
4
  import { VideoAgentScene } from './VideoAgentScene'
4
5
 
5
- export function VideoAgent(props: { onClick?: () => void }) {
6
+ export function VideoAgent(props: { onClick?: () => void; options?: VideoAgentMeshOptions }) {
6
7
  const ref = React.useRef<HTMLDivElement>(null)
7
8
  const controller = useController()
8
9
 
@@ -12,7 +13,7 @@ export function VideoAgent(props: { onClick?: () => void }) {
12
13
  console.warn('"VideoAgentScene" 重复初始化,已被过滤 ...')
13
14
  return
14
15
  }
15
- const videoAgentScene = new VideoAgentScene(ref.current)
16
+ const videoAgentScene = new VideoAgentScene(ref.current, true, props.options || {})
16
17
  controller.videoAgentScene = videoAgentScene
17
18
 
18
19
  return () => {
@@ -0,0 +1,66 @@
1
+ import * as React from 'react'
2
+ import { BgMusicData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
3
+ import { useController } from '../../../hooks'
4
+
5
+ export function BgMusic() {
6
+ const controller = useController()
7
+ const timeoutIdRef = React.useRef<NodeJS.Timeout | null>(null)
8
+ const cleanTimeout = React.useCallback( () => {
9
+ if (timeoutIdRef.current) {
10
+ clearTimeout(timeoutIdRef.current)
11
+ timeoutIdRef.current = null
12
+ }
13
+ }, [])
14
+
15
+ React.useEffect(() => {
16
+ const audio = new Audio()
17
+ audio.setAttribute('id', 'vreo-singleton-bgmusic')
18
+ audio.style.display = 'none'
19
+
20
+ audio.setAttribute('playsinline', 'true')
21
+ audio.loop = true
22
+ document.body.append(audio)
23
+
24
+ const callback = (keyframe: VreoKeyframe) => {
25
+ const { start, end } = keyframe
26
+ const { url } = keyframe.data as BgMusicData
27
+ audio.src = url
28
+ const playCallback = () => {
29
+ audio.play()
30
+ }
31
+
32
+ audio.addEventListener('canplaythrough', playCallback)
33
+
34
+ cleanTimeout()
35
+
36
+ const cleanAudio = () => {
37
+ audio.pause()
38
+ audio.currentTime = 0
39
+ audio.src = ''
40
+ cleanTimeout()
41
+ audio.removeEventListener('canplaythrough', playCallback)
42
+ }
43
+
44
+ const duration = (end - start) || 5000
45
+
46
+ timeoutIdRef.current = setTimeout(() => {
47
+ cleanAudio()
48
+ }, duration)
49
+
50
+ controller.once('paused', () => {
51
+ cleanAudio()
52
+ })
53
+
54
+ }
55
+
56
+ controller.on(VreoKeyframeEnum.BgMusic, callback)
57
+
58
+ return () => {
59
+ controller.off(VreoKeyframeEnum.BgMusic, callback)
60
+ document.body.removeChild(audio)
61
+ cleanTimeout()
62
+ }
63
+ })
64
+
65
+ return <></>
66
+ }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react'
2
2
  import { CameraMovementPlugin } from '../../../../fivePlugins/CameraMovementPlugin'
3
- import { CameraMovementEffect, RotateArgs } from '../../../../fivePlugins/CameraMovementPlugin/typings'
3
+ import { CameraMovementEffect, MoveArgs, RotateArgs } from '../../../../fivePlugins/CameraMovementPlugin/typings'
4
4
  import { CameraMovementData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
5
  import { useController, useFiveInstance } from '../../../hooks'
6
6
 
@@ -18,9 +18,13 @@ export function CameraMovement() {
18
18
  const cameraMovementData = data as CameraMovementData
19
19
  const effect = cameraMovementData.effect
20
20
  if (effect === CameraMovementEffect.Rotate) {
21
- ref.current.rotate(data as RotateArgs, end - start)
21
+ await ref.current.rotate(data as RotateArgs, end - start)
22
+ } else if (effect === CameraMovementEffect.Move) {
23
+ await ref.current.move(data as MoveArgs, end - start)
24
+ } else if (cameraMovementData.panoIndex !== undefined && cameraMovementData.panoIndex !== five.panoIndex) {
25
+ await ref.current.move(data as MoveArgs, end - start)
22
26
  } else {
23
- ref.current.move(data, end - start)
27
+ await ref.current.rotate(data as RotateArgs, end - start)
24
28
  }
25
29
  }
26
30
 
@@ -1,19 +1,48 @@
1
1
  import * as React from 'react'
2
- import { InfoPanelData, InfoPanelTypeEnum, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
2
+ import { ReactNode } from 'react'
3
+ import {
4
+ InfoPanelData,
5
+ InfoPanelStyleEnum,
6
+ InfoPanelTypeEnum,
7
+ VreoKeyframe,
8
+ VreoKeyframeEnum,
9
+ } from '../../../../typings/VreoUnit'
3
10
  import { useController } from '../../../hooks'
4
11
 
5
- function InfoPanelImg({ url }: { url: string }) {
12
+ function InfoPanelImg({ url, children }: { url: string; children?: ReactNode }) {
6
13
  return (
7
14
  <div className="vreo-infoPanel vreo-infoPanel--img">
8
- <img className="vreo-infoPanelImg" src={url} />
15
+ {children}
16
+ <div className="vreo-infoPanelImg" style={{ backgroundImage: `url(${url})` }}></div>
9
17
  </div>
10
18
  )
11
19
  }
12
20
 
13
- function InfoPanelVideo({ url }: { url: string }) {
21
+ function InfoPanelVideo({ url, children }: { url: string; children?: ReactNode }) {
14
22
  return (
15
23
  <div className="vreo-infoPanel vreo-infoPanel--video">
16
- <video playsInline autoPlay className="vreo-infoPanelVideo" src={url} />
24
+ {children}
25
+ <div className="vreo-infoPanelWrapper">
26
+ <video playsInline autoPlay className="vreo-infoPanelVideo" src={url} />
27
+ </div>
28
+ </div>
29
+ )
30
+ }
31
+
32
+ interface TitleProps {
33
+ title?: string
34
+ subTitle?: string
35
+ }
36
+
37
+ const Title = (props: TitleProps) => {
38
+ if (!props.title && !props.subTitle) {
39
+ return null
40
+ }
41
+
42
+ return (
43
+ <div className="vreo-infoPanel-title">
44
+ <div className="vreo-infoPanel-t1">{props.title}</div>
45
+ <div className="vreo-infoPanel-t2">{props.subTitle}</div>
17
46
  </div>
18
47
  )
19
48
  }
@@ -26,20 +55,89 @@ export function InfoPanel() {
26
55
  if (controller.configs?.keyframeMap.InfoPanel === false) {
27
56
  return
28
57
  }
58
+
29
59
  const callback = (keyframe: VreoKeyframe) => {
30
60
  const { start, end, data } = keyframe
31
61
 
32
62
  const infoPanelData = data as InfoPanelData
33
63
 
34
- if (infoPanelData.type === InfoPanelTypeEnum.Image) {
35
- controller.openDrawer({ content: <InfoPanelImg url={infoPanelData.url} />, height: '60vh' })
36
- } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
37
- controller.openDrawer({ content: <InfoPanelVideo url={infoPanelData.url} />, height: '60vh' })
38
- }
39
- timeoutRef.current = setTimeout(() => controller.openDrawer(false), end - start)
64
+ const { title, subTitle, style } = infoPanelData
65
+ do {
66
+ if (style === InfoPanelStyleEnum.PopUp) {
67
+ if (infoPanelData.type === InfoPanelTypeEnum.Image) {
68
+ controller.openPopUp(
69
+ <InfoPanelImg url={infoPanelData.url}>
70
+ <Title title={title} subTitle={subTitle} />
71
+ </InfoPanelImg>
72
+ )
73
+ } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
74
+ controller.openPopUp(
75
+ <InfoPanelVideo url={infoPanelData.url}>
76
+ <Title title={title} subTitle={subTitle} />
77
+ </InfoPanelVideo>
78
+ )
79
+ }
80
+ break
81
+ }
82
+ if (infoPanelData.type === InfoPanelTypeEnum.Image) {
83
+ controller.openDrawer({
84
+ content: (
85
+ <InfoPanelImg url={infoPanelData.url}>
86
+ <Title title={title} subTitle={subTitle} />
87
+ </InfoPanelImg>
88
+ ),
89
+ height: '60vh',
90
+ })
91
+ } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
92
+ controller.openDrawer({
93
+ content: (
94
+ <InfoPanelVideo url={infoPanelData.url}>
95
+ <Title title={title} subTitle={subTitle} />
96
+ </InfoPanelVideo>
97
+ ),
98
+ height: '60vh',
99
+ })
100
+ }
101
+ } while (false)
102
+
103
+ timeoutRef.current = setTimeout(() => {
104
+ controller.openDrawer(false)
105
+ controller.openPopUp(false)
106
+ }, end - start)
40
107
  }
41
108
  controller.on(VreoKeyframeEnum.InfoPanel, callback)
42
109
 
110
+ // Object.assign(window, {
111
+ // $setInfoPanel: () => {
112
+ // controller.openPopUp(
113
+ // // <InfoPanelImg url='//vrlab-static.ljcdn.com/release/web/psq/a.8e868cb2.gif' />
114
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/b.f9a1ed52.png' />
115
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/c.4f88c112.png' />
116
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif' />
117
+ // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
118
+ // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
119
+ // </InfoPanelImg>
120
+ // // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
121
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
122
+ // // </InfoPanelVideo>
123
+ // )
124
+ // },
125
+ // $setInfoPanel2: () => {
126
+ // controller.openPopUp(
127
+ // <InfoPanelImg url='//vrlab-static.ljcdn.com/release/web/psq/a.8e868cb2.gif' />
128
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/b.f9a1ed52.png' />
129
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/c.4f88c112.png' />
130
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif' />
131
+ // // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
132
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
133
+ // // </InfoPanelImg>
134
+ // // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
135
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
136
+ // // </InfoPanelVideo>
137
+ // )
138
+ // },
139
+ // })
140
+
43
141
  return () => {
44
142
  controller.off(VreoKeyframeEnum.InfoPanel, callback)
45
143
  if (timeoutRef.current) {
@@ -1,7 +1,9 @@
1
1
  import * as React from 'react'
2
+ import * as THREE from 'three'
3
+ import { useController, useFiveInstance } from '../../../hooks'
2
4
  import { ModelTVVideoPlugin } from '../../../../fivePlugins/ModelTVVideoPlugin'
5
+ import { createTransMatrix } from '../../../../shared-utils/createTransMatrix'
3
6
  import { ModelVideoData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
4
- import { useController, useFiveInstance } from '../../../hooks'
5
7
 
6
8
  export function ModelVideo() {
7
9
  const controller = useController()
@@ -15,14 +17,45 @@ export function ModelVideo() {
15
17
  ref.current = ModelTVVideoPlugin(five, {})
16
18
  }
17
19
  const { start, end } = keyframe
18
- const { videoSrc, videoPosterSrc, vertexs } = keyframe.data as ModelVideoData
20
+ const { videoSrc, videoPosterSrc, vertexs, matrixWorld } = keyframe.data as ModelVideoData
21
+
22
+ const position = (() => {
23
+ if (vertexs.length < 4) {
24
+ throw new Error('ModelVideo: 顶点数据集合不够,无法组成矩形 ....')
25
+ }
26
+ if (vertexs.length === 4) {
27
+ return vertexs
28
+ }
29
+
30
+ const box = new THREE.Box3()
31
+ vertexs.forEach((v) => box.expandByPoint(new THREE.Vector3(v.x, v.y, v.z)))
32
+ return [
33
+ new THREE.Vector3(box.min.x, box.max.y, box.max.z),
34
+ new THREE.Vector3(box.min.x, box.min.y, box.max.z),
35
+ new THREE.Vector3(box.max.x, box.min.y, box.max.z),
36
+ new THREE.Vector3(box.max.x, box.max.y, box.max.z),
37
+ ]
38
+ })()
39
+
40
+ const points = (() => {
41
+ if (matrixWorld) {
42
+ const transMatrix = createTransMatrix(matrixWorld)
43
+ return [
44
+ position.map((p) => {
45
+ const res = transMatrix([p.x, p.y, p.z])
46
+ return { x: res[0], y: res[1], z: res[2] }
47
+ }),
48
+ ]
49
+ }
50
+ return [position]
51
+ })()
19
52
 
20
53
  ref.current.disable()
21
54
  await ref.current.load(
22
55
  {
23
- video_src: videoSrc.replace(/https*:/, ''),
24
- video_poster_src: videoPosterSrc.replace(/https*:/, ''),
25
- points: [vertexs],
56
+ video_src: videoSrc,
57
+ video_poster_src: videoPosterSrc,
58
+ points,
26
59
  },
27
60
  controller.configs?.videos?.modelTVVideo
28
61
  )
@@ -30,13 +30,13 @@ export function PanoTextLabel() {
30
30
  if (!res) return
31
31
  const { x: left, y: top } = res
32
32
 
33
- Object.assign(window, { $PanoTextLabel: { setState } })
33
+ // Object.assign(window, { $PanoTextLabel: { setState } })
34
34
  setState({ left, top, text: data.text || '', fontSize: data.fontSize || 16 })
35
35
  timeoutRef.current = setTimeout(() => setState(null), end - start)
36
36
  }
37
37
  controller.on(VreoKeyframeEnum.PanoTextLabel, callback)
38
38
 
39
- Object.assign(window, { $panoTextLabel: { setState } })
39
+ // Object.assign(window, { $panoTextLabel: { setState } })
40
40
  return () => {
41
41
  controller.off(VreoKeyframeEnum.PanoTextLabel, callback)
42
42
  if (timeoutRef.current) {
@@ -2,7 +2,6 @@ import * as React from 'react'
2
2
  import classNames from 'classnames'
3
3
  import { useController } from '../../../hooks'
4
4
 
5
- import { CSSTransition, TransitionGroup } from 'react-transition-group'
6
5
  import { VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
7
6
 
8
7
  export function Prompter() {
@@ -27,7 +26,8 @@ export function Prompter() {
27
26
 
28
27
  ref.current = setTimeout(() => {
29
28
  setHidden(true)
30
- setTimeout(() => setText(''), 500)
29
+ setText('')
30
+ // setTimeout(() => setText(''), 500)
31
31
 
32
32
  if (ref.current) clearTimeout(ref.current)
33
33
  ref.current = null
@@ -48,19 +48,9 @@ export function Prompter() {
48
48
  'vreo-prompter--audio': controller.isAudio,
49
49
  })}
50
50
  >
51
- {text ? (
52
- /* @warning "index.js:1 Warning: findDOMNode is deprecated in StrictMode." */
53
- <TransitionGroup className="vreo-prompter-text">
54
- <CSSTransition
55
- key={text}
56
- classNames="vreo-prompter-text-transition"
57
- timeout={500}
58
- addEndListener={(node, done) => node.addEventListener('transitionend', done, false)}
59
- >
60
- <div className="vreo-prompter-innerText">{text}</div>
61
- </CSSTransition>
62
- </TransitionGroup>
63
- ) : undefined}
51
+ <div className="vreo-prompter-text">
52
+ <div className="vreo-prompter-innerText">{text}</div>
53
+ </div>
64
54
  </div>
65
55
  )
66
56
  }
@@ -1,36 +1,99 @@
1
1
  import * as React from 'react'
2
- import { parseWork } from '@realsee/five'
2
+ import { parseWork, Work } from '@realsee/five'
3
3
  import { useController, useFiveInstance } from '../../../hooks'
4
4
  import { UpdateVRPanoramaData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
5
 
6
6
  export function UpdateVRPanorama() {
7
7
  const controller = useController()
8
8
  const five = useFiveInstance()
9
+ const deafultWorkRef = React.useRef<string[] | null>(null)
10
+ const updateWorkRef = React.useRef<Work | null>(null)
11
+
12
+ // 恢复默认 VR
13
+ const restoreCallback = React.useCallback(() => {
14
+ // 先清理掉 之前的 VR 数据备份
15
+ updateWorkRef.current = null
16
+
17
+ if (deafultWorkRef.current) {
18
+ const work = parseWork(deafultWorkRef.current)
19
+ five.load(work)
20
+ }
21
+
22
+ }, [])
23
+
24
+ // 暂停时: 恢复默认 VR
25
+ const pausedCallback = React.useCallback(() => {
26
+ if (deafultWorkRef.current) {
27
+ const work = parseWork(deafultWorkRef.current)
28
+ Object.assign(window, {$rawWork: work})
29
+ five.load(work)
30
+ }
31
+ }, [])
32
+
33
+ // 播放时:如果暂停前有更新 VR 需要还原
34
+ const playingCallback = React.useCallback(() => {
35
+ if (!updateWorkRef.current) {
36
+ return
37
+ }
38
+ five.load(updateWorkRef.current)
39
+ }, [])
9
40
 
10
41
  React.useEffect(() => {
11
42
  const callback = (keyframe: VreoKeyframe) => {
12
- const { panoIndex, images } = keyframe.data as UpdateVRPanoramaData
43
+ if (!deafultWorkRef.current) {
44
+ deafultWorkRef.current = five.work.raw.works
45
+ }
13
46
 
14
- const newWorkJSON = JSON.parse(JSON.stringify(five.work?.raw.work))
47
+ const data = keyframe.data as UpdateVRPanoramaData
15
48
 
16
- // // 原Work数据不能被修改
17
- if (newWorkJSON.panorama && newWorkJSON.panorama.list && newWorkJSON.panorama.list[panoIndex]) {
18
- Object.assign(newWorkJSON.panorama.list[panoIndex], images)
19
- } else if (newWorkJSON.observers && newWorkJSON.observers[panoIndex] && newWorkJSON.observers[panoIndex].images) {
20
- Object.assign(newWorkJSON.observers[panoIndex].images, images)
49
+ // 如果数据中有新 work 数据,则直接载入
50
+ if (data.work) {
51
+ updateWorkRef.current = parseWork(data.work)
52
+ five.load(updateWorkRef.current)
53
+ return
21
54
  }
22
55
 
23
- const newWork = parseWork(newWorkJSON)
56
+ const lastRawWork = five.work?.raw.works[0]
24
57
 
25
- // // 需要还原么?待定 ...
26
- five.load(newWork)
58
+
59
+ // 动态场景:不提供完成的签名数据,需重新整理
60
+ if (data.dynamic_scene && !data.panorama) {
61
+ const lastWork = JSON.parse(lastRawWork)
62
+ const panorama = lastWork.panorama
63
+ const index = data.dynamic_scene.images.index
64
+ panorama.list[index] = data.dynamic_scene.images
65
+ data.panorama = panorama
66
+ delete data.dynamic_scene
67
+ }
68
+
69
+ Object.assign(window, {$work1: JSON.parse(lastRawWork), $work2: data, parseWork: parseWork})
70
+
71
+ updateWorkRef.current = parseWork([lastRawWork, data])
72
+ five.load(updateWorkRef.current)
27
73
  }
28
74
 
29
75
  controller.on(VreoKeyframeEnum.UpdateVRPanorama, callback)
76
+
77
+ // 离开 将之前的内容清空
78
+ controller.on(VreoKeyframeEnum.Exit, restoreCallback)
79
+
80
+ // 新载入数据 将之前的内容清空
81
+ controller.on('loaded', restoreCallback)
82
+
83
+ // 暂停 回到默认状态
84
+ controller.on('paused', pausedCallback)
85
+ // 播放 回归暂停前状态
86
+ controller.on('playing', playingCallback)
87
+
30
88
  return () => {
89
+ // 清理事件监听
31
90
  controller.off(VreoKeyframeEnum.UpdateVRPanorama, callback)
91
+ controller.off(VreoKeyframeEnum.Exit, restoreCallback)
92
+ controller.off('loaded', restoreCallback)
93
+ controller.off('paused', pausedCallback)
94
+ controller.off('playing', playingCallback)
32
95
  }
33
- }, [controller])
96
+ }, [])
34
97
 
35
98
  return <></>
36
99
  }
@@ -1,4 +1,8 @@
1
- import { VreoKeyframeConfigMap } from '../typings/VreoUnit'
1
+ import React, { ReactNode } from 'react';
2
+ import { Subscribe, Five } from '@realsee/five';
3
+
4
+ import { VreoKeyframeConfigMap, VreoKeyframeEvent } from '../typings/VreoUnit'
5
+ import { VideoAgentMeshOptions } from './modules/VideoAgent/VideoAgentMesh';
2
6
 
3
7
  export interface PlayerConfigs {
4
8
  containter?: ReactDOM.Container
@@ -12,4 +16,20 @@ export interface PlayerConfigs {
12
16
  videoEffect?: HTMLVideoElement
13
17
  modelTVVideo?: HTMLVideoElement
14
18
  }
19
+
20
+ videoAgentMeshOptions?: VideoAgentMeshOptions
21
+ /**
22
+ * 如果需要在 底部面板添加自定义内容,可以传递个 React 组件。
23
+ */
24
+ customPanelChildren?: ReactNode
25
+ customKeyframes?: React.FC<CustomVreoKeyframeProps>[]
26
+ imageOptions?: { size: number }
27
+ autoPreload?: boolean
28
+ }
29
+
30
+ export type VreoSubscribe = Pick<Subscribe<VreoKeyframeEvent>, 'on' | 'once' | 'off'>
31
+
32
+ export interface CustomVreoKeyframeProps {
33
+ subscribe: VreoSubscribe
34
+ five: Five
15
35
  }