@realsee/vreo 0.2.0-alpha.1 → 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 (52) 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 +9 -9
  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 +13 -13
  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 +3 -3
  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/custom/SpatialScenePanel/index.d.ts +22 -0
  36. package/lib/Player/custom/SpatialScenePanel/index.js +207 -0
  37. package/lib/Player/index.js +17 -1
  38. package/lib/Player/modules/keyframes/InfoPanel/index.js +31 -21
  39. package/lib/Player/typings.d.ts +9 -2
  40. package/lib/react/index.d.ts +5 -1
  41. package/lib/react/index.js +1 -1
  42. package/lib/typings/VreoUnit.d.ts +2 -1
  43. package/package.json +2 -1
  44. package/resources/Player/App.tsx +1 -1
  45. package/resources/Player/custom/SpatialScenePanel/index.tsx +161 -0
  46. package/resources/Player/index.tsx +13 -1
  47. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +41 -19
  48. package/resources/Player/typings.ts +12 -2
  49. package/resources/react/index.tsx +7 -2
  50. package/resources/typings/VreoUnit.ts +10 -2
  51. package/stylesheets/custom/SpatialScenePanel.css +303 -0
  52. package/stylesheets/default.css +11 -0
@@ -0,0 +1,161 @@
1
+ import * as React from 'react'
2
+ import ReactDOM from 'react-dom'
3
+ import { Five } from '@realsee/five'
4
+ import { Raycaster, Vector3 } from 'three'
5
+ import { tweenProgress } from '@realsee/dnalogel/shared-utils/animationFrame/BetterTween'
6
+ import { CSS3DRenderPlugin, CSS3DRenderPluginExportType } from '@realsee/dnalogel/plugins/CSS3DRenderPlugin'
7
+
8
+ import { VreoKeyframe, VreoKeyframeEnum } from '../../../typings/VreoUnit'
9
+ import { CustomVreoKeyframeProps } from '../../typings'
10
+
11
+ export interface SpatialScenePanelData {
12
+ customType: 'SpatialScenePanel'
13
+ title: string
14
+ temperature: string
15
+ stateList: {
16
+ text: string
17
+ icon: string
18
+ }[]
19
+ position: { x: number; y: number; z: number }
20
+ quaternion: [number, number, number, number]
21
+ }
22
+
23
+ interface SearchParams {
24
+ five: Five
25
+ position: Vector3
26
+ rotation?: Vector3
27
+ quaternion: [number, number, number, number]
28
+ dom: HTMLDivElement
29
+ }
30
+
31
+ const searchV1 = ({ five, position, rotation, dom }: SearchParams) => {
32
+ const cameraDirection = new Vector3()
33
+ five.camera.getWorldDirection(cameraDirection)
34
+ const cameraPosition = five.camera.position
35
+ const [intersect] = five.model.intersectRaycaster(new Raycaster(cameraPosition, cameraDirection))
36
+ const point = five.project2d(intersect.point)
37
+
38
+ // const width = dom!.clientWidth
39
+ const height = dom!.clientHeight
40
+ dom!.style.left = point!.x + 'px'
41
+ dom!.style.top = point!.y - height / 2 + 'px'
42
+ const rect = dom!.getBoundingClientRect()
43
+ const { left, top, bottom, right } = rect
44
+
45
+ const leftBottom = new Vector3(left, bottom)
46
+ const leftTop = new Vector3(left, top)
47
+ const rightTop = new Vector3(right, top)
48
+ const rightBottom = new Vector3(right, bottom)
49
+
50
+ 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)
53
+ point.setZ(0.5)
54
+ return point.unproject(five.camera).addScaledVector(cameraDirection, 0.2)
55
+ })
56
+
57
+ // const colors = [0xdc143c, 0xffff00, 0x0000ff, 0x008000]
58
+ // points.forEach((p, index) => five.scene.add(getSphere(p, colors[index])))
59
+
60
+ const ratio = leftBottom.distanceTo(rightBottom) / 160
61
+ return { points, ratio }
62
+ }
63
+
64
+ /**
65
+ * 空间场景面板
66
+ * @returns
67
+ */
68
+ export function SpatialScenePanel(props: CustomVreoKeyframeProps) {
69
+ const ref = React.useRef<HTMLDivElement>(null)
70
+ const panelRef = React.useRef<HTMLDivElement | null>(null)
71
+ const rendererRef = React.useRef<CSS3DRenderPluginExportType>(CSS3DRenderPlugin(props.five))
72
+
73
+ React.useEffect(() => {
74
+
75
+ if (!ref.current) {
76
+ return
77
+ }
78
+
79
+ const callback = (keyframe: VreoKeyframe) => {
80
+ if (keyframe.data.customType !== 'SpatialScenePanel') {
81
+ return
82
+ }
83
+
84
+ const data = keyframe.data as SpatialScenePanelData
85
+ // const data = mockData as SpatialScenePanelData
86
+
87
+ const { points, ratio } = searchV1({
88
+ five: props.five,
89
+ position: new Vector3(data.position.x, data.position.y, data.position.z),
90
+ quaternion: data.quaternion,
91
+ dom: ref.current!
92
+ })
93
+
94
+ console.log(points, ratio)
95
+
96
+ const { container, dispose, css3DObject, render } =
97
+ rendererRef.current.create3DDomContainer(points, { ratio, autoRender: false }) || {}
98
+
99
+ if (!container) return
100
+
101
+
102
+ ReactDOM.render(<Panel ref={(ref) => (panelRef.current = ref)} data={data} />, container)
103
+ const startRotateY = -(Math.PI * 2) / 9
104
+ let lastRotateY = 0
105
+ tweenProgress(1000)
106
+ .onUpdate(({ progress }) => {
107
+ const needRotateY = (Math.PI / 90) * 11 * progress
108
+ const rotateY = needRotateY - lastRotateY
109
+ css3DObject?.rotateY(rotateY)
110
+ lastRotateY = needRotateY
111
+ })
112
+ .onStart(() => {
113
+ css3DObject?.rotateY(startRotateY)
114
+ render!()
115
+ })
116
+ .onDispose(() => {
117
+ panelRef.current?.classList.add('show')
118
+ })
119
+ .play()
120
+ const { start, end } = keyframe
121
+ setTimeout(() => {
122
+ panelRef.current?.classList.add('hide')
123
+ setTimeout(() => dispose?.(), 1500)
124
+ }, end - start)
125
+ }
126
+
127
+ Object.assign(window, {$SpatialScenePanelCallback: callback})
128
+ props.subscribe.on(VreoKeyframeEnum.Custom, callback)
129
+
130
+ return () => {
131
+ props.subscribe.off(VreoKeyframeEnum.Custom, callback)
132
+ }
133
+ }, [])
134
+
135
+ return <div className="vreo-SpatialScenePanel" ref={ref}></div>
136
+ }
137
+
138
+ const Panel = React.forwardRef(
139
+ (props: { data: SpatialScenePanelData }, myRef: React.LegacyRef<HTMLDivElement> | undefined) => (
140
+ <div className="SpatialScenePanel" ref={myRef}>
141
+ <div className="SpatialScenePanel-show-area">
142
+ <div className="SpatialScenePanel-bg"></div>
143
+ <div className="SpatialScenePanel-header">
144
+ <div className="SpatialScenePanel-title">{props.data?.title}</div>
145
+ <div className="SpatialScenePanel-temperature">{props.data?.temperature}℃</div>
146
+ </div>
147
+ <div className="SpatialScenePanel-body">
148
+ {props.data?.stateList?.map((state, index) => (
149
+ <div key={`scene-${state.text}`} className={`SpatialScenePanel-item index_${index}`}>
150
+ <img className="SpatialScenePanel-icon" src={state.icon}></img>
151
+ <div className="SpatialScenePanel-text">{state.text}</div>
152
+ <div className="SpatialScenePanel-dot"></div>
153
+ </div>
154
+ ))}
155
+ </div>
156
+ </div>
157
+
158
+ <div className="SpatialScenePanel-disappear-area"></div>
159
+ </div>
160
+ ),
161
+ )
@@ -4,7 +4,7 @@ import { Five, Subscribe } from '@realsee/five'
4
4
 
5
5
  import { App } from './App'
6
6
  import { Controller, ControllerContext } from './Controller'
7
- import { VreoKeyframeEvent, VreoKeyframeConfigMap, VreoUnit } from '../typings/VreoUnit'
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'
@@ -42,6 +42,18 @@ export class Player extends Subscribe<VreoKeyframeEvent> {
42
42
  <ControllerContext.Provider value={this.controller}>
43
43
  <App></App>
44
44
  <Drawer />
45
+ {this.configs.customKeyframes &&
46
+ this.configs.customKeyframes.map((CustomCmpt, key) => (
47
+ <CustomCmpt
48
+ key={key}
49
+ subscribe={{
50
+ on: (name, callback) => this.on(name, callback),
51
+ once: (name, callback) => this.once(name, callback),
52
+ off: (name, callback) => this.off(name, callback),
53
+ }}
54
+ five={five}
55
+ />
56
+ ))}
45
57
  </ControllerContext.Provider>,
46
58
  configs.containter
47
59
  )
@@ -7,7 +7,7 @@ function InfoPanelImg({ url, children }: { url: string; children?: ReactNode })
7
7
  return (
8
8
  <div className="vreo-infoPanel vreo-infoPanel--img">
9
9
  {children}
10
- <div className="vreo-infoPanelImg" style={{backgroundImage: `url(${url})`}} ></div>
10
+ <div className="vreo-infoPanelImg" style={{ backgroundImage: `url(${url})` }}></div>
11
11
  </div>
12
12
  )
13
13
  }
@@ -16,7 +16,7 @@ function InfoPanelVideo({ url, children }: { url: string; children?: ReactNode }
16
16
  return (
17
17
  <div className="vreo-infoPanel vreo-infoPanel--video">
18
18
  {children}
19
- <video playsInline autoPlay className="vreo-infoPanelVideo" src={url} />
19
+ <div className="vreo-infoPanelWrapper"><video playsInline autoPlay className="vreo-infoPanelVideo" src={url} /></div>
20
20
  </div>
21
21
  )
22
22
  }
@@ -31,10 +31,12 @@ const Title = (props: TitleProps) => {
31
31
  return null
32
32
  }
33
33
 
34
- return <div className="vreo-infoPanel-title">
35
- <div className="vreo-infoPanel-t1">{props.title}</div>
36
- <div className="vreo-infoPanel-t2">{props.subTitle}</div>
37
- </div>
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>
38
+ </div>
39
+ )
38
40
  }
39
41
 
40
42
  export function InfoPanel() {
@@ -49,27 +51,47 @@ export function InfoPanel() {
49
51
  const { start, end, data } = keyframe
50
52
 
51
53
  const infoPanelData = data as InfoPanelData
52
-
53
-
54
54
 
55
+ const { title, subTitle } = infoPanelData
55
56
  if (infoPanelData.type === InfoPanelTypeEnum.Image) {
56
- 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
+ })
57
65
  } else if (infoPanelData.type === InfoPanelTypeEnum.Video) {
58
- 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
+ })
59
74
  }
60
75
  timeoutRef.current = setTimeout(() => controller.openDrawer(false), end - start)
61
76
  }
62
77
  controller.on(VreoKeyframeEnum.InfoPanel, callback)
63
78
 
64
- Object.assign(window, { $setInfoPanel: () => {
65
- controller.openDrawer({ content: (
66
-
67
- // <InfoPanelImg url='//vrlab-public.ljcdn.com/release/seesay/tools/cat_music___f68fb9bbe1f7cd6d00a16456dd0b09ad.gif'>
68
- <InfoPanelImg url='http://vrlab-public.ljcdn.com/common/images/web/d94e1bd7-0311-4b20-9c41-a1294fe43554.png'>
69
- <Title title="场景联动抓拍图片" subTitle={"2022.02.17 14:00"} />
70
- </InfoPanelImg>
71
- ), height: '60vh' })
72
- }})
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
+ // })
73
95
 
74
96
  return () => {
75
97
  controller.off(VreoKeyframeEnum.InfoPanel, callback)
@@ -1,5 +1,7 @@
1
- import { ReactNode } from 'react';
2
- 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'
3
5
 
4
6
  export interface PlayerConfigs {
5
7
  containter?: ReactDOM.Container
@@ -17,4 +19,12 @@ export interface PlayerConfigs {
17
19
  * 如果需要在 底部面板添加自定义内容,可以传递个 React 组件。
18
20
  */
19
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
20
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 {
@@ -101,9 +101,14 @@ export interface VreoUnit {
101
101
  * 剧本事件
102
102
  */
103
103
  export type VreoKeyframeEvent = { [key in VreoKeyframeEnum]: (keyframe: VreoKeyframe) => void } & {
104
+ // 新数据载入完成
104
105
  loaded: (vreoUnit: VreoUnit) => void
106
+ // 语音状态 播放 -> 暂停
105
107
  paused: () => void
108
+ // 语音状态 暂停 -> 播放
106
109
  playing: () => void
110
+ // 未知的 剧本帧类型
111
+ unknownKeyframeType: (keyframe: Record<string, any>) => void
107
112
  }
108
113
 
109
114
  /**
@@ -133,6 +138,7 @@ export type UpdateVRPanoramaData = {
133
138
  allow_hosts: string[]
134
139
  certificate: string
135
140
  expire_at: string
141
+ // 动态场景
136
142
  dynamic_scene?: {
137
143
  images: {
138
144
  index: number
@@ -235,7 +241,9 @@ export enum InfoPanelTypeEnum {
235
241
  export type InfoPanelData = {
236
242
  type: InfoPanelTypeEnum
237
243
  url: string
238
- tilte?: string
244
+ // 标题
245
+ title?: string
246
+ // 副标题
239
247
  subTitle?: string
240
248
  }
241
249
 
@@ -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
+