@realsee/vreo 0.1.0

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 (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +465 -0
  3. package/docs/.nojekyll +1 -0
  4. package/docs/assets/custom.css +52 -0
  5. package/docs/assets/highlight.css +127 -0
  6. package/docs/assets/icons.css +1043 -0
  7. package/docs/assets/icons.png +0 -0
  8. package/docs/assets/icons@2x.png +0 -0
  9. package/docs/assets/main.js +52 -0
  10. package/docs/assets/search.js +1 -0
  11. package/docs/assets/style.css +1388 -0
  12. package/docs/assets/widgets.png +0 -0
  13. package/docs/assets/widgets@2x.png +0 -0
  14. package/docs/classes/Player.Player-1.html +50 -0
  15. package/docs/enums/Player.InfoPanelTypeEnum.html +3 -0
  16. package/docs/enums/Player.PanoEffectEnum.html +5 -0
  17. package/docs/enums/Player.PanoTagEnum.html +3 -0
  18. package/docs/enums/Player.VreoKeyframeEnum.html +388 -0
  19. package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -0
  20. package/docs/enums/fivePlugins.Rotation.html +1 -0
  21. package/docs/index.html +204 -0
  22. package/docs/interfaces/Player.PlayerConfigs.html +4 -0
  23. package/docs/interfaces/Player.Vertex.html +3 -0
  24. package/docs/interfaces/Player.VreoKeyframe.html +3 -0
  25. package/docs/interfaces/Player.VreoUnit.html +3 -0
  26. package/docs/interfaces/Player.VreoVideo.html +3 -0
  27. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -0
  28. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +7 -0
  29. package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +1 -0
  30. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -0
  31. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -0
  32. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -0
  33. package/docs/interfaces/react.VreoActionCallbacks.html +15 -0
  34. package/docs/modules/Player.html +29 -0
  35. package/docs/modules/fivePlugins.html +3 -0
  36. package/docs/modules/react.html +1 -0
  37. package/docs/modules.html +1 -0
  38. package/lib/Player/App.d.ts +2 -0
  39. package/lib/Player/App.js +68 -0
  40. package/lib/Player/Controller.d.ts +39 -0
  41. package/lib/Player/Controller.js +226 -0
  42. package/lib/Player/hooks.d.ts +4 -0
  43. package/lib/Player/hooks.js +41 -0
  44. package/lib/Player/index.d.ts +15 -0
  45. package/lib/Player/index.js +191 -0
  46. package/lib/Player/modules/Drawer/index.d.ts +2 -0
  47. package/lib/Player/modules/Drawer/index.js +67 -0
  48. package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +30 -0
  49. package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +324 -0
  50. package/lib/Player/modules/VideoAgent/VideoAgentScene.d.ts +10 -0
  51. package/lib/Player/modules/VideoAgent/VideoAgentScene.js +65 -0
  52. package/lib/Player/modules/VideoAgent/index.d.ts +4 -0
  53. package/lib/Player/modules/VideoAgent/index.js +44 -0
  54. package/lib/Player/modules/keyframes/CameraMovement/index.d.ts +2 -0
  55. package/lib/Player/modules/keyframes/CameraMovement/index.js +73 -0
  56. package/lib/Player/modules/keyframes/InfoPanel/index.d.ts +2 -0
  57. package/lib/Player/modules/keyframes/InfoPanel/index.js +89 -0
  58. package/lib/Player/modules/keyframes/ModelVideo/index.d.ts +2 -0
  59. package/lib/Player/modules/keyframes/ModelVideo/index.js +87 -0
  60. package/lib/Player/modules/keyframes/PanoEffect/index.d.ts +2 -0
  61. package/lib/Player/modules/keyframes/PanoEffect/index.js +142 -0
  62. package/lib/Player/modules/keyframes/PanoEffect/lineAnime.d.ts +5 -0
  63. package/lib/Player/modules/keyframes/PanoEffect/lineAnime.js +46 -0
  64. package/lib/Player/modules/keyframes/PanoTag/index.d.ts +2 -0
  65. package/lib/Player/modules/keyframes/PanoTag/index.js +168 -0
  66. package/lib/Player/modules/keyframes/PanoTextLabel/index.d.ts +2 -0
  67. package/lib/Player/modules/keyframes/PanoTextLabel/index.js +113 -0
  68. package/lib/Player/modules/keyframes/Prompter/index.d.ts +2 -0
  69. package/lib/Player/modules/keyframes/Prompter/index.js +105 -0
  70. package/lib/Player/modules/keyframes/UpdateVRPanorama/index.d.ts +2 -0
  71. package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +51 -0
  72. package/lib/Player/modules/keyframes/VideoEffect/index.d.ts +2 -0
  73. package/lib/Player/modules/keyframes/VideoEffect/index.js +176 -0
  74. package/lib/Player/typings.d.ts +14 -0
  75. package/lib/Player/typings.js +5 -0
  76. package/lib/fivePlugins/CameraMovementPlugin/index.d.ts +6 -0
  77. package/lib/fivePlugins/CameraMovementPlugin/index.js +307 -0
  78. package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +48 -0
  79. package/lib/fivePlugins/CameraMovementPlugin/typings.js +25 -0
  80. package/lib/fivePlugins/ModelTVVideoPlugin/index.d.ts +20 -0
  81. package/lib/fivePlugins/ModelTVVideoPlugin/index.js +305 -0
  82. package/lib/index.d.ts +1 -0
  83. package/lib/index.js +13 -0
  84. package/lib/react/index.d.ts +42 -0
  85. package/lib/react/index.js +120 -0
  86. package/lib/shared-utils/Preloader.d.ts +6 -0
  87. package/lib/shared-utils/Preloader.js +51 -0
  88. package/lib/shared-utils/animationFrame/BetterTween.d.ts +11 -0
  89. package/lib/shared-utils/animationFrame/BetterTween.js +102 -0
  90. package/lib/shared-utils/animationFrame/index.d.ts +15 -0
  91. package/lib/shared-utils/animationFrame/index.js +68 -0
  92. package/lib/shared-utils/animationFrame/tween.d.ts +75 -0
  93. package/lib/shared-utils/animationFrame/tween.js +76 -0
  94. package/lib/typings/VreoUnit.d.ts +204 -0
  95. package/lib/typings/VreoUnit.js +65 -0
  96. package/package.json +55 -0
  97. package/resources/Player/App.tsx +57 -0
  98. package/resources/Player/Controller.ts +154 -0
  99. package/resources/Player/hooks.ts +28 -0
  100. package/resources/Player/index.tsx +115 -0
  101. package/resources/Player/modules/Drawer/index.tsx +40 -0
  102. package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +202 -0
  103. package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +38 -0
  104. package/resources/Player/modules/VideoAgent/index.tsx +31 -0
  105. package/resources/Player/modules/keyframes/CameraMovement/index.tsx +33 -0
  106. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +52 -0
  107. package/resources/Player/modules/keyframes/ModelVideo/index.tsx +44 -0
  108. package/resources/Player/modules/keyframes/PanoEffect/index.tsx +99 -0
  109. package/resources/Player/modules/keyframes/PanoEffect/lineAnime.ts +31 -0
  110. package/resources/Player/modules/keyframes/PanoTag/index.tsx +127 -0
  111. package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +65 -0
  112. package/resources/Player/modules/keyframes/Prompter/index.tsx +65 -0
  113. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +36 -0
  114. package/resources/Player/modules/keyframes/VideoEffect/index.tsx +115 -0
  115. package/resources/Player/typings.ts +15 -0
  116. package/resources/fivePlugins/CameraMovementPlugin/index.ts +203 -0
  117. package/resources/fivePlugins/CameraMovementPlugin/typings.ts +57 -0
  118. package/resources/fivePlugins/ModelTVVideoPlugin/index.ts +278 -0
  119. package/resources/index.ts +1 -0
  120. package/resources/react/index.tsx +95 -0
  121. package/resources/shared-utils/Preloader.ts +35 -0
  122. package/resources/shared-utils/animationFrame/BetterTween.ts +33 -0
  123. package/resources/shared-utils/animationFrame/index.ts +48 -0
  124. package/resources/shared-utils/animationFrame/tween.ts +51 -0
  125. package/resources/typings/VreoUnit.ts +225 -0
  126. package/stylesheets/default.css +497 -0
@@ -0,0 +1,52 @@
1
+ import * as React from 'react'
2
+ import { InfoPanelData, InfoPanelTypeEnum, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
3
+ import { useController } from '../../../hooks'
4
+
5
+ function InfoPanelImg({ url }: { url: string }) {
6
+ return (
7
+ <div className="vreo-infoPanel vreo-infoPanel--img">
8
+ <img className="vreo-infoPanelImg" src={url} />
9
+ </div>
10
+ )
11
+ }
12
+
13
+ function InfoPanelVideo({ url }: { url: string }) {
14
+ return (
15
+ <div className="vreo-infoPanel vreo-infoPanel--video">
16
+ <video playsInline autoPlay className="vreo-infoPanelVideo" src={url} />
17
+ </div>
18
+ )
19
+ }
20
+
21
+ export function InfoPanel() {
22
+ const timeoutRef = React.useRef<NodeJS.Timeout | null>()
23
+ const controller = useController()
24
+
25
+ React.useEffect(() => {
26
+ if (controller.configs?.keyframeMap.InfoPanel === false) {
27
+ return
28
+ }
29
+ const callback = (keyframe: VreoKeyframe) => {
30
+ const { start, end, data } = keyframe
31
+
32
+ const infoPanelData = data as InfoPanelData
33
+
34
+ if (infoPanelData.type === InfoPanelTypeEnum.Image) {
35
+ controller.openDrawer({ content: <InfoPanelImg url={infoPanelData.url} />, height: '60vh' })
36
+ } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
37
+ controller.openDrawer({ content: <InfoPanelVideo url={infoPanelData.url} />, height: '60vh' })
38
+ }
39
+ timeoutRef.current = setTimeout(() => controller.openDrawer(false), end - start)
40
+ }
41
+ controller.on(VreoKeyframeEnum.InfoPanel, callback)
42
+
43
+ return () => {
44
+ controller.off(VreoKeyframeEnum.InfoPanel, callback)
45
+ if (timeoutRef.current) {
46
+ clearTimeout(timeoutRef.current)
47
+ }
48
+ }
49
+ }, [controller])
50
+
51
+ return <></>
52
+ }
@@ -0,0 +1,44 @@
1
+ import * as React from 'react'
2
+ import { ModelTVVideoPlugin } from '../../../../fivePlugins/ModelTVVideoPlugin'
3
+ import { ModelVideoData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
4
+ import { useController, useFiveInstance } from '../../../hooks'
5
+
6
+ export function ModelVideo() {
7
+ const controller = useController()
8
+ const five = useFiveInstance()
9
+ const ref = React.useRef<ReturnType<typeof ModelTVVideoPlugin>>()
10
+ const timeoutRef = React.useRef<NodeJS.Timeout | null>()
11
+
12
+ React.useEffect(() => {
13
+ const callback = async (keyframe: VreoKeyframe) => {
14
+ if (!ref.current) {
15
+ ref.current = ModelTVVideoPlugin(five, {})
16
+ }
17
+ const { start, end } = keyframe
18
+ const { videoSrc, videoPosterSrc, vertexs } = keyframe.data as ModelVideoData
19
+
20
+ ref.current.disable()
21
+ await ref.current.load(
22
+ {
23
+ video_src: videoSrc.replace(/https*:/, ''),
24
+ video_poster_src: videoPosterSrc.replace(/https*:/, ''),
25
+ points: [vertexs],
26
+ },
27
+ controller.configs?.videos?.modelTVVideo
28
+ )
29
+
30
+ ref.current.enable()
31
+ timeoutRef.current = setTimeout(() => ref.current?.disable(), end - start)
32
+ }
33
+
34
+ controller.on(VreoKeyframeEnum.ModelVideo, callback)
35
+ return () => {
36
+ controller.off(VreoKeyframeEnum.ModelVideo, callback)
37
+ if (timeoutRef.current) {
38
+ clearTimeout(timeoutRef.current)
39
+ }
40
+ }
41
+ }, [controller])
42
+
43
+ return <></>
44
+ }
@@ -0,0 +1,99 @@
1
+ import * as React from 'react'
2
+ import { Vector3 } from 'three'
3
+ import classNames from 'classnames'
4
+
5
+ import lineAnime from './lineAnime'
6
+ import { useController, useFiveInstance, useFiveProject2d } from '../../../hooks'
7
+ import { BetterTween } from '../../../../shared-utils/animationFrame/BetterTween'
8
+ import { PanoEffectData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
9
+
10
+ export function PanoEffect() {
11
+ const [state, setState] = React.useState<{
12
+ center: Vector3
13
+ distance: number
14
+ } | null>(null)
15
+
16
+ const five = useFiveInstance()
17
+ const lineRef = React.useRef<BetterTween<{ progress: number }> | null>(null)
18
+ const [pos, setPos] = React.useState<{ left: number; top: number } | null>(null)
19
+ const timeoutRef = React.useRef<NodeJS.Timeout | null>()
20
+
21
+ const controller = useController()
22
+ const project2d = useFiveProject2d()
23
+
24
+ const delLine = () => {
25
+ if (lineRef.current) {
26
+ lineRef.current.dispose()
27
+ }
28
+ }
29
+
30
+ React.useEffect(() => {
31
+ const callback = (keyframe: VreoKeyframe) => {
32
+ const { start, end, data } = keyframe
33
+
34
+ const videoEffectData = data as PanoEffectData
35
+
36
+ const [v1, v2] = videoEffectData.twoVertexs
37
+ const p1 = new Vector3(v1.x, v1.y, v1.z)
38
+ const p2 = new Vector3(v2.x, v2.y, v2.z)
39
+
40
+ lineRef.current = lineAnime(five, p1.clone(), p2.clone())
41
+ lineRef.current.play()
42
+
43
+ const center = p1.lerp(p2, 0.5)
44
+ const distance = p1.distanceTo(p2)
45
+
46
+ const p = project2d(center)
47
+ if (!p) return
48
+ const { x: left, y: top } = p
49
+ setState({ center, distance })
50
+ setPos({ left, top })
51
+ timeoutRef.current = setTimeout(() => {
52
+ setState(null)
53
+ setPos(null)
54
+ delLine()
55
+ }, end - start)
56
+ }
57
+
58
+ controller.on(VreoKeyframeEnum.PanoEffect, callback)
59
+
60
+ return () => {
61
+ controller.off(VreoKeyframeEnum.PanoEffect, callback)
62
+ if (timeoutRef.current) {
63
+ clearTimeout(timeoutRef.current)
64
+ }
65
+ delLine()
66
+ }
67
+ }, [controller])
68
+
69
+ React.useEffect(() => {
70
+ const callback = () => {
71
+ if (!state?.center) return
72
+ const { x, y, z } = state.center
73
+ const res = project2d(new Vector3(x, y, z))
74
+ if (!res) return
75
+ const { x: left, y: top } = res
76
+ setPos({ left, top })
77
+ }
78
+ five.on('currentStateChange', callback)
79
+ return () => {
80
+ five.off('currentStateChange', callback)
81
+ }
82
+ }, [state?.center])
83
+
84
+ return (
85
+ <>
86
+ <div
87
+ className={classNames('PanoEffect', {
88
+ 'PanoEffect--notHidden': state,
89
+ })}
90
+ style={{
91
+ left: (pos?.left || 0) + 'px',
92
+ top: (pos?.top || 0) + 'px',
93
+ }}
94
+ >
95
+ {state?.distance.toFixed(4) + 'm'}
96
+ </div>
97
+ </>
98
+ )
99
+ }
@@ -0,0 +1,31 @@
1
+ import * as THREE from 'three'
2
+ import { Five } from '@realsee/five'
3
+ import { Line as FiveLine } from '@realsee/five/line'
4
+ import { tweenProgress } from '../../../../shared-utils/animationFrame/BetterTween'
5
+
6
+ export default function lineAnime(five: Five, startPoint: THREE.Vector3, endPoint: THREE.Vector3) {
7
+ const pointImage =
8
+ 'data:image/png;base64,' +
9
+ 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAIVBMVEUAAAD////////////////////////////////////////PIev5AAAACnRSTlMAG/Py2baba05un7UgfgAAAHJJREFUKM9joBpgLHVSCRdA4metAoJlCJHmVWBgAeNzroKCCVCBLpjACqgJVjCBxRBT2FbBQQJYQAohsBAsUIUQWA4WiEIILAULeCEEloAFtBACizAEMLRgGIphLabDMJ2O6TlM72MGECIIMQIZIxqoBQCPvpJ/e9FaAAAAAABJRU5ErkJggg=='
10
+ const pointTexture = new THREE.TextureLoader().load(pointImage)
11
+ const color = new THREE.Color(0xffffff) as any
12
+ const line = new FiveLine()
13
+ line.setMaterial({ linewidth: 2, color })
14
+ const pointMaterial = line.points.material as THREE.PointsMaterial
15
+ pointMaterial.map = pointTexture
16
+ pointMaterial.color.set(color)
17
+ line.line.material.depthTest = false
18
+ return tweenProgress()
19
+ .onUpdate(({ progress }) => {
20
+ const lerpLeft = 0.5 - progress / 2
21
+ const lerpRight = 0.5 + progress / 2
22
+ const leftPoint = startPoint.clone().lerp(endPoint, lerpLeft)
23
+ const rightPoint = startPoint.clone().lerp(endPoint, lerpRight)
24
+ line.setPoints(leftPoint, rightPoint)
25
+ })
26
+ .onStart(() => five.scene.add(line))
27
+ .onDispose(() => {
28
+ five.scene.remove(line)
29
+ five.needsRender = true
30
+ })
31
+ }
@@ -0,0 +1,127 @@
1
+ import classNames from 'classnames'
2
+ import * as React from 'react'
3
+ import { Vector3 } from 'three'
4
+ import { useController, useFiveInstance, useFiveProject2d } from '../../../hooks'
5
+ import { PanoTagData, PanoTagEnum, Vertex, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
6
+
7
+ export function PanoTag() {
8
+ const [state, setState] = React.useState<{
9
+ vertex: Vertex
10
+ text?: string
11
+ type: PanoTagEnum
12
+ imgUrl?: string
13
+ } | null>(null)
14
+
15
+ const [pos, setPos] = React.useState<{ left: number; top: number } | null>(null)
16
+ const timeoutRef = React.useRef<NodeJS.Timeout | null>()
17
+
18
+ const controller = useController()
19
+ const five = useFiveInstance()
20
+ const project2d = useFiveProject2d()
21
+
22
+ React.useEffect(() => {
23
+ if (controller.configs?.keyframeMap.PanoTag === false) {
24
+ return
25
+ }
26
+ const callback = (keyframe: VreoKeyframe) => {
27
+ const { start, end, data } = keyframe
28
+
29
+ const panoTagData = data as PanoTagData
30
+ const vertex = panoTagData.vertex
31
+ const { x, y, z } = panoTagData.vertex
32
+ const res = project2d(new Vector3(x, y, z))
33
+ if (!res) return
34
+ const { x: left, y: top } = res
35
+ setState({
36
+ vertex,
37
+ text: panoTagData.text || PanoTagEnum.Text,
38
+ type: panoTagData.type,
39
+ imgUrl: panoTagData.imgUrl,
40
+ })
41
+ setPos({ left, top })
42
+ timeoutRef.current = setTimeout(() => {
43
+ setState(null)
44
+ setPos(null)
45
+ }, end - start)
46
+ }
47
+
48
+ controller.on(VreoKeyframeEnum.PanoTag, callback)
49
+
50
+ return () => {
51
+ controller.off(VreoKeyframeEnum.PanoTag, callback)
52
+ if (timeoutRef.current) {
53
+ clearTimeout(timeoutRef.current)
54
+ }
55
+ }
56
+ }, [controller])
57
+
58
+ React.useEffect(() => {
59
+ const callback = () => {
60
+ if (!state?.vertex) return
61
+ const { x, y, z } = state.vertex
62
+ const res = project2d(new Vector3(x, y, z))
63
+ if (!res) return
64
+ const { x: left, y: top } = res
65
+ setPos({ left, top })
66
+ }
67
+ five.on('currentStateChange', callback)
68
+
69
+ return () => {
70
+ five.off('currentStateChange', callback)
71
+ }
72
+ }, [state?.vertex])
73
+
74
+ const boxContent = (() => {
75
+ if (!state) return undefined
76
+
77
+ if (state.type === PanoTagEnum.Text) {
78
+ return (
79
+ <>
80
+ <span>{state.text}</span>
81
+ </>
82
+ )
83
+ }
84
+ if (state.type === PanoTagEnum.Image) {
85
+ return (
86
+ <>
87
+ <img className="PanoTag-img" src={state.imgUrl!} alt={state.text || ''}></img>
88
+ <span className="PanoTag-txt">{state.text}</span>
89
+ </>
90
+ )
91
+ }
92
+ return undefined
93
+ })()
94
+
95
+ return (
96
+ <>
97
+ <div
98
+ className={classNames('PanoTag', {
99
+ 'PanoTag--notHidden': state,
100
+ })}
101
+ style={{
102
+ left: (pos?.left || 0) + 'px',
103
+ top: (pos?.top || 0) + 'px',
104
+ }}
105
+ >
106
+ <div className="PanoTag-point"></div>
107
+ <div className="PanoTag-content">
108
+ <span className="PanoTag-linewrap">
109
+ <span className="PanoTag-slashline"></span>
110
+ <span className="PanoTag-straightline"></span>
111
+ </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>
123
+ </div>
124
+ </div>
125
+ </>
126
+ )
127
+ }
@@ -0,0 +1,65 @@
1
+ import classNames from 'classnames'
2
+ import * as React from 'react'
3
+ import { Vector3 } from 'three'
4
+ import { PanoTextLabelData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
+ import { useController, useFiveProject2d } from '../../../hooks'
6
+
7
+ interface PanoTextLabelState {
8
+ text: string
9
+ left: number
10
+ top: number
11
+ fontSize: number
12
+ }
13
+
14
+ export function PanoTextLabel() {
15
+ const [state, setState] = React.useState<PanoTextLabelState | null>(null)
16
+ const timeoutRef = React.useRef<NodeJS.Timeout | null>()
17
+ const controller = useController()
18
+ const project2d = useFiveProject2d()
19
+
20
+ React.useEffect(() => {
21
+ if (controller.configs?.keyframeMap.PanoTextLabel === false) {
22
+ return
23
+ }
24
+ const callback = (keyframe: VreoKeyframe) => {
25
+ const { start, end, data } = keyframe
26
+ const panoTextLabelData = data as PanoTextLabelData
27
+ const { x, y, z } = panoTextLabelData.vertex
28
+
29
+ const res = project2d(new Vector3(x, y, z))
30
+ if (!res) return
31
+ const { x: left, y: top } = res
32
+
33
+ Object.assign(window, { $PanoTextLabel: { setState } })
34
+ setState({ left, top, text: data.text || '', fontSize: data.fontSize || 16 })
35
+ timeoutRef.current = setTimeout(() => setState(null), end - start)
36
+ }
37
+ controller.on(VreoKeyframeEnum.PanoTextLabel, callback)
38
+
39
+ Object.assign(window, { $panoTextLabel: { setState } })
40
+ return () => {
41
+ controller.off(VreoKeyframeEnum.PanoTextLabel, callback)
42
+ if (timeoutRef.current) {
43
+ clearTimeout(timeoutRef.current)
44
+ }
45
+ }
46
+ }, [controller])
47
+
48
+ return (
49
+ <div
50
+ className={classNames('PanoTextLabel', {
51
+ 'PanoTextLabel--notHidden': state,
52
+ })}
53
+ style={{
54
+ left: (state?.left || 0) + 'px',
55
+ top: (state?.top || 0) + 'px',
56
+ }}
57
+ >
58
+ <div className="PanoTextLabel-wrapper">
59
+ <div style={{ fontSize: `${state?.fontSize || 16}px` }} className="PanoText-innerText">
60
+ {state?.text || ''}
61
+ </div>
62
+ </div>
63
+ </div>
64
+ )
65
+ }
@@ -0,0 +1,65 @@
1
+ import * as React from 'react'
2
+ import classNames from 'classnames'
3
+ import { useController } from '../../../hooks'
4
+
5
+ import { CSSTransition, TransitionGroup } from 'react-transition-group'
6
+ import { VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
7
+
8
+ export function Prompter() {
9
+ const [text, setText] = React.useState<string>('')
10
+ const [hidden, setHidden] = React.useState<boolean>(true)
11
+ const ref = React.useRef<NodeJS.Timeout | null>(null)
12
+ const controller = useController()
13
+
14
+ React.useEffect(() => {
15
+ if (controller.configs?.keyframeMap.Prompter === false) {
16
+ return
17
+ }
18
+ const callback = (keyframe: VreoKeyframe) => {
19
+ const { start, end, data } = keyframe
20
+ setText(data.text)
21
+ setHidden(false)
22
+
23
+ if (ref.current) {
24
+ clearTimeout(ref.current)
25
+ ref.current = null
26
+ }
27
+
28
+ ref.current = setTimeout(() => {
29
+ setHidden(true)
30
+ setTimeout(() => setText(''), 500)
31
+
32
+ if (ref.current) clearTimeout(ref.current)
33
+ ref.current = null
34
+ }, end - start)
35
+ }
36
+
37
+ controller.on(VreoKeyframeEnum.Prompter, callback)
38
+
39
+ return () => {
40
+ controller.off(VreoKeyframeEnum.Prompter, callback)
41
+ }
42
+ }, [controller])
43
+
44
+ return (
45
+ <div
46
+ className={classNames('vreo-prompter', {
47
+ 'vreo-prompter--hidden': hidden,
48
+ })}
49
+ >
50
+ {text ? (
51
+ /* @warning "index.js:1 Warning: findDOMNode is deprecated in StrictMode." */
52
+ <TransitionGroup className="vreo-prompter-text">
53
+ <CSSTransition
54
+ key={text}
55
+ classNames="vreo-prompter-text-transition"
56
+ timeout={500}
57
+ addEndListener={(node, done) => node.addEventListener('transitionend', done, false)}
58
+ >
59
+ <div className="vreo-prompter-innerText">{text}</div>
60
+ </CSSTransition>
61
+ </TransitionGroup>
62
+ ) : undefined}
63
+ </div>
64
+ )
65
+ }
@@ -0,0 +1,36 @@
1
+ import * as React from 'react'
2
+ import { parseWork } from '@realsee/five'
3
+ import { useController, useFiveInstance } from '../../../hooks'
4
+ import { UpdateVRPanoramaData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
+
6
+ export function UpdateVRPanorama() {
7
+ const controller = useController()
8
+ const five = useFiveInstance()
9
+
10
+ React.useEffect(() => {
11
+ const callback = (keyframe: VreoKeyframe) => {
12
+ const { panoIndex, images } = keyframe.data as UpdateVRPanoramaData
13
+
14
+ const newWorkJSON = JSON.parse(JSON.stringify(five.work?.raw.work))
15
+
16
+ // // 原Work数据不能被修改
17
+ if (newWorkJSON.panorama && newWorkJSON.panorama.list && newWorkJSON.panorama.list[panoIndex]) {
18
+ Object.assign(newWorkJSON.panorama.list[panoIndex], images)
19
+ } else if (newWorkJSON.observers && newWorkJSON.observers[panoIndex] && newWorkJSON.observers[panoIndex].images) {
20
+ Object.assign(newWorkJSON.observers[panoIndex].images, images)
21
+ }
22
+
23
+ const newWork = parseWork(newWorkJSON)
24
+
25
+ // // 需要还原么?待定 ...
26
+ five.load(newWork)
27
+ }
28
+
29
+ controller.on(VreoKeyframeEnum.UpdateVRPanorama, callback)
30
+ return () => {
31
+ controller.off(VreoKeyframeEnum.UpdateVRPanorama, callback)
32
+ }
33
+ }, [controller])
34
+
35
+ return <></>
36
+ }
@@ -0,0 +1,115 @@
1
+ import classNames from 'classnames'
2
+ import * as React from 'react'
3
+ // import { Preloader } from '../../../../shared-utils/Preloader'
4
+ import { VideoEffectData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
+ import { useController, useFiveInstance } from '../../../hooks'
6
+
7
+ const inlinePlay = (videoInstance?: HTMLVideoElement | null) => {
8
+ if (!videoInstance) return
9
+ const canplaythrough = () => {
10
+ videoInstance.removeEventListener('canplaythrough', canplaythrough)
11
+ try {
12
+ videoInstance.play()
13
+ } catch (error) {}
14
+ }
15
+ videoInstance.addEventListener('canplaythrough', canplaythrough)
16
+ videoInstance.load()
17
+ }
18
+
19
+ // const emptyVideo = '//vrlab-static.ljcdn.com/release/web/leisure.69fd3522.mov'
20
+ const PI = Math.PI
21
+ const PI_2 = PI * 2
22
+
23
+ export function VideoEffect() {
24
+ const ref = React.useRef<HTMLDivElement>(null)
25
+ const videoRef = React.useRef<HTMLVideoElement | null>()
26
+ const controller = useController()
27
+ const timeoutRef = React.useRef<NodeJS.Timeout | null>()
28
+
29
+ const [visible, setVisible] = React.useState(false)
30
+ const five = useFiveInstance()
31
+ const setBlobSrc = (blob: string) => {
32
+ if (!videoRef.current) return
33
+
34
+ videoRef.current.src = blob
35
+ }
36
+
37
+ React.useEffect(() => {
38
+ const callback = async (keyframe: VreoKeyframe) => {
39
+ const { start, end } = keyframe
40
+ const { videoSrc, fov, direction, panoIndex, vector } = keyframe.data as VideoEffectData
41
+ const [longitude, latitude] = (() => {
42
+ if (vector) {
43
+ return [vector.longitude, vector.latitude]
44
+ }
45
+ if (!direction) {
46
+ return [0, 0]
47
+ }
48
+
49
+ let longitude = -Math.atan2(direction.x, -direction.z)
50
+ longitude = ((longitude % PI_2) + PI_2) % PI_2
51
+ const latitude = -Math.asin(direction.y / 1)
52
+ return [longitude, latitude]
53
+ })()
54
+
55
+ five.setState({ fov, panoIndex, longitude, latitude }, true)
56
+ setBlobSrc(videoSrc)
57
+
58
+ inlinePlay(videoRef.current)
59
+ setVisible(true)
60
+
61
+ timeoutRef.current = setTimeout(() => {
62
+ if (!videoRef.current?.paused) {
63
+ videoRef.current?.pause()
64
+ }
65
+ setVisible(false)
66
+ setBlobSrc('')
67
+ }, end - start)
68
+ }
69
+
70
+ controller.on(VreoKeyframeEnum.VideoEffect, callback)
71
+ return () => {
72
+ controller.off(VreoKeyframeEnum.VideoEffect, callback)
73
+ if (timeoutRef.current) {
74
+ clearTimeout(timeoutRef.current)
75
+ }
76
+ }
77
+ }, [controller])
78
+
79
+ React.useEffect(() => {
80
+ if (!ref.current) return
81
+ const video = controller.configs?.videos?.videoEffect || document.createElement('video')
82
+ // <video playsInline key="VideoEffect-video" className="VideoEffect-video" src={blobSrc} />
83
+ video.setAttribute('playsinline', 'true')
84
+ video.setAttribute('webkit-playsinline', 'true')
85
+ video.setAttribute('autoplay', 'true')
86
+ video.setAttribute('key', 'VideoEffect-video')
87
+ video.setAttribute('class', 'VideoEffect-video')
88
+
89
+ videoRef.current = video
90
+ ref.current.append(videoRef.current)
91
+ document.addEventListener(
92
+ 'WeixinJSBridgeReady',
93
+ function () {
94
+ videoRef.current?.play()
95
+ },
96
+ false
97
+ )
98
+
99
+ if (!ref.current) return
100
+ // const asyncfunc = async () => {
101
+ // setBlobSrc(await URL.createObjectURL(await Preloader.blob(emptyVideo)))
102
+ // inlinePlay(videoRef.current)
103
+ // }
104
+ // asyncfunc()
105
+ }, [])
106
+
107
+ return (
108
+ <div
109
+ ref={ref}
110
+ className={classNames('VideoEffect', {
111
+ 'VideoEffect--visible': visible,
112
+ })}
113
+ ></div>
114
+ )
115
+ }
@@ -0,0 +1,15 @@
1
+ import { VreoKeyframeConfigMap } from '../typings/VreoUnit'
2
+
3
+ export interface PlayerConfigs {
4
+ containter?: ReactDOM.Container
5
+ keyframeMap: VreoKeyframeConfigMap
6
+ /**
7
+ * 微信端自动播放功能实现需要提前初始化 Video 实例。
8
+ *
9
+ * 如果需要支持微信浏览器端自动播放需要接入微信SDK及提前初始化好相关 Video 实例。
10
+ */
11
+ videos?: {
12
+ videoEffect?: HTMLVideoElement
13
+ modelTVVideo?: HTMLVideoElement
14
+ }
15
+ }