@realsee/vreo 0.2.0-alpha.5 → 0.2.0-alpha.8
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/README.md +47 -3
- package/docs/assets/custom.css +2 -2
- package/docs/assets/search.js +1 -1
- package/docs/classes/Player.Controller.html +3 -3
- package/docs/classes/Player.Player-1.html +3 -3
- package/docs/classes/Player.VideoAgentMesh.html +11 -11
- package/docs/classes/Player.VideoAgentScene.html +1 -1
- package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
- package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
- package/docs/enums/Player.PanoEffectEnum.html +1 -1
- package/docs/enums/Player.PanoTagEnum.html +1 -1
- 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 +26 -2
- package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -1
- package/docs/interfaces/Player.PlayerConfigs.html +3 -3
- package/docs/interfaces/Player.Vertex.html +1 -1
- package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -1
- package/docs/interfaces/Player.VreoKeyframe.html +1 -1
- package/docs/interfaces/Player.VreoUnit.html +1 -1
- package/docs/interfaces/Player.VreoVideo.html +1 -1
- package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
- package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +2 -2
- 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/react.VreoActionCallbacks.html +6 -6
- package/docs/interfaces/react.VreoProviderProps.html +1 -1
- package/docs/modules/Player.html +13 -13
- package/docs/modules/custom.html +1 -1
- package/docs/modules/fivePlugins.html +2 -2
- package/docs/modules/react.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/Controller.d.ts +2 -0
- package/lib/Player/Controller.js +14 -0
- package/lib/Player/custom/SpatialScenePanel/index.d.ts +2 -2
- package/lib/Player/custom/SpatialScenePanel/index.js +96 -15
- package/lib/Player/index.d.ts +1 -1
- package/lib/Player/index.js +71 -10
- package/lib/Player/modules/PopUp/index.d.ts +2 -0
- package/lib/Player/modules/PopUp/index.js +43 -0
- package/lib/Player/modules/keyframes/CameraMovement/index.js +41 -5
- package/lib/Player/modules/keyframes/InfoPanel/index.js +73 -35
- package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +23 -15
- package/lib/Player/typings.d.ts +4 -0
- package/lib/fivePlugins/CameraMovementPlugin/index.js +101 -90
- package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +3 -2
- package/lib/typings/VreoUnit.d.ts +9 -3
- package/lib/typings/VreoUnit.js +14 -6
- package/package.json +2 -2
- package/resources/PlayController/createHTMLAudioElement.ts +53 -0
- package/resources/PlayController/index.ts +167 -0
- package/resources/Player/Controller.ts +12 -0
- package/resources/Player/custom/SpatialScenePanel/index.tsx +143 -34
- package/resources/Player/index.tsx +36 -2
- package/resources/Player/modules/PopUp/index.tsx +26 -0
- 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/UpdateVRPanorama/index.tsx +20 -15
- package/resources/Player/typings.ts +2 -0
- package/resources/fivePlugins/CameraMovementPlugin/index.ts +55 -47
- package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
- package/resources/typings/VreoUnit.ts +11 -4
- package/stylesheets/custom/SpatialScenePanel.css +14 -8
- package/stylesheets/default.css +66 -0
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
import ReactDOM from 'react-dom'
|
|
3
3
|
import { Five } from '@realsee/five'
|
|
4
|
-
import
|
|
4
|
+
import * as THREE from 'three'
|
|
5
|
+
import { Object3D, Raycaster, Vector3 } from 'three'
|
|
5
6
|
import { tweenProgress } from '@realsee/dnalogel/shared-utils/animationFrame/BetterTween'
|
|
6
7
|
import { CSS3DRenderPlugin, CSS3DRenderPluginExportType } from '@realsee/dnalogel/plugins/CSS3DRenderPlugin'
|
|
7
8
|
|
|
8
9
|
import { VreoKeyframe, VreoKeyframeEnum } from '../../../typings/VreoUnit'
|
|
9
10
|
import { CustomVreoKeyframeProps } from '../../typings'
|
|
10
11
|
|
|
12
|
+
// __debug__
|
|
13
|
+
// const mockData: SpatialScenePanelData = {
|
|
14
|
+
// customType: 'SpatialScenePanel',
|
|
15
|
+
// "stateList": [
|
|
16
|
+
// {
|
|
17
|
+
// "icon": "http://vrlab-public.ljcdn.com/release/seesay/tools/___fc42f951076607a22fd5c54f005ba553.png",
|
|
18
|
+
// "text": "窗帘关闭"
|
|
19
|
+
// },
|
|
20
|
+
// {
|
|
21
|
+
// "icon": "http://vrlab-public.ljcdn.com/release/seesay/tools/___b331e7ad732debc07250a169a3393b13.png",
|
|
22
|
+
// "text": "摄像头休眠"
|
|
23
|
+
// },
|
|
24
|
+
// {
|
|
25
|
+
// "icon": "http://vrlab-public.ljcdn.com/release/seesay/tools/___2e425a81ac0ad88232d50d4e52a9abfa.png",
|
|
26
|
+
// "text": "氛围音乐"
|
|
27
|
+
// },
|
|
28
|
+
// {
|
|
29
|
+
// "icon": "http://vrlab-public.ljcdn.com/release/seesay/tools/___bff48bb81cde37aa6a319d6f5d56e3a4.png",
|
|
30
|
+
// "text": "空调打开"
|
|
31
|
+
// }
|
|
32
|
+
// ],
|
|
33
|
+
// "temperature": "27",
|
|
34
|
+
// "title": "沉浸式回家"
|
|
35
|
+
// }
|
|
11
36
|
export interface SpatialScenePanelData {
|
|
12
37
|
customType: 'SpatialScenePanel'
|
|
13
38
|
title: string
|
|
@@ -16,8 +41,8 @@ export interface SpatialScenePanelData {
|
|
|
16
41
|
text: string
|
|
17
42
|
icon: string
|
|
18
43
|
}[]
|
|
19
|
-
position
|
|
20
|
-
quaternion
|
|
44
|
+
position?: { x: number; y: number; z: number }
|
|
45
|
+
quaternion?: [number, number, number, number]
|
|
21
46
|
}
|
|
22
47
|
|
|
23
48
|
interface SearchParams {
|
|
@@ -25,9 +50,17 @@ interface SearchParams {
|
|
|
25
50
|
// position: Vector3
|
|
26
51
|
// rotation?: Vector3
|
|
27
52
|
// quaternion: [number, number, number, number]
|
|
28
|
-
dom: HTMLDivElement
|
|
53
|
+
dom: HTMLDivElement
|
|
29
54
|
}
|
|
30
55
|
|
|
56
|
+
// const getSphere = (position: Vector3, color = 0xffff00) => {
|
|
57
|
+
// const geometry = new SphereGeometry(0.05, 32, 16)
|
|
58
|
+
// const material = new MeshBasicMaterial({ color })
|
|
59
|
+
// const sphere = new Mesh(geometry, material)
|
|
60
|
+
// sphere.position.copy(position)
|
|
61
|
+
// return sphere
|
|
62
|
+
// }
|
|
63
|
+
|
|
31
64
|
const searchV1 = ({ five, dom }: SearchParams) => {
|
|
32
65
|
const cameraDirection = new Vector3()
|
|
33
66
|
five.camera.getWorldDirection(cameraDirection)
|
|
@@ -35,6 +68,7 @@ const searchV1 = ({ five, dom }: SearchParams) => {
|
|
|
35
68
|
const [intersect] = five.model.intersectRaycaster(new Raycaster(cameraPosition, cameraDirection))
|
|
36
69
|
const point = five.project2d(intersect.point)
|
|
37
70
|
|
|
71
|
+
const widescreen = window.innerWidth > 560 ? true : false
|
|
38
72
|
// const width = dom!.clientWidth
|
|
39
73
|
const height = dom!.clientHeight
|
|
40
74
|
dom!.style.left = point!.x + 'px'
|
|
@@ -48,16 +82,18 @@ const searchV1 = ({ five, dom }: SearchParams) => {
|
|
|
48
82
|
const rightBottom = new Vector3(right, bottom)
|
|
49
83
|
|
|
50
84
|
const points = [leftBottom, rightBottom, rightTop, leftTop].map((point) => {
|
|
51
|
-
point.setX((point.x / window.innerWidth) * 2 -
|
|
52
|
-
point.setY(-(point.y / window.innerHeight) * 2 + 1)
|
|
85
|
+
point.setX((point.x / window.innerWidth) * 2 - (widescreen ? 1.25: 1.75))
|
|
86
|
+
point.setY(-(point.y / window.innerHeight) * 2 + (widescreen ? 1.35: 1.125))
|
|
53
87
|
point.setZ(0.5)
|
|
54
88
|
return point.unproject(five.camera).addScaledVector(cameraDirection, 0.2)
|
|
55
89
|
})
|
|
56
90
|
|
|
91
|
+
// __debug__
|
|
57
92
|
// const colors = [0xdc143c, 0xffff00, 0x0000ff, 0x008000]
|
|
58
93
|
// points.forEach((p, index) => five.scene.add(getSphere(p, colors[index])))
|
|
59
94
|
|
|
60
|
-
|
|
95
|
+
// 判断是手机 150
|
|
96
|
+
const ratio = leftBottom.distanceTo(rightBottom) / (widescreen ? 150 : 120)
|
|
61
97
|
return { points, ratio }
|
|
62
98
|
}
|
|
63
99
|
|
|
@@ -66,12 +102,12 @@ const searchV1 = ({ five, dom }: SearchParams) => {
|
|
|
66
102
|
* @returns
|
|
67
103
|
*/
|
|
68
104
|
export function SpatialScenePanel(props: CustomVreoKeyframeProps) {
|
|
105
|
+
const timeoutRef = React.useRef<NodeJS.Timeout | null>(null)
|
|
69
106
|
const ref = React.useRef<HTMLDivElement>(null)
|
|
70
107
|
const panelRef = React.useRef<HTMLDivElement | null>(null)
|
|
71
108
|
const rendererRef = React.useRef<CSS3DRenderPluginExportType>(CSS3DRenderPlugin(props.five))
|
|
72
109
|
|
|
73
110
|
React.useEffect(() => {
|
|
74
|
-
|
|
75
111
|
if (!ref.current) {
|
|
76
112
|
return
|
|
77
113
|
}
|
|
@@ -83,57 +119,102 @@ export function SpatialScenePanel(props: CustomVreoKeyframeProps) {
|
|
|
83
119
|
|
|
84
120
|
const data = keyframe.data as SpatialScenePanelData
|
|
85
121
|
|
|
122
|
+
// const data = mockData
|
|
86
123
|
const { points, ratio } = searchV1({
|
|
87
124
|
five: props.five,
|
|
88
|
-
dom: ref.current
|
|
125
|
+
dom: ref.current!,
|
|
89
126
|
})
|
|
90
127
|
|
|
91
128
|
const { container, dispose, css3DObject, render } =
|
|
92
129
|
rendererRef.current.create3DDomContainer(points, { ratio, autoRender: false }) || {}
|
|
93
130
|
|
|
131
|
+
Object.assign(window, { $css3DObject: css3DObject })
|
|
94
132
|
if (!container) return
|
|
95
133
|
|
|
96
|
-
|
|
97
134
|
ReactDOM.render(<Panel ref={(ref) => (panelRef.current = ref)} data={data} />, container)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
135
|
+
const startRotateY = -(Math.PI * 2) / 9
|
|
136
|
+
let lastRotateY = 0
|
|
137
|
+
|
|
138
|
+
tweenProgress(1000)
|
|
139
|
+
.onUpdate(({ progress }) => {
|
|
140
|
+
const needRotateY = (Math.PI / 90) * 11 * progress
|
|
141
|
+
const rotateY = needRotateY - lastRotateY
|
|
142
|
+
css3DObject?.rotateY(rotateY)
|
|
143
|
+
// css3DObject?.rotateZ
|
|
144
|
+
lastRotateY = needRotateY
|
|
145
|
+
})
|
|
146
|
+
.onStart(() => {
|
|
147
|
+
css3DObject?.rotateY(startRotateY)
|
|
148
|
+
render!()
|
|
149
|
+
})
|
|
150
|
+
.onDispose(() => {
|
|
151
|
+
panelRef.current?.classList.add('show')
|
|
152
|
+
})
|
|
153
|
+
.play()
|
|
154
|
+
|
|
155
|
+
// Object.assign(window, { $dispose: () => {
|
|
156
|
+
// panelRef.current?.classList.add('hide')
|
|
157
|
+
// setTimeout(() => dispose?.(), 1500)
|
|
158
|
+
// } })
|
|
159
|
+
|
|
160
|
+
const { start, end } = keyframe
|
|
161
|
+
|
|
162
|
+
timeoutRef.current = setTimeout(() => {
|
|
163
|
+
panelRef.current?.classList.add('hide')
|
|
164
|
+
timeoutRef.current = setTimeout(() => {
|
|
165
|
+
dispose?.()
|
|
166
|
+
timeoutRef.current = null
|
|
167
|
+
}, 1500)
|
|
168
|
+
}, end - start)
|
|
120
169
|
}
|
|
121
170
|
|
|
171
|
+
Object.assign(window, { $callback: callback })
|
|
172
|
+
|
|
173
|
+
// setTimeout(() => {callback()}, 8000)
|
|
122
174
|
props.subscribe.on(VreoKeyframeEnum.Custom, callback)
|
|
123
175
|
|
|
124
176
|
return () => {
|
|
125
177
|
props.subscribe.off(VreoKeyframeEnum.Custom, callback)
|
|
178
|
+
if (timeoutRef.current) {
|
|
179
|
+
clearTimeout(timeoutRef.current)
|
|
180
|
+
}
|
|
126
181
|
}
|
|
127
182
|
}, [])
|
|
128
183
|
|
|
129
184
|
return <div className="vreo-SpatialScenePanel" ref={ref}></div>
|
|
130
185
|
}
|
|
131
186
|
|
|
187
|
+
/** 背景动画:控制延迟 */
|
|
188
|
+
function SpatialScenePanelBg() {
|
|
189
|
+
const ref = React.useRef<HTMLDivElement>(null)
|
|
190
|
+
const timeoutRef = React.useRef<NodeJS.Timeout | null>(null)
|
|
191
|
+
React.useEffect(() => {
|
|
192
|
+
if (!ref.current) return
|
|
193
|
+
|
|
194
|
+
const listener = () => {
|
|
195
|
+
ref.current?.setAttribute('class', 'SpatialScenePanel-bg')
|
|
196
|
+
|
|
197
|
+
timeoutRef.current = setTimeout(() => {
|
|
198
|
+
ref.current?.setAttribute('class', 'SpatialScenePanel-bg SpatialScenePanel-bg--animation')
|
|
199
|
+
timeoutRef.current = null
|
|
200
|
+
}, 3000)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
ref.current.addEventListener('animationend', listener)
|
|
204
|
+
|
|
205
|
+
return () => {
|
|
206
|
+
if (ref.current) ref.current.removeEventListener('animationend', listener)
|
|
207
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current)
|
|
208
|
+
}
|
|
209
|
+
}, [])
|
|
210
|
+
return <div ref={ref} className="SpatialScenePanel-bg SpatialScenePanel-bg--animation"></div>
|
|
211
|
+
}
|
|
212
|
+
|
|
132
213
|
const Panel = React.forwardRef(
|
|
133
214
|
(props: { data: SpatialScenePanelData }, myRef: React.LegacyRef<HTMLDivElement> | undefined) => (
|
|
134
215
|
<div className="SpatialScenePanel" ref={myRef}>
|
|
135
216
|
<div className="SpatialScenePanel-show-area">
|
|
136
|
-
<
|
|
217
|
+
<SpatialScenePanelBg />
|
|
137
218
|
<div className="SpatialScenePanel-header">
|
|
138
219
|
<div className="SpatialScenePanel-title">{props.data?.title}</div>
|
|
139
220
|
<div className="SpatialScenePanel-temperature">{props.data?.temperature}℃</div>
|
|
@@ -151,5 +232,33 @@ const Panel = React.forwardRef(
|
|
|
151
232
|
|
|
152
233
|
<div className="SpatialScenePanel-disappear-area"></div>
|
|
153
234
|
</div>
|
|
154
|
-
)
|
|
235
|
+
)
|
|
155
236
|
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
// export function SpatialScenePanel() {
|
|
240
|
+
// // const data = mockData
|
|
241
|
+
|
|
242
|
+
// return (
|
|
243
|
+
// <div className="SpatialScenePanel" >
|
|
244
|
+
// <div className="SpatialScenePanel-show-area">
|
|
245
|
+
// <SpatialScenePanelBg />
|
|
246
|
+
// <div className="SpatialScenePanel-header">
|
|
247
|
+
// <div className="SpatialScenePanel-title">{data?.title}</div>
|
|
248
|
+
// <div className="SpatialScenePanel-temperature">{data?.temperature}℃</div>
|
|
249
|
+
// </div>
|
|
250
|
+
// <div className="SpatialScenePanel-body">
|
|
251
|
+
// {data?.stateList?.map((state, index) => (
|
|
252
|
+
// <div key={`scene-${state.text}`} className={`SpatialScenePanel-item index_${index}`}>
|
|
253
|
+
// <img className="SpatialScenePanel-icon" src={state.icon}></img>
|
|
254
|
+
// <div className="SpatialScenePanel-text">{state.text}</div>
|
|
255
|
+
// <div className="SpatialScenePanel-dot"></div>
|
|
256
|
+
// </div>
|
|
257
|
+
// ))}
|
|
258
|
+
// </div>
|
|
259
|
+
// </div>
|
|
260
|
+
|
|
261
|
+
// <div className="SpatialScenePanel-disappear-area"></div>
|
|
262
|
+
// </div>
|
|
263
|
+
// )
|
|
264
|
+
// }
|
|
@@ -4,10 +4,11 @@ import { Five, Subscribe } from '@realsee/five'
|
|
|
4
4
|
|
|
5
5
|
import { App } from './App'
|
|
6
6
|
import { Controller, ControllerContext } from './Controller'
|
|
7
|
-
import { VreoKeyframeEvent, VreoUnit } from '../typings/VreoUnit'
|
|
7
|
+
import { CameraMovementData, VreoKeyframeEnum, VreoKeyframeEvent, VreoUnit } from '../typings/VreoUnit'
|
|
8
8
|
import { reaction } from 'mobx'
|
|
9
9
|
import { Drawer } from './modules/Drawer'
|
|
10
10
|
import { PlayerConfigs } from './typings'
|
|
11
|
+
import { PopUp } from './modules/PopUp'
|
|
11
12
|
|
|
12
13
|
export class Player extends Subscribe<VreoKeyframeEvent> {
|
|
13
14
|
$five: Five
|
|
@@ -42,6 +43,7 @@ export class Player extends Subscribe<VreoKeyframeEvent> {
|
|
|
42
43
|
<ControllerContext.Provider value={this.controller}>
|
|
43
44
|
<App></App>
|
|
44
45
|
<Drawer />
|
|
46
|
+
<PopUp />
|
|
45
47
|
{this.configs.customKeyframes &&
|
|
46
48
|
this.configs.customKeyframes.map((CustomCmpt, key) => (
|
|
47
49
|
<CustomCmpt
|
|
@@ -67,7 +69,7 @@ export class Player extends Subscribe<VreoKeyframeEvent> {
|
|
|
67
69
|
)
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
async load(vreoUnit: VreoUnit, currentTime = 0) {
|
|
72
|
+
async load(vreoUnit: VreoUnit, currentTime = 0, preload = false) {
|
|
71
73
|
if (!this.controller.visible) {
|
|
72
74
|
this.controller.setVisible(true)
|
|
73
75
|
// 延迟 500ms 规避跟 DOM 动画冲突
|
|
@@ -84,6 +86,38 @@ export class Player extends Subscribe<VreoKeyframeEvent> {
|
|
|
84
86
|
this.controller.vreoUnit = vreoUnit
|
|
85
87
|
this.controller.videoInstance?.pause()
|
|
86
88
|
|
|
89
|
+
// 预载逻辑
|
|
90
|
+
// 是否降低图片分辨率
|
|
91
|
+
if (this.$five.imageOptions.size && this.configs.imageOptions?.size && this.$five.imageOptions.size > this.configs.imageOptions.size) {
|
|
92
|
+
this.$five.imageOptions.size = this.configs.imageOptions.size
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 预载数据中的点位
|
|
96
|
+
if (preload || (preload === undefined && this.configs.autoPreload)) {
|
|
97
|
+
const panoIndexMap = vreoUnit.keyframes.filter((vreoKeyframe) => {
|
|
98
|
+
if (vreoKeyframe.type !== VreoKeyframeEnum.CameraMovement) {
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const data = vreoKeyframe.data as CameraMovementData
|
|
103
|
+
if (data.panoIndex === undefined) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
return true
|
|
107
|
+
}).reduce((accu: Record<number, boolean>, curr) => {
|
|
108
|
+
const panoIndex = curr.data.panoIndex as number
|
|
109
|
+
if (!accu[panoIndex]) {
|
|
110
|
+
accu[panoIndex] = true
|
|
111
|
+
}
|
|
112
|
+
return accu
|
|
113
|
+
}, {})
|
|
114
|
+
|
|
115
|
+
const panoIndexs = Object.keys(panoIndexMap)
|
|
116
|
+
for (let i = 0; i < panoIndexs.length; i++) {
|
|
117
|
+
await this.$five.preloadPano(Number(panoIndexs[i]))
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
87
121
|
// 新数据载入就绪
|
|
88
122
|
this.emit('loaded', vreoUnit)
|
|
89
123
|
if (vreoUnit.video.url) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import classNames from 'classnames'
|
|
3
|
+
import { observer } from 'mobx-react'
|
|
4
|
+
import { Controller } from '../../Controller'
|
|
5
|
+
import { useController } from '../../hooks'
|
|
6
|
+
|
|
7
|
+
const PopUpView = observer(({ controller }: { controller: Controller }) => {
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<div
|
|
11
|
+
className={classNames('vreo-PopUp', {
|
|
12
|
+
'vreo-PopUp-visible': controller.popUp,
|
|
13
|
+
})}
|
|
14
|
+
onClick={() => controller.openPopUp(false)}
|
|
15
|
+
>
|
|
16
|
+
<div className="vreo-PopUp-inner">
|
|
17
|
+
{controller.popUp || ''}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export function PopUp() {
|
|
24
|
+
const controller = useController()
|
|
25
|
+
return <PopUpView controller={controller} />
|
|
26
|
+
}
|
|
@@ -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
|
|
|
@@ -6,49 +6,52 @@ import { UpdateVRPanoramaData, VreoKeyframe, VreoKeyframeEnum } from '../../../.
|
|
|
6
6
|
export function UpdateVRPanorama() {
|
|
7
7
|
const controller = useController()
|
|
8
8
|
const five = useFiveInstance()
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const deafultWorkRef = React.useRef<string[] | null>(null)
|
|
10
|
+
const updateWorkRef = React.useRef<Work | null>(null)
|
|
11
11
|
|
|
12
12
|
const restoreCallback = React.useCallback(() => {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
|
|
14
|
+
if (deafultWorkRef.current) {
|
|
15
|
+
const work = parseWork(deafultWorkRef.current)
|
|
15
16
|
five.load(work)
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
updateWorkRef.current = null
|
|
19
20
|
}, [])
|
|
20
21
|
|
|
21
22
|
const pausedCallback = React.useCallback(() => {
|
|
22
|
-
if (
|
|
23
|
-
const work = parseWork(
|
|
23
|
+
if (deafultWorkRef.current) {
|
|
24
|
+
const work = parseWork(deafultWorkRef.current)
|
|
25
|
+
Object.assign(window, {$rawWork: work})
|
|
24
26
|
five.load(work)
|
|
25
27
|
}
|
|
26
28
|
}, [])
|
|
27
29
|
|
|
28
30
|
const playingCallback = React.useCallback(() => {
|
|
29
|
-
if (!
|
|
31
|
+
if (!updateWorkRef.current) {
|
|
30
32
|
return
|
|
31
33
|
}
|
|
32
|
-
five.load(
|
|
34
|
+
five.load(updateWorkRef.current)
|
|
33
35
|
}, [])
|
|
34
36
|
|
|
35
37
|
React.useEffect(() => {
|
|
36
38
|
const callback = (keyframe: VreoKeyframe) => {
|
|
37
|
-
if (!
|
|
38
|
-
|
|
39
|
+
if (!deafultWorkRef.current) {
|
|
40
|
+
deafultWorkRef.current = five.work.raw.works
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
const data = keyframe.data as UpdateVRPanoramaData
|
|
42
44
|
|
|
43
45
|
// 如果数据中有新 work 数据,则直接载入
|
|
44
46
|
if (data.work) {
|
|
45
|
-
|
|
46
|
-
five.load(
|
|
47
|
+
updateWorkRef.current = parseWork(data.work)
|
|
48
|
+
five.load(updateWorkRef.current)
|
|
47
49
|
return
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
const lastRawWork = five.work?.raw.works[0]
|
|
51
53
|
|
|
54
|
+
|
|
52
55
|
// 动态场景:不提供完成的签名数据,需重新整理
|
|
53
56
|
if (data.dynamic_scene && !data.panorama) {
|
|
54
57
|
const lastWork = JSON.parse(lastRawWork)
|
|
@@ -59,8 +62,10 @@ export function UpdateVRPanorama() {
|
|
|
59
62
|
delete data.dynamic_scene
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
Object.assign(window, {$work1: JSON.parse(lastRawWork), $work2: data, parseWork: parseWork})
|
|
66
|
+
|
|
67
|
+
updateWorkRef.current = parseWork([lastRawWork, data])
|
|
68
|
+
five.load(updateWorkRef.current)
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
controller.on(VreoKeyframeEnum.UpdateVRPanorama, callback)
|
|
@@ -20,6 +20,8 @@ export interface PlayerConfigs {
|
|
|
20
20
|
*/
|
|
21
21
|
customPanelChildren?: ReactNode
|
|
22
22
|
customKeyframes?: React.FC<CustomVreoKeyframeProps>[]
|
|
23
|
+
imageOptions?: { size: number }
|
|
24
|
+
autoPreload?: boolean
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export type VreoSubscribe = Pick<Subscribe<VreoKeyframeEvent>, 'on' | 'once' | 'off'>
|