@realsee/vreo 0.2.0-alpha.4 → 0.2.0-alpha.7

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 (52) hide show
  1. package/README.md +20 -3
  2. package/docs/assets/custom.css +2 -2
  3. package/docs/assets/search.js +1 -1
  4. package/docs/classes/Player.Controller.html +3 -3
  5. package/docs/classes/Player.Player-1.html +3 -3
  6. package/docs/classes/Player.VideoAgentMesh.html +11 -11
  7. package/docs/classes/Player.VideoAgentScene.html +1 -1
  8. package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
  9. package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
  10. package/docs/enums/Player.PanoEffectEnum.html +1 -1
  11. package/docs/enums/Player.PanoTagEnum.html +1 -1
  12. package/docs/enums/Player.VreoKeyframeEnum.html +12 -12
  13. package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
  14. package/docs/enums/fivePlugins.Rotation.html +1 -1
  15. package/docs/index.html +6 -2
  16. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -1
  17. package/docs/interfaces/Player.PlayerConfigs.html +2 -2
  18. package/docs/interfaces/Player.Vertex.html +1 -1
  19. package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -1
  20. package/docs/interfaces/Player.VreoKeyframe.html +1 -1
  21. package/docs/interfaces/Player.VreoUnit.html +1 -1
  22. package/docs/interfaces/Player.VreoVideo.html +1 -1
  23. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
  24. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +2 -2
  25. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -1
  26. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -1
  27. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -1
  28. package/docs/interfaces/react.VreoActionCallbacks.html +6 -6
  29. package/docs/interfaces/react.VreoProviderProps.html +1 -1
  30. package/docs/modules/Player.html +13 -13
  31. package/docs/modules/custom.html +1 -1
  32. package/docs/modules/fivePlugins.html +2 -2
  33. package/docs/modules/react.html +1 -1
  34. package/lib/Player/Controller.d.ts +2 -0
  35. package/lib/Player/Controller.js +14 -0
  36. package/lib/Player/custom/SpatialScenePanel/index.d.ts +2 -2
  37. package/lib/Player/custom/SpatialScenePanel/index.js +97 -15
  38. package/lib/Player/index.js +3 -1
  39. package/lib/Player/modules/PopUp/index.d.ts +2 -0
  40. package/lib/Player/modules/PopUp/index.js +43 -0
  41. package/lib/Player/modules/keyframes/InfoPanel/index.js +73 -35
  42. package/lib/typings/VreoUnit.d.ts +5 -0
  43. package/lib/typings/VreoUnit.js +14 -6
  44. package/package.json +2 -2
  45. package/resources/Player/Controller.ts +12 -0
  46. package/resources/Player/custom/SpatialScenePanel/index.tsx +144 -34
  47. package/resources/Player/index.tsx +2 -0
  48. package/resources/Player/modules/PopUp/index.tsx +26 -0
  49. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +79 -34
  50. package/resources/typings/VreoUnit.ts +6 -0
  51. package/stylesheets/custom/SpatialScenePanel.css +14 -8
  52. package/stylesheets/default.css +66 -0
@@ -75,49 +75,87 @@ function InfoPanel() {
75
75
  data = keyframe.data;
76
76
  var infoPanelData = data;
77
77
  var title = infoPanelData.title,
78
- subTitle = infoPanelData.subTitle;
79
-
80
- if (infoPanelData.type === _VreoUnit.InfoPanelTypeEnum.Image) {
81
- controller.openDrawer({
82
- content: /*#__PURE__*/React.createElement(InfoPanelImg, {
83
- url: infoPanelData.url
84
- }, /*#__PURE__*/React.createElement(Title, {
85
- title: title,
86
- subTitle: subTitle
87
- })),
88
- height: '60vh'
89
- });
90
- } else if (infoPanelData.type === _VreoUnit.InfoPanelTypeEnum.Video) {
91
- controller.openDrawer({
92
- content: /*#__PURE__*/React.createElement(InfoPanelVideo, {
93
- url: infoPanelData.url
94
- }, /*#__PURE__*/React.createElement(Title, {
95
- title: title,
96
- subTitle: subTitle
97
- })),
98
- height: '60vh'
99
- });
100
- }
78
+ subTitle = infoPanelData.subTitle,
79
+ style = infoPanelData.style;
80
+
81
+ do {
82
+ if (style === _VreoUnit.InfoPanelStyleEnum.PopUp) {
83
+ if (infoPanelData.type === _VreoUnit.InfoPanelTypeEnum.Image) {
84
+ controller.openPopUp( /*#__PURE__*/React.createElement(InfoPanelImg, {
85
+ url: infoPanelData.url
86
+ }, /*#__PURE__*/React.createElement(Title, {
87
+ title: title,
88
+ subTitle: subTitle
89
+ })));
90
+ } else if (infoPanelData.type === _VreoUnit.InfoPanelTypeEnum.Video) {
91
+ controller.openPopUp( /*#__PURE__*/React.createElement(InfoPanelVideo, {
92
+ url: infoPanelData.url
93
+ }, /*#__PURE__*/React.createElement(Title, {
94
+ title: title,
95
+ subTitle: subTitle
96
+ })));
97
+ }
98
+
99
+ break;
100
+ }
101
+
102
+ if (infoPanelData.type === _VreoUnit.InfoPanelTypeEnum.Image) {
103
+ controller.openDrawer({
104
+ content: /*#__PURE__*/React.createElement(InfoPanelImg, {
105
+ url: infoPanelData.url
106
+ }, /*#__PURE__*/React.createElement(Title, {
107
+ title: title,
108
+ subTitle: subTitle
109
+ })),
110
+ height: '60vh'
111
+ });
112
+ } else if (infoPanelData.type === _VreoUnit.InfoPanelTypeEnum.Video) {
113
+ controller.openDrawer({
114
+ content: /*#__PURE__*/React.createElement(InfoPanelVideo, {
115
+ url: infoPanelData.url
116
+ }, /*#__PURE__*/React.createElement(Title, {
117
+ title: title,
118
+ subTitle: subTitle
119
+ })),
120
+ height: '60vh'
121
+ });
122
+ }
123
+ } while (false);
101
124
 
102
125
  timeoutRef.current = setTimeout(function () {
103
- return controller.openDrawer(false);
126
+ controller.openDrawer(false);
127
+ controller.openPopUp(false);
104
128
  }, end - start);
105
129
  };
106
130
 
107
131
  controller.on(_VreoUnit.VreoKeyframeEnum.InfoPanel, callback); // Object.assign(window, {
108
132
  // $setInfoPanel: () => {
109
- // controller.openDrawer({
110
- // content: (
111
- // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif'>
112
- // // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
113
- // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
114
- // // </InfoPanelImg>
115
- // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
133
+ // controller.openPopUp(
134
+ // // <InfoPanelImg url='//vrlab-static.ljcdn.com/release/web/psq/a.8e868cb2.gif' />
135
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/b.f9a1ed52.png' />
136
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/c.4f88c112.png' />
137
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif' />
138
+ // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
116
139
  // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
117
- // </InfoPanelVideo>
118
- // ),
119
- // height: '60vh',
120
- // })
140
+ // </InfoPanelImg>
141
+ // // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
142
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
143
+ // // </InfoPanelVideo>
144
+ // )
145
+ // },
146
+ // $setInfoPanel2: () => {
147
+ // controller.openPopUp(
148
+ // <InfoPanelImg url='//vrlab-static.ljcdn.com/release/web/psq/a.8e868cb2.gif' />
149
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/b.f9a1ed52.png' />
150
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/web/psq/c.4f88c112.png' />
151
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif' />
152
+ // // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
153
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
154
+ // // </InfoPanelImg>
155
+ // // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
156
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
157
+ // // </InfoPanelVideo>
158
+ // )
121
159
  // },
122
160
  // })
123
161
 
@@ -210,11 +210,16 @@ export declare enum InfoPanelTypeEnum {
210
210
  Image = "Image",
211
211
  Video = "Video"
212
212
  }
213
+ export declare enum InfoPanelStyleEnum {
214
+ Drawer = "Drawer",
215
+ PopUp = "PopUp"
216
+ }
213
217
  /**
214
218
  * 信息面板
215
219
  */
216
220
  export declare type InfoPanelData = {
217
221
  type: InfoPanelTypeEnum;
222
+ style?: InfoPanelStyleEnum;
218
223
  url: string;
219
224
  title?: string;
220
225
  subTitle?: string;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VreoKeyframeEnum = exports.PanoTagEnum = exports.PanoEffectEnum = exports.InfoPanelTypeEnum = void 0;
6
+ exports.VreoKeyframeEnum = exports.PanoTagEnum = exports.PanoEffectEnum = exports.InfoPanelTypeEnum = exports.InfoPanelStyleEnum = void 0;
7
7
  var VreoKeyframeEnum;
8
8
  /**
9
9
  * 支持自定义剧本关键帧配置项
@@ -55,13 +55,21 @@ exports.PanoEffectEnum = PanoEffectEnum;
55
55
  * 信息面板类型枚举
56
56
  */
57
57
  var InfoPanelTypeEnum;
58
- /**
59
- * 信息面板
60
- */
61
-
62
58
  exports.InfoPanelTypeEnum = InfoPanelTypeEnum;
63
59
 
64
60
  (function (InfoPanelTypeEnum) {
65
61
  InfoPanelTypeEnum["Image"] = "Image";
66
62
  InfoPanelTypeEnum["Video"] = "Video";
67
- })(InfoPanelTypeEnum || (exports.InfoPanelTypeEnum = InfoPanelTypeEnum = {}));
63
+ })(InfoPanelTypeEnum || (exports.InfoPanelTypeEnum = InfoPanelTypeEnum = {}));
64
+
65
+ var InfoPanelStyleEnum;
66
+ /**
67
+ * 信息面板
68
+ */
69
+
70
+ exports.InfoPanelStyleEnum = InfoPanelStyleEnum;
71
+
72
+ (function (InfoPanelStyleEnum) {
73
+ InfoPanelStyleEnum["Drawer"] = "Drawer";
74
+ InfoPanelStyleEnum["PopUp"] = "PopUp";
75
+ })(InfoPanelStyleEnum || (exports.InfoPanelStyleEnum = InfoPanelStyleEnum = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realsee/vreo",
3
- "version": "0.2.0-alpha.4",
3
+ "version": "0.2.0-alpha.7",
4
4
  "description": "Vreo (VR Video 缩写) 是基于如视三维渲染引擎 Five 和 用户界面构建库 React 实现的如视 3D 空间剧本播放器。",
5
5
  "keywords": [
6
6
  "realsee",
@@ -18,7 +18,7 @@
18
18
  "LICENSE"
19
19
  ],
20
20
  "scripts": {
21
- "dev": "vite --port=3088",
21
+ "dev": "vite --port=3088 --host 0.0.0.0",
22
22
  "build": "tsc && vite build",
23
23
  "preview": "vite preview",
24
24
  "docs": "npx typedoc",
@@ -24,6 +24,16 @@ export class Controller extends Subscribe<VreoKeyframeEvent> {
24
24
  return !this.videoAgentScene?.videoAgentMesh.videoUrl?.endsWith('.mp4')
25
25
  }
26
26
 
27
+ popUp: string | JSX.Element | null = null
28
+
29
+ openPopUp(popUp: string | JSX.Element | false) {
30
+ if (!popUp) {
31
+ this.popUp = null
32
+ return
33
+ }
34
+ this.popUp = popUp
35
+ }
36
+
27
37
  drawerConfig: {
28
38
  content: string | JSX.Element
29
39
  height?: number | string
@@ -57,6 +67,8 @@ export class Controller extends Subscribe<VreoKeyframeEvent> {
57
67
  setVisible: action,
58
68
  playing: observable,
59
69
  setPlaying: action,
70
+ popUp: observable.ref,
71
+ openPopUp: action,
60
72
  drawerConfig: observable.ref,
61
73
  openDrawer: action,
62
74
  })
@@ -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 { Raycaster, Vector3 } from 'three'
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: { x: number; y: number; z: number }
20
- quaternion: [number, number, number, number]
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 - 1)
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
- const ratio = leftBottom.distanceTo(rightBottom) / 160
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,103 @@ 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
- const startRotateY = -(Math.PI * 2) / 9
99
- let lastRotateY = 0
100
- tweenProgress(1000)
101
- .onUpdate(({ progress }) => {
102
- const needRotateY = (Math.PI / 90) * 11 * progress
103
- const rotateY = needRotateY - lastRotateY
104
- css3DObject?.rotateY(rotateY)
105
- lastRotateY = needRotateY
106
- })
107
- .onStart(() => {
108
- css3DObject?.rotateY(startRotateY)
109
- render!()
110
- })
111
- .onDispose(() => {
112
- panelRef.current?.classList.add('show')
113
- })
114
- .play()
115
- const { start, end } = keyframe
116
- setTimeout(() => {
117
- panelRef.current?.classList.add('hide')
118
- setTimeout(() => dispose?.(), 1500)
119
- }, end - start)
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
+ console.log('listener')
196
+ ref.current?.setAttribute('class', 'SpatialScenePanel-bg')
197
+
198
+ timeoutRef.current = setTimeout(() => {
199
+ ref.current?.setAttribute('class', 'SpatialScenePanel-bg SpatialScenePanel-bg--animation')
200
+ timeoutRef.current = null
201
+ }, 3000)
202
+ }
203
+
204
+ ref.current.addEventListener('animationend', listener)
205
+
206
+ return () => {
207
+ if (ref.current) ref.current.removeEventListener('animationend', listener)
208
+ if (timeoutRef.current) clearTimeout(timeoutRef.current)
209
+ }
210
+ }, [])
211
+ return <div ref={ref} className="SpatialScenePanel-bg SpatialScenePanel-bg--animation"></div>
212
+ }
213
+
132
214
  const Panel = React.forwardRef(
133
215
  (props: { data: SpatialScenePanelData }, myRef: React.LegacyRef<HTMLDivElement> | undefined) => (
134
216
  <div className="SpatialScenePanel" ref={myRef}>
135
217
  <div className="SpatialScenePanel-show-area">
136
- <div className="SpatialScenePanel-bg"></div>
218
+ <SpatialScenePanelBg />
137
219
  <div className="SpatialScenePanel-header">
138
220
  <div className="SpatialScenePanel-title">{props.data?.title}</div>
139
221
  <div className="SpatialScenePanel-temperature">{props.data?.temperature}℃</div>
@@ -151,5 +233,33 @@ const Panel = React.forwardRef(
151
233
 
152
234
  <div className="SpatialScenePanel-disappear-area"></div>
153
235
  </div>
154
- ),
236
+ )
155
237
  )
238
+
239
+
240
+ // export function SpatialScenePanel() {
241
+ // // const data = mockData
242
+
243
+ // return (
244
+ // <div className="SpatialScenePanel" >
245
+ // <div className="SpatialScenePanel-show-area">
246
+ // <SpatialScenePanelBg />
247
+ // <div className="SpatialScenePanel-header">
248
+ // <div className="SpatialScenePanel-title">{data?.title}</div>
249
+ // <div className="SpatialScenePanel-temperature">{data?.temperature}℃</div>
250
+ // </div>
251
+ // <div className="SpatialScenePanel-body">
252
+ // {data?.stateList?.map((state, index) => (
253
+ // <div key={`scene-${state.text}`} className={`SpatialScenePanel-item index_${index}`}>
254
+ // <img className="SpatialScenePanel-icon" src={state.icon}></img>
255
+ // <div className="SpatialScenePanel-text">{state.text}</div>
256
+ // <div className="SpatialScenePanel-dot"></div>
257
+ // </div>
258
+ // ))}
259
+ // </div>
260
+ // </div>
261
+
262
+ // <div className="SpatialScenePanel-disappear-area"></div>
263
+ // </div>
264
+ // )
265
+ // }
@@ -8,6 +8,7 @@ import { 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
@@ -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
+ }