@realsee/vreo 0.2.0-alpha.1 → 0.2.0-alpha.12
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 +104 -17
- package/docs/assets/custom.css +4 -4
- package/docs/assets/search.js +1 -1
- package/docs/classes/Player.Controller.html +54 -0
- package/docs/classes/Player.Player-1.html +9 -9
- package/docs/classes/Player.VideoAgentMesh.html +142 -0
- package/docs/classes/Player.VideoAgentScene.html +1 -0
- package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
- package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
- package/docs/enums/Player.PanoEffectEnum.html +2 -2
- package/docs/enums/Player.PanoTagEnum.html +1 -1
- package/docs/enums/Player.PanoTagStyleEnum.html +7 -0
- package/docs/enums/Player.VreoKeyframeEnum.html +13 -13
- package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
- package/docs/enums/fivePlugins.Rotation.html +1 -1
- package/docs/index.html +53 -20
- package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -0
- package/docs/interfaces/Player.PlayerConfigs.html +3 -3
- package/docs/interfaces/Player.Vertex.html +1 -1
- package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -0
- 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 +3 -3
- 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/react.VreoActionCallbacks.html +15 -7
- package/docs/interfaces/react.VreoProviderProps.html +1 -0
- package/docs/modules/Player.html +17 -15
- package/docs/modules/custom.html +3 -0
- package/docs/modules/fivePlugins.html +2 -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 +4 -3
- package/lib/Player/Controller.d.ts +2 -0
- package/lib/Player/Controller.js +14 -0
- package/lib/Player/custom/SpatialScenePanel/index.d.ts +22 -0
- package/lib/Player/custom/SpatialScenePanel/index.js +279 -0
- package/lib/Player/index.d.ts +2 -2
- package/lib/Player/index.js +102 -12
- 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 +2 -1
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +26 -20
- package/lib/Player/modules/VideoAgent/VideoAgentScene.d.ts +4 -1
- package/lib/Player/modules/VideoAgent/VideoAgentScene.js +2 -1
- package/lib/Player/modules/VideoAgent/index.d.ts +2 -0
- package/lib/Player/modules/VideoAgent/index.js +1 -1
- package/lib/Player/modules/keyframes/CameraMovement/index.js +41 -5
- package/lib/Player/modules/keyframes/InfoPanel/index.js +84 -36
- package/lib/Player/modules/keyframes/ModelVideo/index.js +45 -8
- package/lib/Player/modules/keyframes/PanoTag/index.js +19 -6
- package/lib/Player/modules/keyframes/PanoTextLabel/index.js +4 -12
- package/lib/Player/modules/keyframes/Prompter/index.js +4 -18
- package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +30 -18
- package/lib/Player/typings.d.ts +15 -2
- package/lib/fivePlugins/CameraMovementPlugin/index.js +104 -90
- package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +1 -0
- package/lib/react/index.d.ts +12 -4
- package/lib/react/index.js +3 -3
- package/lib/shared-utils/createTransMatrix.d.ts +1 -0
- package/lib/shared-utils/createTransMatrix.js +43 -0
- package/lib/typings/VreoUnit.d.ts +32 -6
- package/lib/typings/VreoUnit.js +26 -6
- package/package.json +6 -6
- package/resources/PlayController/createHTMLAudioElement.ts +53 -0
- package/resources/PlayController/index.ts +167 -0
- package/resources/Player/App.tsx +3 -1
- package/resources/Player/Controller.ts +12 -0
- package/resources/Player/custom/SpatialScenePanel/index.tsx +264 -0
- package/resources/Player/index.tsx +59 -4
- package/resources/Player/modules/PopUp/index.tsx +26 -0
- package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +7 -6
- package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +2 -2
- 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 +90 -23
- 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 +2 -2
- 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 +17 -2
- package/resources/fivePlugins/CameraMovementPlugin/index.ts +59 -48
- package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
- package/resources/react/index.tsx +14 -5
- package/resources/shared-utils/createTransMatrix.ts +12 -0
- package/resources/typings/VreoUnit.ts +42 -7
- package/stylesheets/custom/SpatialScenePanel.css +309 -0
- package/stylesheets/default.css +116 -10
|
@@ -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
|
</>
|
|
@@ -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
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
}
|
|
@@ -6,49 +6,56 @@ 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
|
+
// 恢复默认 VR
|
|
12
13
|
const restoreCallback = React.useCallback(() => {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
// 先清理掉 之前的 VR 数据备份
|
|
15
|
+
updateWorkRef.current = null
|
|
16
|
+
|
|
17
|
+
if (deafultWorkRef.current) {
|
|
18
|
+
const work = parseWork(deafultWorkRef.current)
|
|
15
19
|
five.load(work)
|
|
16
20
|
}
|
|
17
21
|
|
|
18
|
-
workRef.current = null
|
|
19
22
|
}, [])
|
|
20
23
|
|
|
24
|
+
// 暂停时: 恢复默认 VR
|
|
21
25
|
const pausedCallback = React.useCallback(() => {
|
|
22
|
-
if (
|
|
23
|
-
const work = parseWork(
|
|
26
|
+
if (deafultWorkRef.current) {
|
|
27
|
+
const work = parseWork(deafultWorkRef.current)
|
|
28
|
+
Object.assign(window, {$rawWork: work})
|
|
24
29
|
five.load(work)
|
|
25
30
|
}
|
|
26
31
|
}, [])
|
|
27
32
|
|
|
33
|
+
// 播放时:如果暂停前有更新 VR 需要还原
|
|
28
34
|
const playingCallback = React.useCallback(() => {
|
|
29
|
-
if (!
|
|
35
|
+
if (!updateWorkRef.current) {
|
|
30
36
|
return
|
|
31
37
|
}
|
|
32
|
-
five.load(
|
|
38
|
+
five.load(updateWorkRef.current)
|
|
33
39
|
}, [])
|
|
34
40
|
|
|
35
41
|
React.useEffect(() => {
|
|
36
42
|
const callback = (keyframe: VreoKeyframe) => {
|
|
37
|
-
if (!
|
|
38
|
-
|
|
43
|
+
if (!deafultWorkRef.current) {
|
|
44
|
+
deafultWorkRef.current = five.work.raw.works
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
const data = keyframe.data as UpdateVRPanoramaData
|
|
42
48
|
|
|
43
49
|
// 如果数据中有新 work 数据,则直接载入
|
|
44
50
|
if (data.work) {
|
|
45
|
-
|
|
46
|
-
five.load(
|
|
51
|
+
updateWorkRef.current = parseWork(data.work)
|
|
52
|
+
five.load(updateWorkRef.current)
|
|
47
53
|
return
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
const lastRawWork = five.work?.raw.works[0]
|
|
51
57
|
|
|
58
|
+
|
|
52
59
|
// 动态场景:不提供完成的签名数据,需重新整理
|
|
53
60
|
if (data.dynamic_scene && !data.panorama) {
|
|
54
61
|
const lastWork = JSON.parse(lastRawWork)
|
|
@@ -59,8 +66,10 @@ export function UpdateVRPanorama() {
|
|
|
59
66
|
delete data.dynamic_scene
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
Object.assign(window, {$work1: JSON.parse(lastRawWork), $work2: data, parseWork: parseWork})
|
|
70
|
+
|
|
71
|
+
updateWorkRef.current = parseWork([lastRawWork, data])
|
|
72
|
+
five.load(updateWorkRef.current)
|
|
64
73
|
}
|
|
65
74
|
|
|
66
75
|
controller.on(VreoKeyframeEnum.UpdateVRPanorama, callback)
|
|
@@ -84,7 +93,7 @@ export function UpdateVRPanorama() {
|
|
|
84
93
|
controller.off('paused', pausedCallback)
|
|
85
94
|
controller.off('playing', playingCallback)
|
|
86
95
|
}
|
|
87
|
-
}, [
|
|
96
|
+
}, [])
|
|
88
97
|
|
|
89
98
|
return <></>
|
|
90
99
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
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';
|
|
3
6
|
|
|
4
7
|
export interface PlayerConfigs {
|
|
5
8
|
containter?: ReactDOM.Container
|
|
@@ -13,8 +16,20 @@ export interface PlayerConfigs {
|
|
|
13
16
|
videoEffect?: HTMLVideoElement
|
|
14
17
|
modelTVVideo?: HTMLVideoElement
|
|
15
18
|
}
|
|
19
|
+
|
|
20
|
+
videoAgentMeshOptions?: VideoAgentMeshOptions
|
|
16
21
|
/**
|
|
17
22
|
* 如果需要在 底部面板添加自定义内容,可以传递个 React 组件。
|
|
18
23
|
*/
|
|
19
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
|
|
20
35
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Five } from '@realsee/five'
|
|
1
|
+
import { Five, MovePanoOptions } from '@realsee/five'
|
|
2
2
|
import type { FivePlugin } from '@realsee/five'
|
|
3
3
|
import * as TWEEN from '@tweenjs/tween.js'
|
|
4
4
|
|
|
@@ -50,63 +50,73 @@ function progressNumber(from: number, to: number, pst: number) {
|
|
|
50
50
|
export const CameraMovementPlugin: FivePlugin<CameraMovementPluginParameterType, CameraMovementPluginExportType> = (
|
|
51
51
|
five: Five,
|
|
52
52
|
) => {
|
|
53
|
-
const move =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
const move = (args: Partial<MoveArgs>, duration: number, opts: MoveOpts = { preload: true }) => {
|
|
54
|
+
return new Promise<boolean>(async (resolve, reject) => {
|
|
55
|
+
|
|
56
|
+
if (opts.asyncStartCallback) {
|
|
57
|
+
opts.asyncStartCallback()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (five.panoIndex === undefined) {
|
|
61
|
+
return reject(false)
|
|
62
|
+
}
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
if (args.mode && args.mode !== five.currentMode) {
|
|
65
|
+
await new Promise((resolve) => {
|
|
66
|
+
if (!args.mode) return
|
|
67
|
+
five.once('modeChange', (mode) => {
|
|
68
|
+
five.once('initAnimationEnded', () => {
|
|
69
|
+
if (mode === args.mode) {
|
|
70
|
+
resolve(true)
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
five.changeMode(args.mode, {
|
|
75
|
+
fov: args.fov || undefined,
|
|
76
|
+
latitude: args.latitude || undefined,
|
|
77
|
+
longitude: args.longitude || undefined,
|
|
78
|
+
panoIndex: args.panoIndex || undefined,
|
|
66
79
|
})
|
|
67
80
|
})
|
|
68
|
-
|
|
69
|
-
fov: args.fov || undefined,
|
|
70
|
-
latitude: args.latitude || undefined,
|
|
71
|
-
longitude: args.longitude || undefined,
|
|
72
|
-
panoIndex: args.panoIndex || undefined,
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
}
|
|
81
|
+
}
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
if (args.mode === Five.Mode.Floorplan) {
|
|
84
|
+
return resolve(true)
|
|
85
|
+
}
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
if (opts.preload && args.panoIndex !== undefined && args.panoIndex !== five.panoIndex) {
|
|
88
|
+
await five.preloadPano(args.panoIndex)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (opts.asyncEndCallback) {
|
|
92
|
+
opts.asyncEndCallback()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
args.panoIndex === undefined &&
|
|
97
|
+
args.fov === undefined &&
|
|
98
|
+
args.latitude === undefined &&
|
|
99
|
+
args.longitude === undefined
|
|
100
|
+
) {
|
|
101
|
+
return resolve(true)
|
|
102
|
+
}
|
|
84
103
|
|
|
85
|
-
if (opts.asyncEndCallback) {
|
|
86
|
-
opts.asyncEndCallback()
|
|
87
|
-
}
|
|
88
104
|
|
|
89
|
-
if (
|
|
90
|
-
args.panoIndex === undefined &&
|
|
91
|
-
args.fov === undefined &&
|
|
92
|
-
args.latitude === undefined &&
|
|
93
|
-
args.longitude === undefined
|
|
94
|
-
) {
|
|
95
|
-
return true
|
|
96
|
-
}
|
|
97
|
-
return await new Promise<boolean>((resolve, reject) => {
|
|
98
105
|
const panoIndex = args.panoIndex !== undefined ? args.panoIndex : five.panoIndex
|
|
106
|
+
|
|
99
107
|
if (panoIndex !== undefined) {
|
|
100
|
-
|
|
108
|
+
const movePanoOptions: MovePanoOptions = Object.assign(args, {
|
|
109
|
+
duration, // 移动耗时
|
|
110
|
+
moveEndCallback: () => resolve(true), // 移动结束
|
|
111
|
+
moveCancelCallback: () => {
|
|
112
|
+
resolve(true)
|
|
113
|
+
}, // 移动开始
|
|
114
|
+
// effect: args.transEffect || 'fade',
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
await five.moveToPano(
|
|
101
118
|
panoIndex,
|
|
102
|
-
|
|
103
|
-
{
|
|
104
|
-
duration, // 移动耗时
|
|
105
|
-
moveEndCallback: () => resolve(true), // 移动结束
|
|
106
|
-
moveCancelCallback: () => reject(false), // 移动开始
|
|
107
|
-
},
|
|
108
|
-
args,
|
|
109
|
-
),
|
|
119
|
+
movePanoOptions,
|
|
110
120
|
)
|
|
111
121
|
} else {
|
|
112
122
|
reject(false)
|
|
@@ -154,6 +164,7 @@ export const CameraMovementPlugin: FivePlugin<CameraMovementPluginParameterType,
|
|
|
154
164
|
five.moveToPano(args.panoIndex, {
|
|
155
165
|
moveEndCallback: () => resolve(true), // 移动结束
|
|
156
166
|
moveCancelCallback: () => reject(false), // 移动开始
|
|
167
|
+
effect: 'fade',
|
|
157
168
|
})
|
|
158
169
|
})
|
|
159
170
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable prettier/prettier */
|
|
2
|
-
import { Mode, Pose } from '@realsee/five'
|
|
2
|
+
import { Mode, MovePanoOptions, Pose } from '@realsee/five'
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
5
5
|
export interface CameraMovementPluginParameterType { }
|
|
@@ -39,6 +39,7 @@ export interface CameraMovementOptsCallback {
|
|
|
39
39
|
export type MoveArgs = {
|
|
40
40
|
mode: Mode
|
|
41
41
|
panoIndex: number
|
|
42
|
+
transEffect?: "fly" | "fade" | "instant"
|
|
42
43
|
} & Pose
|
|
43
44
|
|
|
44
45
|
export type MoveOpts = {
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { unsafe__useFiveInstance } from '@realsee/five/react'
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
import { Player } from '../Player'
|
|
4
|
+
import { PlayerConfigs } from '../Player/typings'
|
|
4
5
|
import { VreoKeyframeEvent, VreoUnit } from '../typings/VreoUnit'
|
|
5
6
|
|
|
6
7
|
const VreoContext = React.createContext<Player | null>(null)
|
|
7
8
|
|
|
8
|
-
export
|
|
9
|
+
export interface VreoProviderProps {
|
|
10
|
+
configs?: Partial<PlayerConfigs>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const VreoProvider: React.FC<VreoProviderProps> = (props ) => {
|
|
9
14
|
const five = unsafe__useFiveInstance()
|
|
10
15
|
|
|
11
16
|
const [player, setPlayer] = React.useState<Player | null>(null)
|
|
12
17
|
const playerRef = React.useRef<Player | null>(null)
|
|
13
18
|
|
|
14
19
|
React.useEffect(() => {
|
|
15
|
-
playerRef.current = new Player(five)
|
|
20
|
+
playerRef.current = new Player(five, props.configs || {})
|
|
16
21
|
setPlayer(playerRef.current)
|
|
17
22
|
|
|
18
23
|
return () => {
|
|
@@ -40,12 +45,16 @@ function useVreoInstance() {
|
|
|
40
45
|
export interface VreoActionCallbacks {
|
|
41
46
|
/**
|
|
42
47
|
* 载入剧本数据。
|
|
48
|
+
* @param vreoUnit 剧本数据
|
|
49
|
+
* @param currentTime 开始时间戳
|
|
50
|
+
* @param preload 是否开启预载
|
|
51
|
+
* @param force 是否强制载入
|
|
43
52
|
*/
|
|
44
|
-
load: (vreoUnit: VreoUnit, currentTime?: number) => Promise<boolean>
|
|
53
|
+
load: (vreoUnit: VreoUnit, currentTime?: number, preload?: boolean, force?: boolean) => Promise<boolean>
|
|
45
54
|
/**
|
|
46
55
|
* 播放。
|
|
47
56
|
*/
|
|
48
|
-
play: () => void
|
|
57
|
+
play: (currentTime?: number) => void
|
|
49
58
|
/**
|
|
50
59
|
* 暂停。
|
|
51
60
|
*/
|
|
@@ -72,7 +81,7 @@ export function useVreoAction() {
|
|
|
72
81
|
[player]
|
|
73
82
|
)
|
|
74
83
|
|
|
75
|
-
const play = React.useCallback(() => player.play(), [player])
|
|
84
|
+
const play = React.useCallback((currentTime?: number) => player.play(currentTime || 0), [player])
|
|
76
85
|
const pause = React.useCallback(() => player.pause(), [player])
|
|
77
86
|
const show = React.useCallback(() => player.show(), [player])
|
|
78
87
|
const hide = React.useCallback(() => player.hide(), [player])
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
|
|
3
|
+
export function createTransMatrix(arr1: number[]) {
|
|
4
|
+
const matrix4 = new THREE.Matrix4()
|
|
5
|
+
matrix4.fromArray(arr1)
|
|
6
|
+
|
|
7
|
+
return (arr2: number[]) => {
|
|
8
|
+
const vector3 = new THREE.Vector3(...arr2)
|
|
9
|
+
vector3.applyMatrix4(matrix4)
|
|
10
|
+
return vector3.toArray()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mode,
|
|
1
|
+
import { Mode, MovePanoOptions, Pose } from '@realsee/five'
|
|
2
2
|
import { CameraMovementEffect, Rotation } from '../fivePlugins/CameraMovementPlugin/typings'
|
|
3
3
|
|
|
4
4
|
export enum VreoKeyframeEnum {
|
|
@@ -65,7 +65,7 @@ export type VreoKeyframeConfigMap = {
|
|
|
65
65
|
* 剧本关键帧
|
|
66
66
|
*/
|
|
67
67
|
export interface VreoKeyframe {
|
|
68
|
-
uuid
|
|
68
|
+
uuid?: string
|
|
69
69
|
type: VreoKeyframeEnum
|
|
70
70
|
start: number
|
|
71
71
|
end: number
|
|
@@ -101,16 +101,22 @@ export interface VreoUnit {
|
|
|
101
101
|
* 剧本事件
|
|
102
102
|
*/
|
|
103
103
|
export type VreoKeyframeEvent = { [key in VreoKeyframeEnum]: (keyframe: VreoKeyframe) => void } & {
|
|
104
|
+
// 新数据载入完成
|
|
104
105
|
loaded: (vreoUnit: VreoUnit) => void
|
|
105
|
-
|
|
106
|
+
// 语音状态 播放 -> 暂停
|
|
107
|
+
paused: (ended?: boolean) => void
|
|
108
|
+
// 语音状态 暂停 -> 播放
|
|
106
109
|
playing: () => void
|
|
110
|
+
// 未知的 剧本帧类型
|
|
111
|
+
unknownKeyframeType: (keyframe: Record<string, any>) => void
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
/**
|
|
110
115
|
* 相机运动
|
|
111
116
|
*/
|
|
112
117
|
export type CameraMovementData = {
|
|
113
|
-
effect
|
|
118
|
+
effect?: CameraMovementEffect
|
|
119
|
+
transEffect?: "fly" | "fade" | "instant"
|
|
114
120
|
mode: Mode
|
|
115
121
|
panoIndex: number
|
|
116
122
|
loop?: boolean
|
|
@@ -133,6 +139,7 @@ export type UpdateVRPanoramaData = {
|
|
|
133
139
|
allow_hosts: string[]
|
|
134
140
|
certificate: string
|
|
135
141
|
expire_at: string
|
|
142
|
+
// 动态场景
|
|
136
143
|
dynamic_scene?: {
|
|
137
144
|
images: {
|
|
138
145
|
index: number
|
|
@@ -157,9 +164,13 @@ export interface Vertex {
|
|
|
157
164
|
}
|
|
158
165
|
|
|
159
166
|
/**
|
|
160
|
-
*
|
|
167
|
+
* 矩形顶点
|
|
161
168
|
*/
|
|
162
169
|
export type QuadrangleVertexs = [Vertex, Vertex, Vertex, Vertex]
|
|
170
|
+
/**
|
|
171
|
+
* 顶点数组
|
|
172
|
+
*/
|
|
173
|
+
export type Vertexs = Vertex[]
|
|
163
174
|
|
|
164
175
|
/**
|
|
165
176
|
* 视频广告
|
|
@@ -176,7 +187,8 @@ export type ModelVideoData = {
|
|
|
176
187
|
/**
|
|
177
188
|
* 视频映射在模型中的顶点
|
|
178
189
|
*/
|
|
179
|
-
vertexs: QuadrangleVertexs
|
|
190
|
+
vertexs: QuadrangleVertexs | Vertexs
|
|
191
|
+
matrixWorld?: number[]
|
|
180
192
|
}
|
|
181
193
|
|
|
182
194
|
/**
|
|
@@ -196,8 +208,23 @@ export enum PanoTagEnum {
|
|
|
196
208
|
Image = 'Image',
|
|
197
209
|
}
|
|
198
210
|
|
|
211
|
+
/**
|
|
212
|
+
* 标签样式种类
|
|
213
|
+
*/
|
|
214
|
+
export enum PanoTagStyleEnum {
|
|
215
|
+
/**
|
|
216
|
+
* 生长动画:默认值
|
|
217
|
+
*/
|
|
218
|
+
Growth = 'Growth',
|
|
219
|
+
/**
|
|
220
|
+
* 展开动画
|
|
221
|
+
*/
|
|
222
|
+
Expand = 'Expand',
|
|
223
|
+
}
|
|
224
|
+
|
|
199
225
|
export type PanoTagData = {
|
|
200
226
|
type: PanoTagEnum
|
|
227
|
+
style: PanoTagStyleEnum
|
|
201
228
|
text: string
|
|
202
229
|
vertex: Vertex
|
|
203
230
|
imgUrl?: string
|
|
@@ -229,13 +256,21 @@ export enum InfoPanelTypeEnum {
|
|
|
229
256
|
Video = 'Video',
|
|
230
257
|
}
|
|
231
258
|
|
|
259
|
+
export enum InfoPanelStyleEnum {
|
|
260
|
+
Drawer = 'Drawer',
|
|
261
|
+
PopUp = 'PopUp',
|
|
262
|
+
}
|
|
263
|
+
|
|
232
264
|
/**
|
|
233
265
|
* 信息面板
|
|
234
266
|
*/
|
|
235
267
|
export type InfoPanelData = {
|
|
236
268
|
type: InfoPanelTypeEnum
|
|
269
|
+
style?: InfoPanelStyleEnum
|
|
237
270
|
url: string
|
|
238
|
-
|
|
271
|
+
// 标题
|
|
272
|
+
title?: string
|
|
273
|
+
// 副标题
|
|
239
274
|
subTitle?: string
|
|
240
275
|
}
|
|
241
276
|
|