@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.
- package/CHANGELOG.md +5 -0
- package/README.md +80 -5
- package/docs/assets/custom.css +2 -2
- package/docs/assets/highlight.css +1 -1
- package/docs/assets/main.js +2 -2
- package/docs/assets/search.js +1 -1
- package/docs/assets/style.css +28 -2
- package/docs/classes/Player.AudioLike.html +52 -0
- package/docs/classes/Player.Controller.html +13 -13
- package/docs/classes/Player.Player-1.html +11 -11
- package/docs/classes/Player.VideoAgentMesh.html +53 -53
- package/docs/classes/Player.VideoAgentScene.html +1 -1
- package/docs/demo/assets/AppReact.ec0a6e82.js +1 -0
- package/docs/demo/assets/default.55c3f308.css +1 -0
- package/docs/demo/assets/default.a5d6dd99.js +3952 -0
- package/docs/demo/assets/dynamic.8c30b7ae.js +1 -0
- package/docs/demo/assets/examples.dac4a6fe.css +1 -0
- package/docs/demo/assets/examples.ddb41c97.js +25 -0
- package/docs/demo/assets/index.a7bafdff.css +1 -0
- package/docs/demo/assets/index.fc42be2b.js +1 -0
- package/docs/demo/assets/main.d119ebf7.js +1 -0
- package/docs/demo/assets/react.2d403aee.js +25 -0
- package/docs/demo/assets/react.855b3d23.css +1 -0
- package/docs/demo/assets/znRoyv06SZQeqA7m.0057e8ae.js +1 -0
- package/docs/demo/examples.html +17 -0
- package/docs/demo/index-react-dynamic.html +20 -0
- package/docs/demo/index-react.html +20 -0
- package/docs/demo/index.html +19 -0
- package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
- package/docs/enums/Player.InfoPanelTypeEnum.html +2 -2
- package/docs/enums/Player.PanoEffectEnum.html +2 -2
- package/docs/enums/Player.PanoTagEnum.html +2 -2
- package/docs/enums/Player.PanoTagStyleEnum.html +7 -0
- package/docs/enums/Player.VreoKeyframeEnum.html +12 -12
- package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
- package/docs/enums/fivePlugins.Rotation.html +1 -1
- package/docs/index.html +37 -6
- package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -1
- package/docs/interfaces/Player.PlayerConfigs.html +3 -3
- package/docs/interfaces/Player.Vertex.html +2 -2
- package/docs/interfaces/Player.VideoAgentMeshOptions.html +8 -1
- package/docs/interfaces/Player.VreoKeyframe.html +2 -2
- package/docs/interfaces/Player.VreoUnit.html +2 -2
- package/docs/interfaces/Player.VreoVideo.html +2 -2
- package/docs/interfaces/fivePlugins.CSS3DRenderPluginExportType.html +4 -0
- package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
- package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +2 -2
- package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +1 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -1
- package/docs/interfaces/fivePlugins.Vector3Position.html +3 -0
- package/docs/interfaces/react.VreoActionCallbacks.html +15 -7
- package/docs/interfaces/react.VreoProviderProps.html +1 -1
- package/docs/modules/Player.html +21 -15
- package/docs/modules/custom.html +1 -1
- package/docs/modules/fivePlugins.html +5 -2
- package/docs/modules/react.html +1 -1
- package/docs/modules.html +1 -1
- package/lib/PlayController/createHTMLAudioElement.d.ts +1 -0
- package/lib/PlayController/createHTMLAudioElement.js +47 -0
- package/lib/PlayController/index.d.ts +38 -0
- package/lib/PlayController/index.js +300 -0
- package/lib/Player/App.js +5 -4
- package/lib/Player/Controller.d.ts +5 -1
- package/lib/Player/Controller.js +38 -5
- package/lib/Player/custom/SpatialScenePanel/index.d.ts +2 -2
- package/lib/Player/custom/SpatialScenePanel/index.js +98 -26
- package/lib/Player/index.d.ts +3 -2
- package/lib/Player/index.js +116 -24
- package/lib/Player/modules/Drawer/index.js +1 -1
- package/lib/Player/modules/PopUp/index.d.ts +2 -0
- package/lib/Player/modules/PopUp/index.js +43 -0
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +17 -2
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +113 -37
- package/lib/Player/modules/VideoAgent/VideoAgentScene.d.ts +5 -1
- package/lib/Player/modules/VideoAgent/VideoAgentScene.js +9 -4
- package/lib/Player/modules/VideoAgent/index.d.ts +2 -0
- package/lib/Player/modules/VideoAgent/index.js +2 -2
- package/lib/Player/modules/keyframes/BgMusic/index.js +1 -1
- package/lib/Player/modules/keyframes/CameraMovement/index.js +42 -6
- package/lib/Player/modules/keyframes/InfoPanel/index.js +74 -36
- package/lib/Player/modules/keyframes/ModelVideo/index.js +46 -9
- package/lib/Player/modules/keyframes/PanoEffect/index.js +1 -1
- package/lib/Player/modules/keyframes/PanoEffect/lineAnime.js +1 -1
- package/lib/Player/modules/keyframes/PanoTag/index.js +20 -7
- package/lib/Player/modules/keyframes/PanoTextLabel/index.d.ts +3 -0
- package/lib/Player/modules/keyframes/PanoTextLabel/index.js +96 -51
- package/lib/Player/modules/keyframes/Prompter/index.js +5 -19
- package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +31 -19
- package/lib/Player/modules/keyframes/VideoEffect/index.js +1 -1
- package/lib/Player/typings.d.ts +6 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/centerPoint.d.ts +2 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/centerPoint.js +12 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/createResizeObserver.d.ts +7 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/createResizeObserver.js +32 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/evenNumber.d.ts +3 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/evenNumber.js +11 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/index.d.ts +56 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/index.js +275 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.d.ts +7 -0
- package/lib/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.js +18 -0
- package/lib/fivePlugins/CameraMovementPlugin/index.js +104 -90
- package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +1 -0
- package/lib/fivePlugins/ModelTVVideoPlugin/index.js +1 -1
- package/lib/react/index.d.ts +7 -3
- package/lib/react/index.js +3 -3
- package/lib/shared-utils/AduioLike.d.ts +37 -0
- package/lib/shared-utils/AduioLike.js +165 -0
- package/lib/shared-utils/animationFrame/BetterTween.js +7 -3
- package/lib/shared-utils/animationFrame/tween.js +1 -1
- package/lib/shared-utils/createTransMatrix.d.ts +1 -0
- package/lib/shared-utils/createTransMatrix.js +43 -0
- package/lib/typings/VreoUnit.d.ts +42 -5
- package/lib/typings/VreoUnit.js +26 -6
- package/package.json +8 -8
- package/resources/PlayController/createHTMLAudioElement.ts +53 -0
- package/resources/PlayController/index.ts +167 -0
- package/resources/Player/App.tsx +2 -0
- package/resources/Player/Controller.ts +155 -121
- package/resources/Player/custom/SpatialScenePanel/index.tsx +148 -45
- package/resources/Player/index.tsx +186 -110
- package/resources/Player/modules/PopUp/index.tsx +26 -0
- package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +66 -14
- package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +3 -3
- package/resources/Player/modules/VideoAgent/index.tsx +3 -2
- package/resources/Player/modules/keyframes/CameraMovement/index.tsx +7 -3
- package/resources/Player/modules/keyframes/InfoPanel/index.tsx +79 -34
- package/resources/Player/modules/keyframes/ModelVideo/index.tsx +36 -3
- package/resources/Player/modules/keyframes/PanoTag/index.tsx +31 -12
- package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +87 -34
- package/resources/Player/modules/keyframes/Prompter/index.tsx +5 -15
- package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +25 -16
- package/resources/Player/typings.ts +5 -0
- package/resources/fivePlugins/CSS3DRenderPlugin/centerPoint.ts +5 -0
- package/resources/fivePlugins/CSS3DRenderPlugin/createResizeObserver.ts +17 -0
- package/resources/fivePlugins/CSS3DRenderPlugin/evenNumber.ts +4 -0
- package/resources/fivePlugins/CSS3DRenderPlugin/index.ts +254 -0
- package/resources/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.ts +5 -0
- package/resources/fivePlugins/CameraMovementPlugin/index.ts +59 -48
- package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
- package/resources/react/index.tsx +7 -3
- package/resources/shared-utils/AduioLike.ts +108 -0
- package/resources/shared-utils/createTransMatrix.ts +12 -0
- package/resources/typings/VreoUnit.ts +46 -5
- package/stylesheets/custom/SpatialScenePanel.css +14 -8
- 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.
|
|
164
|
-
this.
|
|
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.
|
|
168
|
-
this.
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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.
|
|
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 {
|
|
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"
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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.
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
//
|
|
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
|
-
// </
|
|
90
|
-
//
|
|
91
|
-
//
|
|
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
|
|
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 {
|
|
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
|
</>
|