@realsee/vreo 1.0.0-alpha.8 → 1.1.0-dev.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 (132) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +46 -36
  3. package/lib/PlayController/index.js +1 -1
  4. package/lib/Player/Controller.d.ts +3 -2
  5. package/lib/Player/Controller.js +31 -14
  6. package/lib/Player/index.js +27 -16
  7. package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +2 -2
  8. package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +7 -12
  9. package/lib/Player/modules/VideoAgent/index.js +1 -1
  10. package/lib/Player/modules/Wave/index.js +160 -25
  11. package/lib/Player/modules/keyframes/BgMusic/index.js +52 -40
  12. package/lib/Player/modules/keyframes/PanoTag/index.js +1 -0
  13. package/lib/fivePlugins/CameraMovementPlugin/index.js +3 -2
  14. package/lib/shared-utils/Audio.d.ts +14 -0
  15. package/lib/shared-utils/Audio.js +158 -0
  16. package/lib/shared-utils/{AduioLike.d.ts → AudioLike.d.ts} +0 -0
  17. package/lib/shared-utils/{AduioLike.js → AudioLike.js} +4 -6
  18. package/lib/shared-utils/animationFrame/tween.d.ts +3 -58
  19. package/lib/shared-utils/animationFrame/tween.js +3 -9
  20. package/lib/typings/VreoUnit.d.ts +8 -5
  21. package/package.json +8 -6
  22. package/stylesheets/default.css +9 -2
  23. package/docs/.nojekyll +0 -1
  24. package/docs/assets/custom.css +0 -78
  25. package/docs/assets/highlight.css +0 -127
  26. package/docs/assets/icons.css +0 -1043
  27. package/docs/assets/icons.png +0 -0
  28. package/docs/assets/icons@2x.png +0 -0
  29. package/docs/assets/main.js +0 -52
  30. package/docs/assets/search.js +0 -1
  31. package/docs/assets/style.css +0 -1414
  32. package/docs/assets/widgets.png +0 -0
  33. package/docs/assets/widgets@2x.png +0 -0
  34. package/docs/classes/Player.AudioLike.html +0 -52
  35. package/docs/classes/Player.Controller.html +0 -54
  36. package/docs/classes/Player.Player-1.html +0 -50
  37. package/docs/classes/Player.VideoAgentMesh.html +0 -142
  38. package/docs/classes/Player.VideoAgentScene.html +0 -1
  39. package/docs/demo/assets/AppReact.6a524c19.js +0 -1
  40. package/docs/demo/assets/default.361f7c9c.js +0 -3988
  41. package/docs/demo/assets/default.63ebc790.css +0 -1
  42. package/docs/demo/assets/dynamic.dc5a9120.js +0 -1
  43. package/docs/demo/assets/examples.a3b2ec8a.js +0 -25
  44. package/docs/demo/assets/examples.dac4a6fe.css +0 -1
  45. package/docs/demo/assets/index.12496cce.js +0 -1
  46. package/docs/demo/assets/index.9331038f.css +0 -1
  47. package/docs/demo/assets/main.b05c3bb6.js +0 -1
  48. package/docs/demo/assets/react.2ee8565f.css +0 -1
  49. package/docs/demo/assets/react.61c6e2de.js +0 -25
  50. package/docs/demo/assets/znRoyv06SZQeqA7m.0057e8ae.js +0 -1
  51. package/docs/demo/examples.html +0 -17
  52. package/docs/demo/index-react-dynamic.html +0 -20
  53. package/docs/demo/index-react.html +0 -20
  54. package/docs/demo/index.html +0 -19
  55. package/docs/enums/Player.InfoPanelStyleEnum.html +0 -1
  56. package/docs/enums/Player.InfoPanelTypeEnum.html +0 -3
  57. package/docs/enums/Player.PanoEffectEnum.html +0 -5
  58. package/docs/enums/Player.PanoTagEnum.html +0 -3
  59. package/docs/enums/Player.PanoTagStyleEnum.html +0 -7
  60. package/docs/enums/Player.VreoKeyframeEnum.html +0 -25
  61. package/docs/enums/fivePlugins.CameraMovementEffect.html +0 -1
  62. package/docs/enums/fivePlugins.Rotation.html +0 -1
  63. package/docs/index.html +0 -245
  64. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +0 -1
  65. package/docs/interfaces/Player.PlayerConfigs.html +0 -7
  66. package/docs/interfaces/Player.Vertex.html +0 -3
  67. package/docs/interfaces/Player.VideoAgentMeshOptions.html +0 -8
  68. package/docs/interfaces/Player.VreoKeyframe.html +0 -3
  69. package/docs/interfaces/Player.VreoUnit.html +0 -3
  70. package/docs/interfaces/Player.VreoVideo.html +0 -3
  71. package/docs/interfaces/fivePlugins.CSS3DRenderPluginExportType.html +0 -4
  72. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +0 -1
  73. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +0 -7
  74. package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +0 -1
  75. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +0 -1
  76. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +0 -1
  77. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +0 -1
  78. package/docs/interfaces/fivePlugins.Vector3Position.html +0 -3
  79. package/docs/interfaces/react.VreoActionCallbacks.html +0 -23
  80. package/docs/interfaces/react.VreoProviderProps.html +0 -1
  81. package/docs/modules/Player.html +0 -37
  82. package/docs/modules/custom.html +0 -3
  83. package/docs/modules/fivePlugins.html +0 -6
  84. package/docs/modules/react.html +0 -1
  85. package/docs/modules.html +0 -1
  86. package/resources/PlayController/createHTMLAudioElement.ts +0 -53
  87. package/resources/PlayController/index.ts +0 -154
  88. package/resources/Player/App.tsx +0 -66
  89. package/resources/Player/Controller.ts +0 -294
  90. package/resources/Player/custom/SpatialScenePanel/index.tsx +0 -264
  91. package/resources/Player/hooks.ts +0 -26
  92. package/resources/Player/index.tsx +0 -227
  93. package/resources/Player/modules/Drawer/index.tsx +0 -40
  94. package/resources/Player/modules/PopUp/index.tsx +0 -26
  95. package/resources/Player/modules/ResizeObserver/index.tsx +0 -23
  96. package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +0 -302
  97. package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +0 -56
  98. package/resources/Player/modules/VideoAgent/index.tsx +0 -53
  99. package/resources/Player/modules/Wave/index.tsx +0 -18
  100. package/resources/Player/modules/keyframes/BgMusic/index.tsx +0 -66
  101. package/resources/Player/modules/keyframes/CameraMovement/index.tsx +0 -37
  102. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +0 -165
  103. package/resources/Player/modules/keyframes/ModelVideo/index.tsx +0 -77
  104. package/resources/Player/modules/keyframes/PanoEffect/index.tsx +0 -99
  105. package/resources/Player/modules/keyframes/PanoEffect/lineAnime.ts +0 -31
  106. package/resources/Player/modules/keyframes/PanoTag/index.tsx +0 -82
  107. package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +0 -117
  108. package/resources/Player/modules/keyframes/Prompter/index.tsx +0 -56
  109. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +0 -99
  110. package/resources/Player/modules/keyframes/VideoEffect/index.tsx +0 -115
  111. package/resources/Player/typings.ts +0 -49
  112. package/resources/fivePlugins/CSS3DRenderPlugin/centerPoint.ts +0 -5
  113. package/resources/fivePlugins/CSS3DRenderPlugin/createResizeObserver.ts +0 -17
  114. package/resources/fivePlugins/CSS3DRenderPlugin/evenNumber.ts +0 -4
  115. package/resources/fivePlugins/CSS3DRenderPlugin/index.ts +0 -254
  116. package/resources/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.ts +0 -5
  117. package/resources/fivePlugins/CameraMovementPlugin/index.ts +0 -226
  118. package/resources/fivePlugins/CameraMovementPlugin/typings.ts +0 -59
  119. package/resources/fivePlugins/ModelTVVideoPlugin/index.ts +0 -278
  120. package/resources/index.ts +0 -1
  121. package/resources/react/index.tsx +0 -121
  122. package/resources/shared-utils/AduioLike.ts +0 -109
  123. package/resources/shared-utils/Preloader.ts +0 -35
  124. package/resources/shared-utils/addResizeListener.ts +0 -46
  125. package/resources/shared-utils/animationFrame/BetterTween.ts +0 -33
  126. package/resources/shared-utils/animationFrame/index.ts +0 -48
  127. package/resources/shared-utils/animationFrame/tween.ts +0 -51
  128. package/resources/shared-utils/createTransMatrix.ts +0 -12
  129. package/resources/shared-utils/getFileExpandedName.ts +0 -6
  130. package/resources/shared-utils/getMediaInfo.ts +0 -52
  131. package/resources/shared-utils/setElementDataset.ts +0 -18
  132. package/resources/typings/VreoUnit.ts +0 -314
@@ -1,226 +0,0 @@
1
- import { Five, MovePanoOptions } from '@realsee/five'
2
- import type { FivePlugin } from '@realsee/five'
3
- import * as TWEEN from '@tweenjs/tween.js'
4
-
5
- import {
6
- CameraMovementPluginParameterType,
7
- CameraMovementPluginExportType,
8
- MoveArgs,
9
- MoveOpts,
10
- RotateArgs,
11
- RotateOpts,
12
- Rotation,
13
- } from './typings'
14
-
15
- import { Easing, tweenProgress } from '../../shared-utils/animationFrame/tween'
16
-
17
- const PI = Math.PI
18
- const PI_2 = PI * 2
19
-
20
- function formatLatitude(rad: number) {
21
- return rad % PI_2
22
- }
23
- function formatLongitude(rad: number) {
24
- return rad % PI_2
25
- }
26
-
27
- const getLongitudeParams = (from: number, to: number, rotation: Rotation): { from: number; to: number } => {
28
- from = formatLongitude(from)
29
- to = formatLongitude(to)
30
-
31
- // 逆时针旋转,初始值必须是较大的值
32
- if (rotation === Rotation.Anticlockwise && from > to) to += PI_2
33
-
34
- // 顺时针旋转,结束值必须是较大值
35
- else if (rotation === Rotation.Clockwise && to > from) from += PI_2
36
-
37
- // Loop 旋转,找锐角旋转
38
- // 如果 to 比 from 大 180°,逆时针转
39
- // 如果 from 比 to 大 180°,顺时针转
40
- else if (rotation !== Rotation.Anticlockwise && rotation !== Rotation.Clockwise && to - from > PI) return getLongitudeParams(from, to, Rotation.Clockwise)
41
- else if (rotation !== Rotation.Anticlockwise && rotation !== Rotation.Clockwise && from - to > PI) return getLongitudeParams(from, to, Rotation.Anticlockwise)
42
- return { from, to }
43
- }
44
-
45
- function progressNumber(from: number, to: number, pst: number) {
46
- return from + (to - from) * pst
47
- }
48
-
49
- /**
50
- * **运镜插件** 模拟类似于电影运镜效果。
51
- */
52
- export const CameraMovementPlugin: FivePlugin<CameraMovementPluginParameterType, CameraMovementPluginExportType> = (
53
- five: Five,
54
- ) => {
55
-
56
- const move = (args: Partial<MoveArgs>, duration: number, opts: MoveOpts = { preload: true }) => {
57
- return new Promise<boolean>(async (resolve, reject) => {
58
-
59
- if (opts.asyncStartCallback) {
60
- opts.asyncStartCallback()
61
- }
62
-
63
- if (five.panoIndex === undefined) {
64
- return reject(false)
65
- }
66
-
67
- if (args.mode && args.mode !== five.currentMode) {
68
- await new Promise((resolve) => {
69
- if (!args.mode) return
70
- five.once('modeChange', (mode) => {
71
- five.once('initAnimationEnded', () => {
72
- if (mode === args.mode) {
73
- resolve(true)
74
- }
75
- })
76
- })
77
- five.changeMode(args.mode, {
78
- fov: args.fov || undefined,
79
- latitude: args.latitude || undefined,
80
- longitude: args.longitude || undefined,
81
- panoIndex: args.panoIndex || undefined,
82
- })
83
- })
84
- }
85
-
86
- if (args.mode === Five.Mode.Floorplan) {
87
- return resolve(true)
88
- }
89
-
90
- if (opts.preload && args.panoIndex !== undefined && args.panoIndex !== five.panoIndex) {
91
- await five.preloadPano(args.panoIndex)
92
- }
93
-
94
- if (opts.asyncEndCallback) {
95
- opts.asyncEndCallback()
96
- }
97
-
98
- if (
99
- args.panoIndex === undefined &&
100
- args.fov === undefined &&
101
- args.latitude === undefined &&
102
- args.longitude === undefined
103
- ) {
104
- return resolve(true)
105
- }
106
-
107
-
108
- const panoIndex = args.panoIndex !== undefined ? args.panoIndex : five.panoIndex
109
-
110
- if (panoIndex !== undefined) {
111
- const movePanoOptions: MovePanoOptions = Object.assign(args, {
112
- duration, // 移动耗时
113
- moveEndCallback: () => resolve(true), // 移动结束
114
- moveCancelCallback: () => {
115
- resolve(true)
116
- }, // 移动开始
117
- // effect: args.transEffect || 'fade',
118
- })
119
-
120
- await five.moveToPano(
121
- panoIndex,
122
- movePanoOptions,
123
- )
124
- } else {
125
- reject(false)
126
- }
127
- })
128
- }
129
-
130
- const getAnimeParams = (args: RotateArgs) => {
131
- const currentFiveState = five.state
132
- // latitude
133
- const fromLatitude = formatLatitude(currentFiveState.latitude)
134
- const toLatitude = formatLatitude(args.latitude)
135
- // longitude
136
- const { from: fromLongitude, to: toLongitude } = getLongitudeParams(
137
- currentFiveState.longitude,
138
- args.longitude,
139
- args.rotation || Rotation.Loop,
140
- )
141
- // fov
142
- const fromFov = currentFiveState.fov
143
- const toFov = args.fov
144
- return {
145
- from: { latitude: fromLatitude, longitude: fromLongitude, fov: fromFov },
146
- to: { latitude: toLatitude, longitude: toLongitude, fov: toFov },
147
- }
148
- }
149
-
150
- const rotate = async (args: RotateArgs, duration: number, opts: RotateOpts = {}) => {
151
- if (opts.asyncStartCallback) {
152
- opts.asyncStartCallback()
153
- }
154
-
155
- // 先切换模型再出旋转效果
156
- if (args.mode && five.currentMode !== args.mode) {
157
- await five.changeMode(args.mode)
158
- }
159
-
160
- // 全景状态下,需要点位对齐
161
- if (args.mode === Five.Mode.Panorama &&
162
- five.currentMode === Five.Mode.Panorama &&
163
- args.panoIndex !== undefined &&
164
- args.panoIndex !== five.panoIndex) {
165
- if (opts.preload) await five.preloadPano(args.panoIndex)
166
- await new Promise((resolve, reject) => {
167
- five.moveToPano(args.panoIndex, {
168
- moveEndCallback: () => resolve(true), // 移动结束
169
- moveCancelCallback: () => reject(false), // 移动开始
170
- effect: 'fade',
171
- })
172
- })
173
- }
174
-
175
- if (opts.asyncEndCallback) {
176
- opts.asyncEndCallback()
177
- }
178
-
179
- const { from, to } = getAnimeParams(args)
180
- return await new Promise<boolean>((resolve, reject) => {
181
- const onUpdate = ({ progress }: { progress: number }) => {
182
- const state: Record<string, number> = {}
183
- state.longitude = progressNumber(from.longitude, to.longitude, progress) % PI_2
184
- state.latitude = progressNumber(from.latitude, to.latitude, progress)
185
- state.fov = progressNumber(from.fov, to.fov, progress)
186
- five.setState(state, true)
187
- }
188
-
189
- const onComplete = () => {
190
- resolve(true)
191
- }
192
-
193
- const onDestroy = () => {
194
- resolve(false)
195
- }
196
-
197
- let animeDuration = duration
198
-
199
- if (args.rotation === Rotation.Loop) {
200
- animeDuration = args.rotateSpeed
201
- ? Math.ceil((Math.abs(to.longitude - from.longitude) / args.rotateSpeed) * 1000)
202
- : duration
203
- }
204
-
205
- type _Tween = TWEEN.Tween<{ progress: number }> & { onDestroy: (p: any) => _Tween; destroy: () => void }
206
-
207
- const tween = (tweenProgress(animeDuration, Easing.Linear.None) as _Tween)
208
- .onUpdate(onUpdate)
209
- .onComplete(onComplete)
210
- .onDestroy(onDestroy)
211
- if (args.rotation === Rotation.Loop) {
212
- tween.repeat(Infinity).yoyo(true)
213
- }
214
- setTimeout(() => {
215
- // 总时间到了之后强制结束,同时也是 Loop 模式的结束方式
216
- tween.destroy()
217
- resolve(true)
218
- }, duration)
219
- })
220
- }
221
-
222
- return {
223
- move,
224
- rotate,
225
- }
226
- }
@@ -1,59 +0,0 @@
1
- /* eslint-disable prettier/prettier */
2
- import { Mode, MovePanoOptions, Pose } from '@realsee/five'
3
-
4
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
5
- export interface CameraMovementPluginParameterType { }
6
-
7
- export interface CameraMovementPluginExportType {
8
- /**
9
- * 运镜:移动
10
- * @param moveArgs
11
- * @param duration
12
- * @param opts
13
- */
14
- move(moveArgs: Partial<MoveArgs>, duration: number, opts?: MoveOpts): Promise<boolean>
15
- /**
16
- * 运镜:旋转
17
- * @param args
18
- * @param duration
19
- * @param opts
20
- */
21
- rotate(args: RotateArgs, duration: number, opts?: RotateOpts): Promise<boolean>
22
- }
23
-
24
- export enum CameraMovementEffect {
25
- Move = 'Move',
26
- Rotate = 'Rotate',
27
- }
28
- export enum Rotation {
29
- Clockwise = 'Clockwise',
30
- Anticlockwise = 'Anticlockwise',
31
- Loop = 'Loop',
32
- }
33
-
34
- export interface CameraMovementOptsCallback {
35
- asyncStartCallback?: () => void
36
- asyncEndCallback?: () => void
37
- }
38
-
39
- export type MoveArgs = {
40
- mode: Mode
41
- panoIndex: number
42
- transEffect?: "fly" | "fade" | "instant"
43
- } & Pose
44
-
45
- export type MoveOpts = {
46
- preload?: boolean
47
- } & CameraMovementOptsCallback
48
-
49
- export type RotateArgs = {
50
- mode?: Mode
51
- panoIndex: number
52
- loop: boolean
53
- rotateSpeed: number
54
- rotation: Rotation
55
- } & Pose
56
-
57
- export type RotateOpts = {
58
- preload?: boolean
59
- } & CameraMovementOptsCallback
@@ -1,278 +0,0 @@
1
- import * as THREE from 'three'
2
- import type { FivePlugin } from '@realsee/five'
3
-
4
- export interface ModelTVVideoPluginData {
5
- enable?: boolean
6
- video_src: string
7
- video_poster_src: string
8
- points: { x: number; y: number; z: number }[][]
9
- }
10
-
11
- export interface ModelTVVideoPluginParameterType {
12
- videoElement?: HTMLVideoElement
13
- }
14
- export interface ModelTVVideoPluginExportType {
15
- enable: () => void
16
- disable: () => void
17
- load: (data: ModelTVVideoPluginData, videoElement?: HTMLVideoElement) => Promise<void>
18
- }
19
-
20
- type ModelTVVideoPluginPoints = THREE.Vector3[][]
21
-
22
- type ModelTVVideoPluginState = {
23
- videoMeshes: THREE.Mesh<THREE.BufferGeometry, THREE.MeshBasicMaterial>[]
24
- videoTextureEnabled: boolean
25
- videoSource: string
26
- rectPoints: ModelTVVideoPluginPoints
27
- enabled: boolean
28
- imageTexture?: THREE.Texture
29
- videoTexture?: THREE.VideoTexture
30
- videoElement?: HTMLVideoElement
31
- }
32
-
33
- export const ModelTVVideoPlugin: FivePlugin<ModelTVVideoPluginParameterType, ModelTVVideoPluginExportType> = (
34
- five,
35
- { videoElement },
36
- ) => {
37
- const state: ModelTVVideoPluginState = {
38
- videoMeshes: [],
39
- videoTextureEnabled: false,
40
- videoSource: '',
41
- rectPoints: [],
42
- enabled: false,
43
- videoElement: videoElement,
44
- }
45
-
46
- const setMuted = (muted: boolean) => {
47
- if (state.videoTexture) {
48
- state.videoTexture.image.muted = muted
49
- state.videoTexture.image.play()
50
- }
51
- }
52
- const getMuted = () => {
53
- if (state.videoTexture) return state.videoTexture.image.muted
54
- else return true
55
- }
56
-
57
- const enable = () => {
58
- if (state.enabled) return
59
- if (!state.videoTexture) return
60
-
61
- state.enabled = true
62
- state.videoMeshes = createPanoVideoMeshes()
63
- state.videoMeshes.forEach((mesh) => five.scene.add(mesh))
64
-
65
- const play = () => {
66
- if (!state.videoTexture) return
67
-
68
- const timeupdate = () => {
69
- if (!state.videoTexture) return
70
- state.videoTexture?.image.removeEventListener('timeupdate', timeupdate)
71
- state.videoTextureEnabled = true
72
- state.videoMeshes.forEach((mesh) => {
73
- if (mesh.material.map !== state.videoTexture) mesh.material.map = state.videoTexture!
74
- })
75
- five.needsRender = true
76
- }
77
- state.videoTexture.image.addEventListener('timeupdate', timeupdate)
78
- if (state.videoTexture && state.videoMeshes.length) {
79
- state.videoTexture.image.play()
80
- }
81
- }
82
-
83
- if (five.model.loaded) play()
84
- else {
85
- return five.once('modelLoaded', () => play())
86
- }
87
- }
88
-
89
- const disable = () => {
90
- if (!state.enabled) return
91
- state.enabled = false
92
- state.videoMeshes.forEach((mesh) => {
93
- mesh.geometry.dispose()
94
- mesh.material.dispose()
95
- five.scene.remove(mesh)
96
- if (state.videoTexture) state.videoTexture.image.pause()
97
- })
98
- state.videoMeshes = []
99
- five.needsRender = true
100
- }
101
-
102
- const createPanoVideoMeshes = () => {
103
- return state.rectPoints.map((points, index) => {
104
- const geometry = new THREE.BufferGeometry()
105
- const segments = 128
106
-
107
- const verticesArray: number[] = []
108
- verticesArray.push(points[0].x, points[0].y, points[0].z)
109
- for (let i = 1; i < segments; i++) {
110
- verticesArray.push(
111
- points[0].x + ((points[1].x - points[0].x) * i) / segments,
112
- points[0].y + ((points[1].y - points[0].y) * i) / segments,
113
- points[0].z + ((points[1].z - points[0].z) * i) / segments,
114
- )
115
- }
116
- verticesArray.push(points[1].x, points[1].y, points[1].z)
117
- verticesArray.push(points[2].x, points[2].y, points[2].z)
118
- for (let i = 1; i < segments; i++) {
119
- verticesArray.push(
120
- points[2].x + ((points[3].x - points[2].x) * i) / segments,
121
- points[2].y + ((points[3].y - points[2].y) * i) / segments,
122
- points[2].z + ((points[3].z - points[2].z) * i) / segments,
123
- )
124
- }
125
- verticesArray.push(points[3].x, points[3].y, points[3].z)
126
-
127
- const uvArray: number[] = []
128
- uvArray.push(0, 1)
129
- for (let i = 1; i < segments; i++) {
130
- uvArray.push(0, 1 - i / segments)
131
- }
132
- uvArray.push(0, 0)
133
- uvArray.push(1, 0)
134
- for (let i = 1; i < segments; i++) {
135
- uvArray.push(1, i / segments)
136
- }
137
- uvArray.push(1, 1)
138
-
139
- const indicesArray: number[] = []
140
- for (let i = 0; i < segments; i++) {
141
- indicesArray.push(i, i + 1, segments * 2 - i, i, segments * 2 - i, segments * 2 + 1 - i)
142
- }
143
- geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(verticesArray), 3))
144
- geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvArray), 2))
145
- geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(indicesArray), 1))
146
- const material = new THREE.MeshBasicMaterial({
147
- map: state.videoTextureEnabled ? state.videoTexture : state.imageTexture,
148
- side: THREE.DoubleSide,
149
- })
150
- const mesh = new THREE.Mesh(geometry, material)
151
- mesh.renderOrder = 1
152
- mesh.name = `video-${index}-${performance.now()}`
153
- return mesh
154
- })
155
- }
156
-
157
- const getImageTexture = (source: string) => {
158
- const texture = new THREE.TextureLoader().load(source)
159
- texture.minFilter = THREE.LinearFilter
160
- texture.magFilter = THREE.LinearFilter
161
- texture.format = THREE.RGBFormat
162
- return texture
163
- }
164
-
165
- const getVideoTexture = (
166
- source: string,
167
- video?: HTMLVideoElement,
168
- ): Promise<THREE.VideoTexture & { videoSource: string }> => {
169
- return new Promise((resolve, reject) => {
170
- const xhr = new XMLHttpRequest()
171
- xhr.onreadystatechange = () => {
172
- if (xhr.readyState == 4) {
173
- if (xhr.status == 200) {
174
- const url = window.URL || window.webkitURL
175
- video = video || document.createElement('video')
176
- video.crossOrigin = 'anonymous'
177
- video.autoplay = true
178
- video.muted = true
179
- video.loop = true
180
- video.playsInline = true
181
- video.src = url.createObjectURL(xhr.response)
182
- const texture = new THREE.VideoTexture(video)
183
- texture.minFilter = THREE.LinearFilter
184
- texture.magFilter = THREE.LinearFilter
185
- texture.format = THREE.RGBFormat
186
- resolve(Object.assign(texture, { videoSource: source }))
187
- } else {
188
- reject(new Error('Video download Error: ' + xhr.status))
189
- }
190
- }
191
- }
192
- xhr.onerror = (error) => reject(error)
193
- xhr.open('GET', source)
194
- xhr.responseType = 'blob'
195
- xhr.send()
196
- })
197
- }
198
-
199
- const load = async (data: ModelTVVideoPluginData, videoElement?: HTMLVideoElement) => {
200
- const { video_src, video_poster_src, points } = data
201
- state.videoSource = video_src
202
- state.rectPoints = points.map((items) => items.map(({ x, y, z }) => new THREE.Vector3(x, y, z)))
203
- state.imageTexture = getImageTexture(video_poster_src)
204
-
205
- if (videoElement) {
206
- state.videoElement = videoElement
207
- }
208
-
209
- state.videoTexture = await getVideoTexture(state.videoSource, state.videoElement)
210
-
211
- state.enabled = !!data.enable
212
- if (state.enabled) enable()
213
- }
214
-
215
- five.on('modeChange', () => setMuted(true))
216
-
217
- five.on('wantsTapGesture', (raycaster) => {
218
- if (!state.enabled) return
219
- const [intersect] = raycaster.intersectObjects(five.scene.children, true)
220
- if (!!intersect && /^video/.test(intersect.object.name)) {
221
- if (state.videoTexture) setMuted(!state.videoTexture.image.muted)
222
- return false
223
- }
224
- })
225
-
226
- five.on('panoArrived', () => {
227
- if (!state.enabled) return
228
- if (getMuted()) return
229
- const cameraPosition = five.camera.position
230
-
231
- const visible = state.rectPoints.find((points) => {
232
- const centerVector = points.reduce(
233
- (total, curr) =>
234
- new THREE.Vector3(
235
- total.x + curr.x / points.length,
236
- total.y + curr.y / points.length,
237
- total.z + curr.z / points.length,
238
- ),
239
- new THREE.Vector3(),
240
- )
241
-
242
- return (
243
- points
244
- .map(
245
- (point) =>
246
- new THREE.Vector3(
247
- (point.x + centerVector.x) / 2,
248
- (point.y + centerVector.y) / 2,
249
- (point.z + centerVector.z) / 2,
250
- ),
251
- )
252
- .filter((vector) => {
253
- vector = vector.clone().sub(cameraPosition).normalize()
254
- const raycaster = new THREE.Raycaster(cameraPosition, vector)
255
- const [intersect] = raycaster.intersectObjects(five.scene.children, true)
256
- return !!intersect && /^video/.test(intersect.object.name)
257
- }).length >= 2
258
- )
259
- })
260
- if (!visible) setMuted(true)
261
- })
262
-
263
- five.on('renderFrame', () => {
264
- state.videoMeshes.forEach((meshes) => {
265
- if (meshes)
266
- //@ts-ignore
267
- meshes.needsRender = true
268
- })
269
- })
270
-
271
- five.on('load', (input) => {
272
- if (input.modelTVVideoData) {
273
- load(input.modelTVVideoData)
274
- }
275
- })
276
-
277
- return { enable, disable, load }
278
- }
@@ -1 +0,0 @@
1
- export { Player } from './Player'
@@ -1,121 +0,0 @@
1
- import { unsafe__useFiveInstance } from '@realsee/five/react'
2
- import * as React from 'react'
3
- import { Player } from '../Player'
4
- import { PlayerConfigs } from '../Player/typings'
5
- import { VreoKeyframeEvent, VreoUnit } from '../typings/VreoUnit'
6
-
7
- const VreoContext = React.createContext<Player | null>(null)
8
-
9
- export interface VreoProviderProps {
10
- configs?: Partial<PlayerConfigs>
11
- }
12
-
13
- export const VreoProvider: React.FC<VreoProviderProps> = (props ) => {
14
- const five = unsafe__useFiveInstance()
15
-
16
- const [player, setPlayer] = React.useState<Player | null>(null)
17
- const playerRef = React.useRef<Player | null>(null)
18
-
19
- React.useEffect(() => {
20
- playerRef.current = new Player(five, props.configs || {})
21
- setPlayer(playerRef.current)
22
-
23
- return () => {
24
- playerRef.current?.dispose()
25
- }
26
- }, [])
27
-
28
- if (!player) return <></>
29
-
30
- return <VreoContext.Provider value={player}>{props.children}</VreoContext.Provider>
31
- }
32
-
33
- function useVreoInstance() {
34
- const context = React.useContext(VreoContext)
35
- if (!context) {
36
- throw new Error('VreoProvider never found.')
37
- }
38
-
39
- return context
40
- }
41
-
42
- /**
43
- * VreoPlayer 命令集合。
44
- */
45
- export interface VreoActionCallbacks {
46
- /**
47
- * 载入剧本数据。
48
- * @param vreoUnit 剧本数据
49
- * @param currentTime 开始时间戳
50
- * @param preload 是否开启预载
51
- * @param force 是否强制载入
52
- */
53
- load: (vreoUnit: VreoUnit, currentTime?: number, preload?: boolean, force?: boolean) => Promise<boolean>
54
- /**
55
- * 播放。
56
- */
57
- play: (currentTime?: number) => void
58
- /**
59
- * 暂停。
60
- */
61
- pause: () => void
62
- /**
63
- * 显示 UI 面板。
64
- */
65
- show: () => void
66
- /**
67
- * 隐藏 UI 面板。
68
- */
69
- hide: () => void
70
- /**
71
- * 销毁数据及部分定时任务。
72
- */
73
- dispose: () => void
74
- }
75
-
76
- export function useVreoAction() {
77
- const player = useVreoInstance()
78
-
79
- const load = React.useCallback(
80
- (vreoUnit: VreoUnit, currentTime?: number) => player.load(vreoUnit, currentTime),
81
- [player]
82
- )
83
-
84
- const play = React.useCallback((currentTime?: number) => player.play(currentTime || 0), [player])
85
- const pause = React.useCallback(() => player.pause(), [player])
86
- const show = React.useCallback(() => player.show(), [player])
87
- const hide = React.useCallback(() => player.hide(), [player])
88
- const dispose = React.useCallback(() => player.dispose(), [player])
89
-
90
- return { load, pause, show, play, hide, dispose }
91
- }
92
-
93
- export function useVreoEventCallback<T extends keyof VreoKeyframeEvent>(
94
- name: T,
95
- callback: VreoKeyframeEvent[T],
96
- deps?: React.DependencyList | undefined
97
- ) {
98
- const player = useVreoInstance()
99
- let dependencyList: React.DependencyList = [player, name]
100
- if (deps !== undefined) {
101
- dependencyList = dependencyList.concat(deps)
102
- }
103
- React.useEffect(() => {
104
- // @ts-ignore
105
- player.on(name, callback)
106
- return () => {
107
- // @ts-ignore
108
- player.off(name, callback)
109
- }
110
- }, dependencyList)
111
- }
112
-
113
- export function useVreoPausedState() {
114
- const player = useVreoInstance()
115
- const [state, setState] = React.useState(player.paused)
116
-
117
- useVreoEventCallback('paused', () => setState(true))
118
- useVreoEventCallback('playing', () => setState(false))
119
-
120
- return state
121
- }