@realsee/vreo 0.1.6-alpha.5 → 0.2.0-alpha.2

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 (61) hide show
  1. package/README.md +36 -13
  2. package/docs/assets/custom.css +2 -2
  3. package/docs/assets/search.js +1 -1
  4. package/docs/classes/Player.Controller.html +54 -0
  5. package/docs/classes/Player.Player-1.html +11 -11
  6. package/docs/classes/Player.VideoAgentMesh.html +142 -0
  7. package/docs/classes/Player.VideoAgentScene.html +1 -0
  8. package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
  9. package/docs/enums/Player.PanoEffectEnum.html +2 -2
  10. package/docs/enums/Player.PanoTagEnum.html +1 -1
  11. package/docs/enums/Player.VreoKeyframeEnum.html +14 -12
  12. package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
  13. package/docs/enums/fivePlugins.Rotation.html +1 -1
  14. package/docs/index.html +25 -16
  15. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -0
  16. package/docs/interfaces/Player.PlayerConfigs.html +4 -2
  17. package/docs/interfaces/Player.Vertex.html +1 -1
  18. package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -0
  19. package/docs/interfaces/Player.VreoKeyframe.html +1 -1
  20. package/docs/interfaces/Player.VreoUnit.html +1 -1
  21. package/docs/interfaces/Player.VreoVideo.html +1 -1
  22. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
  23. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +3 -3
  24. package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +1 -1
  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 +7 -7
  29. package/docs/interfaces/react.VreoProviderProps.html +1 -0
  30. package/docs/modules/Player.html +13 -13
  31. package/docs/modules/custom.html +3 -0
  32. package/docs/modules/fivePlugins.html +2 -2
  33. package/docs/modules/react.html +1 -1
  34. package/docs/modules.html +1 -1
  35. package/lib/Player/App.js +6 -2
  36. package/lib/Player/custom/SpatialScenePanel/index.d.ts +22 -0
  37. package/lib/Player/custom/SpatialScenePanel/index.js +207 -0
  38. package/lib/Player/index.js +27 -8
  39. package/lib/Player/modules/Drawer/index.js +1 -1
  40. package/lib/Player/modules/keyframes/BgMusic/index.d.ts +2 -0
  41. package/lib/Player/modules/keyframes/BgMusic/index.js +76 -0
  42. package/lib/Player/modules/keyframes/InfoPanel/index.js +52 -8
  43. package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +55 -16
  44. package/lib/Player/typings.d.ts +13 -1
  45. package/lib/react/index.d.ts +5 -1
  46. package/lib/react/index.js +1 -1
  47. package/lib/typings/VreoUnit.d.ts +32 -4
  48. package/lib/typings/VreoUnit.js +1 -0
  49. package/package.json +4 -3
  50. package/resources/Player/App.tsx +4 -1
  51. package/resources/Player/custom/SpatialScenePanel/index.tsx +161 -0
  52. package/resources/Player/index.tsx +16 -1
  53. package/resources/Player/modules/Drawer/index.tsx +1 -1
  54. package/resources/Player/modules/keyframes/BgMusic/index.tsx +66 -0
  55. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +59 -6
  56. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +63 -15
  57. package/resources/Player/typings.ts +16 -1
  58. package/resources/react/index.tsx +7 -2
  59. package/resources/typings/VreoUnit.ts +40 -4
  60. package/stylesheets/custom/SpatialScenePanel.css +303 -0
  61. package/stylesheets/default.css +46 -2
@@ -1,19 +1,40 @@
1
1
  import * as React from 'react'
2
+ import { ReactNode } from 'react'
2
3
  import { InfoPanelData, InfoPanelTypeEnum, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
3
4
  import { useController } from '../../../hooks'
4
5
 
5
- function InfoPanelImg({ url }: { url: string }) {
6
+ function InfoPanelImg({ url, children }: { url: string; children?: ReactNode }) {
6
7
  return (
7
8
  <div className="vreo-infoPanel vreo-infoPanel--img">
8
- <img className="vreo-infoPanelImg" src={url} />
9
+ {children}
10
+ <div className="vreo-infoPanelImg" style={{ backgroundImage: `url(${url})` }}></div>
9
11
  </div>
10
12
  )
11
13
  }
12
14
 
13
- function InfoPanelVideo({ url }: { url: string }) {
15
+ function InfoPanelVideo({ url, children }: { url: string; children?: ReactNode }) {
14
16
  return (
15
17
  <div className="vreo-infoPanel vreo-infoPanel--video">
16
- <video playsInline autoPlay className="vreo-infoPanelVideo" src={url} />
18
+ {children}
19
+ <div className="vreo-infoPanelWrapper"><video playsInline autoPlay className="vreo-infoPanelVideo" src={url} /></div>
20
+ </div>
21
+ )
22
+ }
23
+
24
+ interface TitleProps {
25
+ title?: string
26
+ subTitle?: string
27
+ }
28
+
29
+ const Title = (props: TitleProps) => {
30
+ if (!props.title && !props.subTitle) {
31
+ return null
32
+ }
33
+
34
+ return (
35
+ <div className="vreo-infoPanel-title">
36
+ <div className="vreo-infoPanel-t1">{props.title}</div>
37
+ <div className="vreo-infoPanel-t2">{props.subTitle}</div>
17
38
  </div>
18
39
  )
19
40
  }
@@ -31,15 +52,47 @@ export function InfoPanel() {
31
52
 
32
53
  const infoPanelData = data as InfoPanelData
33
54
 
55
+ const { title, subTitle } = infoPanelData
34
56
  if (infoPanelData.type === InfoPanelTypeEnum.Image) {
35
- controller.openDrawer({ content: <InfoPanelImg url={infoPanelData.url} />, height: '60vh' })
57
+ controller.openDrawer({
58
+ content: (
59
+ <InfoPanelImg url={infoPanelData.url}>
60
+ <Title title={title} subTitle={subTitle} />
61
+ </InfoPanelImg>
62
+ ),
63
+ height: '60vh',
64
+ })
36
65
  } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
37
- controller.openDrawer({ content: <InfoPanelVideo url={infoPanelData.url} />, height: '60vh' })
66
+ controller.openDrawer({
67
+ content: (
68
+ <InfoPanelVideo url={infoPanelData.url}>
69
+ <Title title={title} subTitle={subTitle} />
70
+ </InfoPanelVideo>
71
+ ),
72
+ height: '60vh',
73
+ })
38
74
  }
39
75
  timeoutRef.current = setTimeout(() => controller.openDrawer(false), end - start)
40
76
  }
41
77
  controller.on(VreoKeyframeEnum.InfoPanel, callback)
42
78
 
79
+ // Object.assign(window, {
80
+ // $setInfoPanel: () => {
81
+ // controller.openDrawer({
82
+ // content: (
83
+ // // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif'>
84
+ // // <InfoPanelImg url="http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png">
85
+ // // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
86
+ // // </InfoPanelImg>
87
+ // <InfoPanelVideo url="//vrlab-public.ljcdn.com/release/seesay/tools/2022011713142___b320f74a5e1b5ad4bb46b4dc69d73ecc.mp4">
88
+ // <Title title="场景联动抓拍图片" subTitle={'2022.02.17 14:00'} />
89
+ // </InfoPanelVideo>
90
+ // ),
91
+ // height: '60vh',
92
+ // })
93
+ // },
94
+ // })
95
+
43
96
  return () => {
44
97
  controller.off(VreoKeyframeEnum.InfoPanel, callback)
45
98
  if (timeoutRef.current) {
@@ -1,40 +1,88 @@
1
1
  import * as React from 'react'
2
- import { parseWork, WorkCubeImage } from '@realsee/five'
2
+ import { parseWork, Work } from '@realsee/five'
3
3
  import { useController, useFiveInstance } from '../../../hooks'
4
4
  import { UpdateVRPanoramaData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
5
 
6
6
  export function UpdateVRPanorama() {
7
7
  const controller = useController()
8
8
  const five = useFiveInstance()
9
+ const rawRef = React.useRef<string[] | null>(null)
10
+ const workRef = React.useRef<Work | null>(null)
11
+
12
+ const restoreCallback = React.useCallback(() => {
13
+ if (rawRef.current) {
14
+ const work = parseWork(rawRef.current)
15
+ five.load(work)
16
+ }
17
+
18
+ workRef.current = null
19
+ }, [])
20
+
21
+ const pausedCallback = React.useCallback(() => {
22
+ if (rawRef.current) {
23
+ const work = parseWork(rawRef.current)
24
+ five.load(work)
25
+ }
26
+ }, [])
27
+
28
+ const playingCallback = React.useCallback(() => {
29
+ if (!workRef.current) {
30
+ return
31
+ }
32
+ five.load(workRef.current)
33
+ }, [])
9
34
 
10
35
  React.useEffect(() => {
11
36
  const callback = (keyframe: VreoKeyframe) => {
12
- const { panoIndex, images, work } = keyframe.data as UpdateVRPanoramaData
37
+ if (!rawRef.current) {
38
+ rawRef.current = five.work.raw.works
39
+ }
40
+
41
+ const data = keyframe.data as UpdateVRPanoramaData
13
42
 
14
- if (work) {
15
- five.load(work)
43
+ // 如果数据中有新 work 数据,则直接载入
44
+ if (data.work) {
45
+ workRef.current = parseWork(data.work)
46
+ five.load(workRef.current)
16
47
  return
17
48
  }
18
49
 
19
- console.warn('not support.')
20
- const newWorkJSON = JSON.parse(JSON.stringify(five.work?.raw.work))
50
+ const lastRawWork = five.work?.raw.works[0]
21
51
 
22
- // // 原Work数据不能被修改
23
- if (newWorkJSON.panorama && newWorkJSON.panorama.list && newWorkJSON.panorama.list[panoIndex]) {
24
- Object.assign(newWorkJSON.panorama.list[panoIndex], images)
25
- } else if (newWorkJSON.observers && newWorkJSON.observers[panoIndex] && newWorkJSON.observers[panoIndex].images) {
26
- Object.assign(newWorkJSON.observers[panoIndex].images, images)
52
+ // 动态场景:不提供完成的签名数据,需重新整理
53
+ if (data.dynamic_scene && !data.panorama) {
54
+ const lastWork = JSON.parse(lastRawWork)
55
+ const panorama = lastWork.panorama
56
+ const index = data.dynamic_scene.images.index
57
+ panorama.list[index] = data.dynamic_scene.images
58
+ data.panorama = panorama
59
+ delete data.dynamic_scene
27
60
  }
28
61
 
29
- const newWork = parseWork(newWorkJSON)
30
-
31
- // // 需要还原么?待定 ...
32
- five.load(newWork)
62
+ workRef.current = parseWork([lastRawWork, data])
63
+ five.load(workRef.current)
33
64
  }
34
65
 
35
66
  controller.on(VreoKeyframeEnum.UpdateVRPanorama, callback)
67
+
68
+ // 离开 将之前的内容清空
69
+ controller.on(VreoKeyframeEnum.Exit, restoreCallback)
70
+
71
+ // 新载入数据 将之前的内容清空
72
+ controller.on('loaded', restoreCallback)
73
+
74
+ // 暂停 回到默认状态
75
+ controller.on('paused', pausedCallback)
76
+ // 播放 回归暂停前状态
77
+ controller.on('playing', playingCallback)
78
+
36
79
  return () => {
80
+ // 清理事件监听
37
81
  controller.off(VreoKeyframeEnum.UpdateVRPanorama, callback)
82
+ controller.off(VreoKeyframeEnum.Exit, restoreCallback)
83
+ controller.off('loaded', restoreCallback)
84
+ controller.off('paused', pausedCallback)
85
+ controller.off('playing', playingCallback)
38
86
  }
39
87
  }, [controller])
40
88
 
@@ -1,4 +1,7 @@
1
- import { VreoKeyframeConfigMap } from '../typings/VreoUnit'
1
+ import React, { ReactNode } from 'react';
2
+ import { Subscribe, Five } from '@realsee/five';
3
+
4
+ import { VreoKeyframeConfigMap, VreoKeyframeEvent } from '../typings/VreoUnit'
2
5
 
3
6
  export interface PlayerConfigs {
4
7
  containter?: ReactDOM.Container
@@ -12,4 +15,16 @@ export interface PlayerConfigs {
12
15
  videoEffect?: HTMLVideoElement
13
16
  modelTVVideo?: HTMLVideoElement
14
17
  }
18
+ /**
19
+ * 如果需要在 底部面板添加自定义内容,可以传递个 React 组件。
20
+ */
21
+ customPanelChildren?: ReactNode
22
+ customKeyframes?: React.FC<CustomVreoKeyframeProps>[]
23
+ }
24
+
25
+ export type VreoSubscribe = Pick<Subscribe<VreoKeyframeEvent>, 'on' | 'once' | 'off'>
26
+
27
+ export interface CustomVreoKeyframeProps {
28
+ subscribe: VreoSubscribe
29
+ five: Five
15
30
  }
@@ -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 const VreoProvider: React.FC = (props) => {
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 () => {
@@ -1,4 +1,4 @@
1
- import { Mode, Pose, WorkCubeImage, Work } from '@realsee/five'
1
+ import { Mode, Pose } from '@realsee/five'
2
2
  import { CameraMovementEffect, Rotation } from '../fivePlugins/CameraMovementPlugin/typings'
3
3
 
4
4
  export enum VreoKeyframeEnum {
@@ -36,6 +36,10 @@ export enum VreoKeyframeEnum {
36
36
  * 视频特效
37
37
  */
38
38
  VideoEffect = 'VideoEffect',
39
+ /**
40
+ * 背景音乐
41
+ */
42
+ BgMusic = 'BgMusic',
39
43
  /**
40
44
  * 结束
41
45
  */
@@ -61,6 +65,7 @@ export type VreoKeyframeConfigMap = {
61
65
  * 剧本关键帧
62
66
  */
63
67
  export interface VreoKeyframe {
68
+ uuid: string
64
69
  type: VreoKeyframeEnum
65
70
  start: number
66
71
  end: number
@@ -96,8 +101,14 @@ export interface VreoUnit {
96
101
  * 剧本事件
97
102
  */
98
103
  export type VreoKeyframeEvent = { [key in VreoKeyframeEnum]: (keyframe: VreoKeyframe) => void } & {
104
+ // 新数据载入完成
105
+ loaded: (vreoUnit: VreoUnit) => void
106
+ // 语音状态 播放 -> 暂停
99
107
  paused: () => void
108
+ // 语音状态 暂停 -> 播放
100
109
  playing: () => void
110
+ // 未知的 剧本帧类型
111
+ unknownKeyframeType: (keyframe: Record<string, any>) => void
101
112
  }
102
113
 
103
114
  /**
@@ -123,9 +134,23 @@ export type PrompterData = {
123
134
  * VR 全景切换
124
135
  */
125
136
  export type UpdateVRPanoramaData = {
126
- panoIndex: number
127
- images: WorkCubeImage
128
- work?: Work
137
+ _signature: string
138
+ allow_hosts: string[]
139
+ certificate: string
140
+ expire_at: string
141
+ // 动态场景
142
+ dynamic_scene?: {
143
+ images: {
144
+ index: number
145
+ right: string
146
+ left: string
147
+ up: string
148
+ down: string
149
+ front: string
150
+ back: string
151
+ }
152
+ }
153
+ [key: string]: any
129
154
  }
130
155
 
131
156
  /**
@@ -216,6 +241,10 @@ export enum InfoPanelTypeEnum {
216
241
  export type InfoPanelData = {
217
242
  type: InfoPanelTypeEnum
218
243
  url: string
244
+ // 标题
245
+ title?: string
246
+ // 副标题
247
+ subTitle?: string
219
248
  }
220
249
 
221
250
  /**
@@ -229,5 +258,12 @@ export type VideoEffectData = {
229
258
  vector?: Pick<Pose, 'longitude' | 'latitude'>
230
259
  }
231
260
 
261
+ /**
262
+ * 背景音乐
263
+ */
264
+ export type BgMusicData = {
265
+ url: string
266
+ }
267
+
232
268
  /** 自定义序列帧 */
233
269
  export type CustomData = Record<string, any>
@@ -0,0 +1,303 @@
1
+ @keyframes SpatialScenePanel-panel-sprites-animation {
2
+ 0% {
3
+ background-position: 0 0
4
+ }
5
+
6
+ 100% {
7
+ background-position: -330rem 0
8
+ }
9
+ }
10
+
11
+
12
+ @keyframes SpatialScenePanel-opacity-animation {
13
+ 0% {
14
+ opacity: .3
15
+ }
16
+
17
+ 100% {
18
+ opacity: 1
19
+ }
20
+ }
21
+
22
+ @keyframes SpatialScenePanel-dot-sprites-animation {
23
+ 0% {
24
+ background-position: 0 0
25
+ }
26
+
27
+ 100% {
28
+ background-position: -31.25rem 0
29
+ }
30
+ }
31
+
32
+ @keyframes SpatialScenePanel-line-sprites-animation {
33
+ 0% {
34
+ background-position: 0 0
35
+ }
36
+
37
+ 100% {
38
+ background-position: -9.583333333333334rem 0
39
+ }
40
+ }
41
+
42
+ .vreo-SpatialScenePanel {
43
+ width: 10rem;
44
+ height: 13.4375rem;
45
+ position: fixed;
46
+ top: 0;
47
+ left: 0;
48
+ pointer-events: none;
49
+ user-select: none
50
+ }
51
+
52
+ .SpatialScenePanel {
53
+ width: 10rem;
54
+ height: 13.4375rem;
55
+ transform: scale3d(1,1,1);
56
+ transform-origin: center;
57
+ position: fixed;
58
+ left: 3rem;
59
+ top: 3rem;
60
+ }
61
+
62
+ .SpatialScenePanel-show-area {
63
+ width: 100%;
64
+ height: 100%;
65
+ transform: scale3d(1,1,1);
66
+ transform-origin: center;
67
+ position: absolute
68
+ }
69
+
70
+ .SpatialScenePanel-show-area .SpatialScenePanel-bg {
71
+ width: 10rem;
72
+ height: 13.4375rem;
73
+ position: absolute;
74
+ top: 50%;
75
+ left: 50%;
76
+ transform: translate3d(-50%,-50%,0);
77
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/panel-min.7d9ba2b7.png");
78
+ background-size: 340rem 13.4375rem;
79
+ background-repeat: no-repeat;
80
+ animation: SpatialScenePanel-panel-sprites-animation 1.375s 0s steps(33) infinite normal
81
+ }
82
+
83
+ .SpatialScenePanel-show-area .SpatialScenePanel-header {
84
+ width: 7.5rem;
85
+ height: 1.375rem;
86
+ display: -ms-flexbox;
87
+ display: flex;
88
+ justify-content: space-between;
89
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/title-bg.377af865.png");
90
+ background-size: 100%;
91
+ margin: 1.875rem auto 1.25rem auto;
92
+ padding-bottom: .25rem
93
+ }
94
+
95
+ .SpatialScenePanel-show-area .SpatialScenePanel-header .SpatialScenePanel-title {
96
+ font-family: PingFangSC-Medium;
97
+ font-size: 1.0625rem;
98
+ color: #ffe5b0;
99
+ letter-spacing: 0;
100
+ line-height: 1.0625rem;
101
+ text-shadow: 0 0 1.25rem rgba(0,0,0,0.15)
102
+ }
103
+
104
+ .SpatialScenePanel-show-area .SpatialScenePanel-header .SpatialScenePanel-temperature {
105
+ font-family: PingFangSC-Semibold;
106
+ font-size: .625rem;
107
+ color: rgba(255,229,176,0.6);
108
+ letter-spacing: 0;
109
+ line-height: .625rem;
110
+ text-shadow: 0 0 .625rem rgba(255,255,255,0.03);
111
+ align-self: flex-end
112
+ }
113
+
114
+ .SpatialScenePanel-show-area .SpatialScenePanel-body {
115
+ position: relative;
116
+ padding: 0 1.25rem
117
+ }
118
+
119
+ .SpatialScenePanel-show-area .SpatialScenePanel-body .SpatialScenePanel-item {
120
+ position: relative;
121
+ display: -ms-flexbox;
122
+ display: flex;
123
+ align-items: center;
124
+ margin-bottom: 1rem;
125
+ width: 100%
126
+ }
127
+
128
+ .SpatialScenePanel-show-area .SpatialScenePanel-body .SpatialScenePanel-text {
129
+ opacity: .3;
130
+ font-family: PingFangSC-Regular;
131
+ font-size: .75rem;
132
+ color: #fff;
133
+ letter-spacing: 0;
134
+ line-height: .75rem
135
+ }
136
+
137
+ .SpatialScenePanel-show-area .SpatialScenePanel-body .SpatialScenePanel-icon {
138
+ opacity: .3;
139
+ width: 1rem;
140
+ height: 1rem;
141
+ margin-right: .375rem;
142
+ flex-shrink: 0
143
+ }
144
+
145
+ .SpatialScenePanel-show-area .SpatialScenePanel-body .SpatialScenePanel-dot {
146
+ position: absolute;
147
+ width: 1.25rem;
148
+ height: 1.25rem;
149
+ flex-shrink: 0;
150
+ display: -ms-flexbox;
151
+ display: flex;
152
+ justify-content: center;
153
+ align-items: center;
154
+ right: -.625rem
155
+ }
156
+
157
+ .SpatialScenePanel-show-area .SpatialScenePanel-body .SpatialScenePanel-dot::before {
158
+ display: block;
159
+ position: absolute;
160
+ width: .25rem;
161
+ height: .25rem;
162
+ background: #c3d5ff;
163
+ opacity: .3;
164
+ content: '';
165
+ z-index: 1;
166
+ border-radius: 100%
167
+ }
168
+
169
+ .SpatialScenePanel-show-area .SpatialScenePanel-body .SpatialScenePanel-dot::after {
170
+ display: block;
171
+ position: absolute;
172
+ content: '';
173
+ z-index: 2
174
+ }
175
+
176
+ .SpatialScenePanel.show .SpatialScenePanel-disappear-area {
177
+ display: none
178
+ }
179
+
180
+ .SpatialScenePanel.show .SpatialScenePanel-show-area {
181
+ transform: scale3d(1,1,1);
182
+ transition: -webkit-transform 1s linear;
183
+ transition: transform 1s linear;
184
+ transition: transform 1s linear, -webkit-transform 1s linear
185
+ }
186
+
187
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_0 .SpatialScenePanel-text,.SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_0 .SpatialScenePanel-icon {
188
+ animation: SpatialScenePanel-opacity-animation 1s 1s 1 normal forwards
189
+ }
190
+
191
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_0 .SpatialScenePanel-dot::before {
192
+ animation: SpatialScenePanel-opacity-animation 1s 1s 1 normal forwards
193
+ }
194
+
195
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_0 .SpatialScenePanel-dot::after {
196
+ width: 2.083333333333333rem;
197
+ height: 2.083333333333333rem;
198
+ position: absolute;
199
+ top: 50%;
200
+ left: 50%;
201
+ transform: translate3d(-50%,-50%,0);
202
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/dot.54b5e078.png");
203
+ background-size: 33.333333333333336rem 2.083333333333333rem;
204
+ background-repeat: no-repeat;
205
+ animation: SpatialScenePanel-dot-sprites-animation 1s 1s steps(15) 1 normal
206
+ }
207
+
208
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_1 .SpatialScenePanel-text,.SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_1 .SpatialScenePanel-icon {
209
+ animation: SpatialScenePanel-opacity-animation 1s 2s 1 normal forwards
210
+ }
211
+
212
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_1 .SpatialScenePanel-dot::before {
213
+ animation: SpatialScenePanel-opacity-animation 1s 2s 1 normal forwards
214
+ }
215
+
216
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_1 .SpatialScenePanel-dot::after {
217
+ width: 2.083333333333333rem;
218
+ height: 2.083333333333333rem;
219
+ position: absolute;
220
+ top: 50%;
221
+ left: 50%;
222
+ transform: translate3d(-50%,-50%,0);
223
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/dot.54b5e078.png");
224
+ background-size: 33.333333333333336rem 2.083333333333333rem;
225
+ background-repeat: no-repeat;
226
+ animation: SpatialScenePanel-dot-sprites-animation 1s 2s steps(15) 1 normal
227
+ }
228
+
229
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_2 .SpatialScenePanel-text,.SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_2 .SpatialScenePanel-icon {
230
+ animation: SpatialScenePanel-opacity-animation 1s 3s 1 normal forwards
231
+ }
232
+
233
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_2 .SpatialScenePanel-dot::before {
234
+ animation: SpatialScenePanel-opacity-animation 1s 3s 1 normal forwards
235
+ }
236
+
237
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_2 .SpatialScenePanel-dot::after {
238
+ width: 2.083333333333333rem;
239
+ height: 2.083333333333333rem;
240
+ position: absolute;
241
+ top: 50%;
242
+ left: 50%;
243
+ transform: translate3d(-50%,-50%,0);
244
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/dot.54b5e078.png");
245
+ background-size: 33.333333333333336rem 2.083333333333333rem;
246
+ background-repeat: no-repeat;
247
+ animation: SpatialScenePanel-dot-sprites-animation 1s 3s steps(15) 1 normal
248
+ }
249
+
250
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_3 .SpatialScenePanel-text,.SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_3 .SpatialScenePanel-icon {
251
+ animation: SpatialScenePanel-opacity-animation 1s 4s 1 normal forwards
252
+ }
253
+
254
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_3 .SpatialScenePanel-dot::before {
255
+ animation: SpatialScenePanel-opacity-animation 1s 4s 1 normal forwards
256
+ }
257
+
258
+ .SpatialScenePanel .SpatialScenePanel-body .SpatialScenePanel-item.index_3 .SpatialScenePanel-dot::after {
259
+ width: 2.083333333333333rem;
260
+ height: 2.083333333333333rem;
261
+ position: absolute;
262
+ top: 50%;
263
+ left: 50%;
264
+ transform: translate3d(-50%,-50%,0);
265
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/dot.54b5e078.png");
266
+ background-size: 33.333333333333336rem 2.083333333333333rem;
267
+ background-repeat: no-repeat;
268
+ animation: SpatialScenePanel-dot-sprites-animation 1s 4s steps(15) 1 normal
269
+ }
270
+
271
+ .SpatialScenePanel.hide .SpatialScenePanel-show-area {
272
+ transform: scale3d(0,1,1);
273
+ transition: -webkit-transform 500ms linear;
274
+ transition: transform 500ms linear;
275
+ transition: transform 500ms linear, -webkit-transform 500ms linear
276
+ }
277
+
278
+ .SpatialScenePanel.hide .SpatialScenePanel-disappear-area {
279
+ display: -ms-flexbox;
280
+ display: flex;
281
+ width: 1.25rem;
282
+ height: 13.4375rem;
283
+ justify-content: center;
284
+ align-items: center
285
+ }
286
+
287
+ .SpatialScenePanel.hide .SpatialScenePanel-disappear-area::after {
288
+ content: '';
289
+ width: 100%;
290
+ height: 100%;
291
+ position: absolute;
292
+ width: .4166666666666667rem;
293
+ height: 11.666666666666666rem;
294
+ position: absolute;
295
+ top: 50%;
296
+ left: 50%;
297
+ transform: translate3d(-50%,-50%,0);
298
+ background-image: url("//vrlab-static.ljcdn.com/release/web/VoiceAssistant/images/line.4ac1c0bb.png");
299
+ background-size: 10rem 11.666666666666666rem;
300
+ background-repeat: no-repeat;
301
+ animation: SpatialScenePanel-line-sprites-animation 500ms 500ms steps(23) 1 normal
302
+ }
303
+