@realsee/vreo 0.2.0-alpha.2 → 0.2.0-alpha.20

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 (147) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +80 -5
  3. package/docs/assets/custom.css +2 -2
  4. package/docs/assets/highlight.css +1 -1
  5. package/docs/assets/main.js +2 -2
  6. package/docs/assets/search.js +1 -1
  7. package/docs/assets/style.css +28 -2
  8. package/docs/classes/Player.AudioLike.html +52 -0
  9. package/docs/classes/Player.Controller.html +13 -13
  10. package/docs/classes/Player.Player-1.html +11 -11
  11. package/docs/classes/Player.VideoAgentMesh.html +53 -53
  12. package/docs/classes/Player.VideoAgentScene.html +1 -1
  13. package/docs/demo/assets/AppReact.ec0a6e82.js +1 -0
  14. package/docs/demo/assets/default.55c3f308.css +1 -0
  15. package/docs/demo/assets/default.a5d6dd99.js +3952 -0
  16. package/docs/demo/assets/dynamic.8c30b7ae.js +1 -0
  17. package/docs/demo/assets/examples.dac4a6fe.css +1 -0
  18. package/docs/demo/assets/examples.ddb41c97.js +25 -0
  19. package/docs/demo/assets/index.a7bafdff.css +1 -0
  20. package/docs/demo/assets/index.fc42be2b.js +1 -0
  21. package/docs/demo/assets/main.d119ebf7.js +1 -0
  22. package/docs/demo/assets/react.2d403aee.js +25 -0
  23. package/docs/demo/assets/react.855b3d23.css +1 -0
  24. package/docs/demo/assets/znRoyv06SZQeqA7m.0057e8ae.js +1 -0
  25. package/docs/demo/examples.html +17 -0
  26. package/docs/demo/index-react-dynamic.html +20 -0
  27. package/docs/demo/index-react.html +20 -0
  28. package/docs/demo/index.html +19 -0
  29. package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
  30. package/docs/enums/Player.InfoPanelTypeEnum.html +2 -2
  31. package/docs/enums/Player.PanoEffectEnum.html +2 -2
  32. package/docs/enums/Player.PanoTagEnum.html +2 -2
  33. package/docs/enums/Player.PanoTagStyleEnum.html +7 -0
  34. package/docs/enums/Player.VreoKeyframeEnum.html +12 -12
  35. package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
  36. package/docs/enums/fivePlugins.Rotation.html +1 -1
  37. package/docs/index.html +37 -6
  38. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -1
  39. package/docs/interfaces/Player.PlayerConfigs.html +3 -3
  40. package/docs/interfaces/Player.Vertex.html +2 -2
  41. package/docs/interfaces/Player.VideoAgentMeshOptions.html +8 -1
  42. package/docs/interfaces/Player.VreoKeyframe.html +2 -2
  43. package/docs/interfaces/Player.VreoUnit.html +2 -2
  44. package/docs/interfaces/Player.VreoVideo.html +2 -2
  45. package/docs/interfaces/fivePlugins.CSS3DRenderPluginExportType.html +4 -0
  46. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
  47. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +2 -2
  48. package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +1 -1
  49. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -1
  50. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -1
  51. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -1
  52. package/docs/interfaces/fivePlugins.Vector3Position.html +3 -0
  53. package/docs/interfaces/react.VreoActionCallbacks.html +15 -7
  54. package/docs/interfaces/react.VreoProviderProps.html +1 -1
  55. package/docs/modules/Player.html +21 -15
  56. package/docs/modules/custom.html +1 -1
  57. package/docs/modules/fivePlugins.html +5 -2
  58. package/docs/modules/react.html +1 -1
  59. package/docs/modules.html +1 -1
  60. package/lib/PlayController/createHTMLAudioElement.d.ts +1 -0
  61. package/lib/PlayController/createHTMLAudioElement.js +47 -0
  62. package/lib/PlayController/index.d.ts +38 -0
  63. package/lib/PlayController/index.js +300 -0
  64. package/lib/Player/App.js +5 -4
  65. package/lib/Player/Controller.d.ts +5 -1
  66. package/lib/Player/Controller.js +38 -5
  67. package/lib/Player/custom/SpatialScenePanel/index.d.ts +2 -2
  68. package/lib/Player/custom/SpatialScenePanel/index.js +98 -26
  69. package/lib/Player/index.d.ts +3 -2
  70. package/lib/Player/index.js +116 -24
  71. package/lib/Player/modules/Drawer/index.js +1 -1
  72. package/lib/Player/modules/PopUp/index.d.ts +2 -0
  73. package/lib/Player/modules/PopUp/index.js +43 -0
  74. package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +17 -2
  75. package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +113 -37
  76. package/lib/Player/modules/VideoAgent/VideoAgentScene.d.ts +5 -1
  77. package/lib/Player/modules/VideoAgent/VideoAgentScene.js +9 -4
  78. package/lib/Player/modules/VideoAgent/index.d.ts +2 -0
  79. package/lib/Player/modules/VideoAgent/index.js +2 -2
  80. package/lib/Player/modules/keyframes/BgMusic/index.js +1 -1
  81. package/lib/Player/modules/keyframes/CameraMovement/index.js +42 -6
  82. package/lib/Player/modules/keyframes/InfoPanel/index.js +74 -36
  83. package/lib/Player/modules/keyframes/ModelVideo/index.js +46 -9
  84. package/lib/Player/modules/keyframes/PanoEffect/index.js +1 -1
  85. package/lib/Player/modules/keyframes/PanoEffect/lineAnime.js +1 -1
  86. package/lib/Player/modules/keyframes/PanoTag/index.js +20 -7
  87. package/lib/Player/modules/keyframes/PanoTextLabel/index.d.ts +3 -0
  88. package/lib/Player/modules/keyframes/PanoTextLabel/index.js +96 -51
  89. package/lib/Player/modules/keyframes/Prompter/index.js +5 -19
  90. package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +31 -19
  91. package/lib/Player/modules/keyframes/VideoEffect/index.js +1 -1
  92. package/lib/Player/typings.d.ts +6 -0
  93. package/lib/fivePlugins/CSS3DRenderPlugin/centerPoint.d.ts +2 -0
  94. package/lib/fivePlugins/CSS3DRenderPlugin/centerPoint.js +12 -0
  95. package/lib/fivePlugins/CSS3DRenderPlugin/createResizeObserver.d.ts +7 -0
  96. package/lib/fivePlugins/CSS3DRenderPlugin/createResizeObserver.js +32 -0
  97. package/lib/fivePlugins/CSS3DRenderPlugin/evenNumber.d.ts +3 -0
  98. package/lib/fivePlugins/CSS3DRenderPlugin/evenNumber.js +11 -0
  99. package/lib/fivePlugins/CSS3DRenderPlugin/index.d.ts +56 -0
  100. package/lib/fivePlugins/CSS3DRenderPlugin/index.js +275 -0
  101. package/lib/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.d.ts +7 -0
  102. package/lib/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.js +18 -0
  103. package/lib/fivePlugins/CameraMovementPlugin/index.js +104 -90
  104. package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +1 -0
  105. package/lib/fivePlugins/ModelTVVideoPlugin/index.js +1 -1
  106. package/lib/react/index.d.ts +7 -3
  107. package/lib/react/index.js +3 -3
  108. package/lib/shared-utils/AduioLike.d.ts +37 -0
  109. package/lib/shared-utils/AduioLike.js +165 -0
  110. package/lib/shared-utils/animationFrame/BetterTween.js +7 -3
  111. package/lib/shared-utils/animationFrame/tween.js +1 -1
  112. package/lib/shared-utils/createTransMatrix.d.ts +1 -0
  113. package/lib/shared-utils/createTransMatrix.js +43 -0
  114. package/lib/typings/VreoUnit.d.ts +42 -5
  115. package/lib/typings/VreoUnit.js +26 -6
  116. package/package.json +8 -8
  117. package/resources/PlayController/createHTMLAudioElement.ts +53 -0
  118. package/resources/PlayController/index.ts +167 -0
  119. package/resources/Player/App.tsx +2 -0
  120. package/resources/Player/Controller.ts +155 -121
  121. package/resources/Player/custom/SpatialScenePanel/index.tsx +148 -45
  122. package/resources/Player/index.tsx +186 -110
  123. package/resources/Player/modules/PopUp/index.tsx +26 -0
  124. package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +66 -14
  125. package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +3 -3
  126. package/resources/Player/modules/VideoAgent/index.tsx +3 -2
  127. package/resources/Player/modules/keyframes/CameraMovement/index.tsx +7 -3
  128. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +79 -34
  129. package/resources/Player/modules/keyframes/ModelVideo/index.tsx +36 -3
  130. package/resources/Player/modules/keyframes/PanoTag/index.tsx +31 -12
  131. package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +87 -34
  132. package/resources/Player/modules/keyframes/Prompter/index.tsx +5 -15
  133. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +25 -16
  134. package/resources/Player/typings.ts +5 -0
  135. package/resources/fivePlugins/CSS3DRenderPlugin/centerPoint.ts +5 -0
  136. package/resources/fivePlugins/CSS3DRenderPlugin/createResizeObserver.ts +17 -0
  137. package/resources/fivePlugins/CSS3DRenderPlugin/evenNumber.ts +4 -0
  138. package/resources/fivePlugins/CSS3DRenderPlugin/index.ts +254 -0
  139. package/resources/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.ts +5 -0
  140. package/resources/fivePlugins/CameraMovementPlugin/index.ts +59 -48
  141. package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
  142. package/resources/react/index.tsx +7 -3
  143. package/resources/shared-utils/AduioLike.ts +108 -0
  144. package/resources/shared-utils/createTransMatrix.ts +12 -0
  145. package/resources/typings/VreoUnit.ts +46 -5
  146. package/stylesheets/custom/SpatialScenePanel.css +14 -8
  147. package/stylesheets/default.css +116 -12
@@ -1,6 +1,7 @@
1
1
  import * as THREE from 'three'
2
2
  import { Preloader } from '../../../shared-utils/Preloader'
3
3
  import { makeObservable, observable, runInAction } from 'mobx'
4
+ import AudioLike from '../../../shared-utils/AduioLike'
4
5
 
5
6
  const vertexShader = `
6
7
  varying vec2 vUv;
@@ -63,7 +64,20 @@ const cacheInstance: {
63
64
  } = {}
64
65
 
65
66
  export interface VideoAgentMeshOptions {
67
+ /**
68
+ * 自定义视频实例。
69
+ */
66
70
  videoInstance?: HTMLVideoElement
71
+ /**
72
+ * 自定义音频实例。
73
+ */
74
+ audioInstance?: HTMLAudioElement
75
+ /**
76
+ * 是否开启音频预载能力。**仅对`.mp3`有效**。
77
+ *
78
+ * @description 开启预载能力后会通过 `Fetch/XHR` 方式将音频文件下载转成二进制 [`Blob`](https://developer.mozilla.org/zh-CN/docs/Web/API/Blob) 提供给多媒体实例。这样的好处是 **能够保障音视频播放过程中不卡顿**。 但在部分 iOS 系统中会存在兼容问题——播 25s 之后会静音(`muted` 为 `false`,但是没有声音)。
79
+ */
80
+ preload?: boolean
67
81
  }
68
82
 
69
83
  /**
@@ -75,14 +89,21 @@ export class VideoAgentMesh extends THREE.Mesh {
75
89
  freeze: boolean
76
90
  paused: boolean
77
91
  audioInstance: HTMLAudioElement
92
+ audioLikeInstance: AudioLike
78
93
  $removeEventListener: () => void
79
94
 
80
- get videoInstance(): HTMLAudioElement {
95
+ get videoInstance(): HTMLAudioElement | AudioLike {
96
+ if (!this.videoUrl) {
97
+ return this.audioLikeInstance
98
+ }
99
+
81
100
  if (this.videoUrl?.endsWith('mp3')) {
82
101
  return this.audioInstance
83
102
  }
103
+
84
104
  const uniforms = (this.material as THREE.ShaderMaterial).uniforms
85
105
  const videoInstance = uniforms.map.value.image as HTMLVideoElement
106
+
86
107
  return videoInstance
87
108
  }
88
109
 
@@ -99,7 +120,9 @@ export class VideoAgentMesh extends THREE.Mesh {
99
120
  height: number,
100
121
  widthSegments: number,
101
122
  heightSegments: number,
102
- options: VideoAgentMeshOptions = {},
123
+ options: VideoAgentMeshOptions = {
124
+ preload: true
125
+ },
103
126
  ) {
104
127
  if (!options.videoInstance) {
105
128
  if (cacheInstance.videoInstance) {
@@ -134,10 +157,9 @@ export class VideoAgentMesh extends THREE.Mesh {
134
157
  this.freeze = false
135
158
  this.paused = true
136
159
 
137
- {
160
+ if (!options.audioInstance) {
138
161
  if (cacheInstance.audioInstance) {
139
162
  this.audioInstance = cacheInstance.audioInstance
140
-
141
163
  } else {
142
164
  const audioInstance = document.createElement('audio')
143
165
  audioInstance.crossOrigin = ''
@@ -151,26 +173,42 @@ export class VideoAgentMesh extends THREE.Mesh {
151
173
  this.audioInstance = audioInstance
152
174
  cacheInstance.audioInstance = audioInstance
153
175
  }
154
-
176
+ } else {
177
+ this.audioInstance = options.audioInstance
155
178
  }
156
179
 
180
+ this.audioLikeInstance = new AudioLike()
181
+
157
182
  makeObservable(this, { paused: observable })
158
183
 
159
184
  const updatePaused = (paused: boolean) => runInAction(() => (this.paused = paused))
160
185
  const onPause = () => updatePaused(true)
161
186
  const onPlay = () => updatePaused(false)
187
+ const onEnded = () => {
188
+ console.log('vreo: video 播放结束')
189
+ }
162
190
 
163
- this.videoInstance.addEventListener('pause', onPause)
164
- this.videoInstance.addEventListener('play', onPlay)
191
+ this.audioInstance.addEventListener('pause', onPause)
192
+ this.audioInstance.addEventListener('play', onPlay)
193
+ this.options.videoInstance?.addEventListener('pause', onPause)
194
+ this.options.videoInstance?.addEventListener('play', onPlay)
195
+ this.audioLikeInstance.addEventListener('pause', onPause)
196
+ this.audioLikeInstance.addEventListener('play', onPlay)
197
+ this.options.videoInstance?.addEventListener('ended', onEnded)
165
198
 
166
199
  this.$removeEventListener = () => {
167
- this.videoInstance.removeEventListener('pause', onPause)
168
- this.videoInstance.removeEventListener('play', onPlay)
200
+ this.audioInstance.removeEventListener('pause', onPause)
201
+ this.audioInstance.removeEventListener('play', onPlay)
202
+ this.options.videoInstance?.removeEventListener('pause', onPause)
203
+ this.options.videoInstance?.removeEventListener('play', onPlay)
204
+ this.audioLikeInstance.removeEventListener('pause', onPause)
205
+ this.audioLikeInstance.removeEventListener('play', onPlay)
206
+ this.options.videoInstance?.removeEventListener('ended', onEnded)
169
207
  }
170
208
  }
171
209
 
172
-
173
210
  private async update(videoUrl: string) {
211
+
174
212
  if (this.videoUrl === videoUrl) {
175
213
  return
176
214
  }
@@ -181,7 +219,9 @@ export class VideoAgentMesh extends THREE.Mesh {
181
219
 
182
220
  const uniforms = (this.material as THREE.ShaderMaterial).uniforms
183
221
  this.videoInstance.muted = true
184
- this.videoInstance.src = await URL.createObjectURL((await Preloader.blob(this.videoUrl)) as unknown as Blob)
222
+
223
+ this.videoInstance.src = (this.options.preload || this.options.preload === undefined || this.videoUrl.endsWith('.mp4')) ?
224
+ await URL.createObjectURL((await Preloader.blob(this.videoUrl)) as unknown as Blob) : this.videoUrl
185
225
  this.videoInstance.setAttribute('data-src', this.videoUrl)
186
226
 
187
227
  const onStart = () => {
@@ -190,21 +230,33 @@ export class VideoAgentMesh extends THREE.Mesh {
190
230
  this.videoInstance.muted = false
191
231
  uniforms.enable.value = this.videoUrl?.endsWith('.mp4') ? 1 : 0
192
232
  this.videoInstance.removeEventListener('timeupdate', onStart, false)
233
+
193
234
  }
194
235
 
195
236
  this.videoInstance.addEventListener('timeupdate', onStart, false)
196
237
  }
197
238
 
198
- async play(videoUrl = '') {
239
+ async play(videoUrl = '', currentTime = 0, duration?: number) {
199
240
  videoUrl = videoUrl || ''
241
+ if (duration && !videoUrl) {
242
+ if (this.currentTime) {
243
+ this.videoInstance.currentTime = currentTime
244
+ }
245
+ (this.videoInstance as AudioLike).duration = duration
246
+ this.videoUrl = ''
247
+ this.videoInstance.play()
248
+ return true
249
+ }
250
+
200
251
  if (!videoUrl) {
201
252
  if (this.videoUrl) await this.videoInstance.play()
202
253
  else console.warn('警告:视频资源未初始化。')
203
254
  return true
204
255
  }
205
256
 
257
+ console.log('play', videoUrl, this.videoUrl)
206
258
  if (videoUrl === this.videoUrl) {
207
- this.videoInstance.currentTime = 0
259
+ this.videoInstance.currentTime = currentTime
208
260
  await this.videoInstance.play()
209
261
  return true
210
262
  }
@@ -215,7 +267,7 @@ export class VideoAgentMesh extends THREE.Mesh {
215
267
 
216
268
  return await new Promise((resolve) =>
217
269
  setTimeout(async () => {
218
- this.videoInstance.currentTime = 0
270
+ this.videoInstance.currentTime = currentTime
219
271
  await this.videoInstance.play()
220
272
  resolve(true)
221
273
  }, 20),
@@ -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, preload?: boolean } = {}) {
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)
@@ -37,7 +37,7 @@ export class VideoAgentScene {
37
37
  if (!(this.videoAgentMesh.paused || this.videoAgentMesh.freeze) && this.videoAgentMesh.currentTime > 1000) {
38
38
  this.renderer.render(this.scene, this.camera)
39
39
  }
40
-
40
+
41
41
  // 兼容非视频场景
42
42
  if (!this.videoAgentMesh.videoUrl?.endsWith('.mp4')) {
43
43
  if (domElement.style.display !== 'none') domElement.style.display = 'none'
@@ -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 () => {
@@ -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,6 +1,12 @@
1
1
  import * as React from 'react'
2
2
  import { ReactNode } from 'react'
3
- import { InfoPanelData, InfoPanelTypeEnum, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
3
+ import {
4
+ InfoPanelData,
5
+ InfoPanelStyleEnum,
6
+ InfoPanelTypeEnum,
7
+ VreoKeyframe,
8
+ VreoKeyframeEnum,
9
+ } from '../../../../typings/VreoUnit'
4
10
  import { useController } from '../../../hooks'
5
11
 
6
12
  function InfoPanelImg({ url, children }: { url: string; children?: ReactNode }) {
@@ -16,7 +22,9 @@ function InfoPanelVideo({ url, children }: { url: string; children?: ReactNode }
16
22
  return (
17
23
  <div className="vreo-infoPanel vreo-infoPanel--video">
18
24
  {children}
19
- <div className="vreo-infoPanelWrapper"><video playsInline autoPlay className="vreo-infoPanelVideo" src={url} /></div>
25
+ <div className="vreo-infoPanelWrapper">
26
+ <video playsInline autoPlay className="vreo-infoPanelVideo" src={url} />
27
+ </div>
20
28
  </div>
21
29
  )
22
30
  }
@@ -47,49 +55,86 @@ export function InfoPanel() {
47
55
  if (controller.configs?.keyframeMap.InfoPanel === false) {
48
56
  return
49
57
  }
58
+
50
59
  const callback = (keyframe: VreoKeyframe) => {
51
60
  const { start, end, data } = keyframe
52
61
 
53
62
  const infoPanelData = data as InfoPanelData
54
63
 
55
- const { title, subTitle } = infoPanelData
56
- if (infoPanelData.type === InfoPanelTypeEnum.Image) {
57
- controller.openDrawer({
58
- content: (
59
- <InfoPanelImg url={infoPanelData.url}>
60
- <Title title={title} subTitle={subTitle} />
61
- </InfoPanelImg>
62
- ),
63
- height: '60vh',
64
- })
65
- } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
66
- controller.openDrawer({
67
- content: (
68
- <InfoPanelVideo url={infoPanelData.url}>
69
- <Title title={title} subTitle={subTitle} />
70
- </InfoPanelVideo>
71
- ),
72
- height: '60vh',
73
- })
74
- }
75
- 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)
76
107
  }
77
108
  controller.on(VreoKeyframeEnum.InfoPanel, callback)
78
109
 
79
110
  // Object.assign(window, {
80
111
  // $setInfoPanel: () => {
81
- // controller.openDrawer({
82
- // content: (
83
- // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif'>
84
- // // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
85
- // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
86
- // // </InfoPanelImg>
87
- // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
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">
88
118
  // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
89
- // </InfoPanelVideo>
90
- // ),
91
- // height: '60vh',
92
- // })
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
+ // )
93
138
  // },
94
139
  // })
95
140
 
@@ -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
56
  video_src: videoSrc,
24
57
  video_poster_src: videoPosterSrc,
25
- points: [vertexs],
58
+ points,
26
59
  },
27
60
  controller.configs?.videos?.modelTVVideo
28
61
  )
@@ -2,13 +2,21 @@ import classNames from 'classnames'
2
2
  import * as React from 'react'
3
3
  import { Vector3 } from 'three'
4
4
  import { useController, useFiveInstance, useFiveProject2d } from '../../../hooks'
5
- import { PanoTagData, PanoTagEnum, Vertex, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
+ import {
6
+ PanoTagData,
7
+ PanoTagEnum,
8
+ PanoTagStyleEnum,
9
+ Vertex,
10
+ VreoKeyframe,
11
+ VreoKeyframeEnum,
12
+ } from '../../../../typings/VreoUnit'
6
13
 
7
14
  export function PanoTag() {
8
15
  const [state, setState] = React.useState<{
9
16
  vertex: Vertex
10
17
  text?: string
11
18
  type: PanoTagEnum
19
+ style?: PanoTagStyleEnum
12
20
  imgUrl?: string
13
21
  } | null>(null)
14
22
 
@@ -30,6 +38,7 @@ export function PanoTag() {
30
38
  const vertex = panoTagData.vertex
31
39
  const { x, y, z } = panoTagData.vertex
32
40
  const res = project2d(new Vector3(x, y, z))
41
+
33
42
  if (!res) return
34
43
  const { x: left, y: top } = res
35
44
  setState({
@@ -37,6 +46,7 @@ export function PanoTag() {
37
46
  text: panoTagData.text || PanoTagEnum.Text,
38
47
  type: panoTagData.type,
39
48
  imgUrl: panoTagData.imgUrl,
49
+ style: panoTagData.style || PanoTagStyleEnum.Growth,
40
50
  })
41
51
  setPos({ left, top })
42
52
  timeoutRef.current = setTimeout(() => {
@@ -92,6 +102,25 @@ export function PanoTag() {
92
102
  return undefined
93
103
  })()
94
104
 
105
+ if (state?.style === PanoTagStyleEnum.Expand) {
106
+ return (
107
+ <>
108
+ <div
109
+ className={classNames('PanoTag', {
110
+ 'PanoTag--expand': true,
111
+ 'PanoTag--notHidden': state,
112
+ })}
113
+ style={{
114
+ left: (pos?.left || 0) + 'px',
115
+ top: (pos?.top || 0) + 'px',
116
+ }}
117
+ >
118
+ <div className={'PanoTag-box PanoTag-box--' + (state?.type || '')}>{boxContent}</div>
119
+ <div className="PanoTag-guideline"></div>
120
+ </div>
121
+ </>
122
+ )
123
+ }
95
124
  return (
96
125
  <>
97
126
  <div
@@ -109,17 +138,7 @@ export function PanoTag() {
109
138
  <span className="PanoTag-slashline"></span>
110
139
  <span className="PanoTag-straightline"></span>
111
140
  </span>
112
- <div
113
- onClick={() => {
114
- if (state?.imgUrl) {
115
- // @TODO
116
- // setDrawerVisible(true)
117
- }
118
- }}
119
- className={'PanoTag-box PanoTag-box--' + (state?.type || '')}
120
- >
121
- {boxContent}
122
- </div>
141
+ <div className={'PanoTag-box PanoTag-box--' + (state?.type || '')}>{boxContent}</div>
123
142
  </div>
124
143
  </div>
125
144
  </>