@ray-js/ipc-player-integration 0.0.50-beta.2 → 0.0.50-beta.3
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.
- package/lib/iconfont/iconfont.css +3 -3
- package/lib/iconfont/iconfont.json +1 -1
- package/lib/iconfont/iconfont.ttf +0 -0
- package/lib/iconfont/iconfont.woff +0 -0
- package/lib/iconfont/iconfont.woff2 +0 -0
- package/lib/ui/ui.js +43 -17
- package/lib/widgets/voiceIntercom/voiceIntercom.js +6 -1
- package/lib/widgets/zoomTurntable/constants.d.ts +162 -39
- package/lib/widgets/zoomTurntable/constants.js +273 -56
- package/lib/widgets/zoomTurntable/measureVisible.d.ts +9 -0
- package/lib/widgets/zoomTurntable/measureVisible.js +10 -0
- package/lib/widgets/zoomTurntable/turntable/index.js +5 -0
- package/lib/widgets/zoomTurntable/turntable/rjs/index.js +27 -4
- package/lib/widgets/zoomTurntable/turntable/rjs/index.rjs +132 -32
- package/lib/widgets/zoomTurntable/turntable/type.d.ts +41 -2
- package/lib/widgets/zoomTurntable/useLensZoom.d.ts +1 -0
- package/lib/widgets/zoomTurntable/useLensZoom.js +13 -0
- package/lib/widgets/zoomTurntable/zoomTurntableDock.js +94 -36
- package/lib/widgets/zoomTurntable/zoomTurntableEntry.js +96 -18
- package/lib/widgets/zoomTurntable/zoomTurntableTip.js +34 -22
- package/lib/widgets/zoomTurntable/zoomTurntableTip.less +23 -7
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
|
2
2
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
3
3
|
import "core-js/modules/esnext.iterator.map.js";
|
|
4
4
|
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
5
|
-
import { View, Text } from '@ray-js/ray';
|
|
5
|
+
import { View, Text, usePageEvent } from '@ray-js/ray';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
7
|
import { useMemoizedFn } from 'ahooks';
|
|
8
8
|
import { useStore } from '../../ctx/store';
|
|
@@ -13,9 +13,9 @@ import { Storage } from '../../utils/storage';
|
|
|
13
13
|
import { useLensZoom } from './useLensZoom';
|
|
14
14
|
import { ZoomTurntableDock } from './zoomTurntableDock';
|
|
15
15
|
import { ZoomTurntableTip } from './zoomTurntableTip';
|
|
16
|
-
import { measureEntryVisible } from './measureVisible';
|
|
16
|
+
import { measureBottomBarHeight, measureEntryVisible } from './measureVisible';
|
|
17
17
|
import { ZOOM_ENTRY_ANCHOR_CLS } from './entryAnchor';
|
|
18
|
-
import { LONG_PRESS_MS, MOVE_TOLERANCE,
|
|
18
|
+
import { FORCE_SHOW_ZOOM_TIP, LONG_PRESS_MS, MOVE_TOLERANCE, TIP_RESHOW_DELAY, getZoomDockBottom, getZoomDockHeight, getZoomDockRight, ZOOM_DOCK_Z_INDEX, zoomTurntableClose, zoomTurntableDockId, zoomTurntableOpen, zoomTurntableTipId } from './constants';
|
|
19
19
|
import './zoomTurntableEntry.less';
|
|
20
20
|
/**
|
|
21
21
|
* 焦距转盘入口:左下角工具条中的图标,长按弹出转盘。
|
|
@@ -39,12 +39,22 @@ export const ZoomTurntableEntry = props => {
|
|
|
39
39
|
const {
|
|
40
40
|
playState,
|
|
41
41
|
screenType,
|
|
42
|
-
|
|
42
|
+
isVerticalFullLayout
|
|
43
43
|
} = useStore({
|
|
44
44
|
playState: props.playState,
|
|
45
45
|
screenType: props.screenType,
|
|
46
|
-
|
|
46
|
+
isVerticalFullLayout: props.isVerticalFullLayout
|
|
47
47
|
});
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 竖屏两种布局,转盘的落位与是否让路完全不同:
|
|
51
|
+
* - 竖屏全屏(isVerticalFullLayout):底部工具条常驻在屏幕底部,转盘停在工具条**之上**,
|
|
52
|
+
* 工具条保持可见(能看到当前镜头、能直接点右下角那排按钮);
|
|
53
|
+
* - 普通竖屏:播放器只是页面顶部的一块,长按 tab 时把底部元素藏掉,
|
|
54
|
+
* 转盘**贴播放器底边**显示。
|
|
55
|
+
* 两种方式下转盘都落在播放器的底部区域。
|
|
56
|
+
*/
|
|
57
|
+
const isVerticalFull = screenType === 'vertical' && isVerticalFullLayout;
|
|
48
58
|
const {
|
|
49
59
|
multiLensReady,
|
|
50
60
|
lenses,
|
|
@@ -82,22 +92,39 @@ export const ZoomTurntableEntry = props => {
|
|
|
82
92
|
dockVisibleRef.current = false;
|
|
83
93
|
setDockVisible(false);
|
|
84
94
|
deleteContent('absolute', zoomTurntableDockId);
|
|
95
|
+
// 竖屏没藏过,这一发是幂等的(横屏才真正需要它恢复右侧控件)
|
|
85
96
|
event.emit(showAllComponent);
|
|
86
97
|
event.emit(startTimeToHideAllComponent);
|
|
87
98
|
});
|
|
88
|
-
const openDock = useMemoizedFn(() => {
|
|
99
|
+
const openDock = useMemoizedFn(async () => {
|
|
89
100
|
if (dockVisibleRef.current) {
|
|
90
101
|
closeDock();
|
|
91
102
|
return;
|
|
92
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* 竖屏全屏要让出底部工具条,高度按**实测**取:ui.tsx 给它写的是 48px,
|
|
106
|
+
* 而 `-full` 变体在 less 里还叠了 `padding-bottom: env(safe-area-inset-bottom)`,
|
|
107
|
+
* 实际占位跟机型 safe-area 有关,硬编码必然对不上。
|
|
108
|
+
* 长按本身已经等了 500ms,这里再等一帧测量,体感无差别;测不到就退回 48。
|
|
109
|
+
*/
|
|
110
|
+
const barHeight = isVerticalFull ? await measureBottomBarHeight() : null;
|
|
93
111
|
event.emit(widgetClick, {
|
|
94
112
|
widgetId: widgetLabs.ZOOM_TURNTABLE
|
|
95
113
|
});
|
|
96
114
|
// PTZ 与转盘都占底部 / 右侧,互斥
|
|
97
115
|
event.emit('ptzControlHide');
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
/**
|
|
117
|
+
* 只有竖屏全屏**不隐藏**其余元素:底部工具条常驻,转盘停在它上方 ——
|
|
118
|
+
* 这样能看到当前在哪个镜头,也能直接点右下角那排按钮,收起不必先点画面。
|
|
119
|
+
*
|
|
120
|
+
* 普通竖屏与横屏仍旧先藏:前者转盘要贴播放器底边、正压在工具条位置上,
|
|
121
|
+
* 后者转盘占右侧、与右侧控件正面重叠。
|
|
122
|
+
*
|
|
123
|
+
* 不要 emit('disablePlayerTap', true):点播放器收起转盘依赖 ui.tsx 正常派发 playerTap。
|
|
124
|
+
*/
|
|
125
|
+
if (!isVerticalFull) {
|
|
126
|
+
event.emit(hideAllComponent);
|
|
127
|
+
}
|
|
101
128
|
event.emit(pauseTimeToHideAllComponent);
|
|
102
129
|
if (!hasContent('absolute', zoomTurntableDockId)) {
|
|
103
130
|
// 必须用 CoverView 承载(不能设 absoluteNoCoverView):播放器是原生组件、层级更高,
|
|
@@ -107,14 +134,17 @@ export const ZoomTurntableEntry = props => {
|
|
|
107
134
|
content: dockProps => /*#__PURE__*/React.createElement(ZoomTurntableDock, dockProps),
|
|
108
135
|
absolutePosition: screenType === 'full' ? {
|
|
109
136
|
top: 0,
|
|
110
|
-
right:
|
|
137
|
+
right: getZoomDockRight(),
|
|
111
138
|
bottom: 0,
|
|
112
139
|
zIndex: ZOOM_DOCK_Z_INDEX
|
|
113
140
|
} : {
|
|
114
141
|
left: 0,
|
|
115
142
|
right: 0,
|
|
116
|
-
|
|
117
|
-
|
|
143
|
+
// 一律是带单位的 px 字符串 —— 裸数字会被当 rpx,见 constants 里 px() 的说明。
|
|
144
|
+
// 竖屏全屏让出底部工具条(实测高度,避免与 ui.tsx 的写死值不同步);
|
|
145
|
+
// 普通竖屏工具条已藏,直接下沉一份底部触摸余量贴住播放器底边。
|
|
146
|
+
bottom: getZoomDockBottom(isVerticalFull, barHeight),
|
|
147
|
+
height: getZoomDockHeight(isVerticalFull),
|
|
118
148
|
zIndex: ZOOM_DOCK_Z_INDEX
|
|
119
149
|
},
|
|
120
150
|
initProps: _objectSpread(_objectSpread({}, props), {}, {
|
|
@@ -138,6 +168,17 @@ export const ZoomTurntableEntry = props => {
|
|
|
138
168
|
};
|
|
139
169
|
}, [event, closeDock]);
|
|
140
170
|
|
|
171
|
+
/**
|
|
172
|
+
* 横竖屏切换、竖屏布局切换(展开/收起竖屏全屏)时都先收起转盘。
|
|
173
|
+
*
|
|
174
|
+
* dock 的 absolutePosition 只在 addContent 那一刻定死,三套落位差别很大
|
|
175
|
+
* (横屏右侧 / 竖屏全屏的工具条之上 / 普通竖屏贴播放器底边),
|
|
176
|
+
* 不收起的话浮层会留在旧位置上 —— 横竖屏之间尤其明显,连朝向都不对。
|
|
177
|
+
*/
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
if (dockVisibleRef.current) closeDock();
|
|
180
|
+
}, [screenType, isVerticalFull, closeDock]);
|
|
181
|
+
|
|
141
182
|
// 卸载 / 停流时兜底收起
|
|
142
183
|
useEffect(() => {
|
|
143
184
|
if (playState !== PlayState.PLAYING && dockVisibleRef.current) {
|
|
@@ -160,19 +201,58 @@ export const ZoomTurntableEntry = props => {
|
|
|
160
201
|
}, [multiLensReady, lenses.length, event]);
|
|
161
202
|
|
|
162
203
|
// ---------------- 圈选引导 ----------------
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* 把引导收起,并允许之后重新判定一次。
|
|
207
|
+
*
|
|
208
|
+
* 引导是挂在 absolute 槽位的浮层,停流 / 进入后台时它还留在最上层 ——
|
|
209
|
+
* 回到前台会先看见它盖在画面上,紧接着重新拉流把 playState 打断,它又消失,
|
|
210
|
+
* 观感就是「闪一下」。所以离开时主动收起,等重新出流稳定后再按可见性重新判定。
|
|
211
|
+
* 注意不写已读标记:用户还没点「知道了」,下次仍应提示。
|
|
212
|
+
*/
|
|
213
|
+
const dismissTipForRestart = useMemoizedFn(() => {
|
|
214
|
+
if (!hasContent('absolute', zoomTurntableTipId)) return;
|
|
215
|
+
deleteContent('absolute', zoomTurntableTipId);
|
|
216
|
+
tipCheckedRef.current = false;
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// 进入后台:先收起,避免回前台的第一帧就看到它压在重连画面上
|
|
220
|
+
usePageEvent('onHide', dismissTipForRestart);
|
|
221
|
+
|
|
222
|
+
// 停流 / 重连:同样先收起,等回到 PLAYING 再重新判定
|
|
223
|
+
useEffect(() => {
|
|
224
|
+
if (playState !== PlayState.PLAYING) {
|
|
225
|
+
dismissTipForRestart();
|
|
226
|
+
}
|
|
227
|
+
}, [playState, dismissTipForRestart]);
|
|
228
|
+
|
|
229
|
+
// 横竖屏切换:入口位置整个变了,旧引导的圈选坐标已失效,必须先收起再按新布局重测。
|
|
230
|
+
// 不收的话横屏、竖屏两套引导会同时留在屏幕上(absolute 槽位不会自动清理)。
|
|
231
|
+
useEffect(() => {
|
|
232
|
+
dismissTipForRestart();
|
|
233
|
+
}, [screenType, dismissTipForRestart]);
|
|
234
|
+
|
|
163
235
|
// 入口在横向 ScrollView 内可能被裁掉,只有真正可见时才提示;能力异步就绪,故判定在 multiLensReady 之后
|
|
164
236
|
useEffect(() => {
|
|
165
237
|
if (disableTip || !multiLensReady || playState !== PlayState.PLAYING) return undefined;
|
|
166
238
|
if (tipCheckedRef.current) return undefined;
|
|
167
239
|
let cancelled = false;
|
|
168
240
|
const storage = new Storage(devId);
|
|
169
|
-
|
|
241
|
+
// 刚出流时布局还在沉降(左下角元素陆续渲染、宽度还在长),等一小会儿再测再展示,
|
|
242
|
+
// 免得引导刚画好就因为入口位置变化而歪掉,也避免出流瞬间弹出来
|
|
243
|
+
const timer = setTimeout(async () => {
|
|
170
244
|
// key 不存在时 getStorage 会 fail,这里不能让它把整条链路带崩
|
|
171
245
|
const read = await storage.get(zoomTurntableTipId).catch(() => null);
|
|
172
|
-
if (cancelled
|
|
246
|
+
if (cancelled) return;
|
|
247
|
+
// 调试开关打开时忽略已读记录,每次都展示
|
|
248
|
+
if (read && !FORCE_SHOW_ZOOM_TIP) return;
|
|
173
249
|
const rect = await measureEntryVisible();
|
|
174
250
|
if (cancelled || !rect) return;
|
|
175
251
|
tipCheckedRef.current = true;
|
|
252
|
+
// ctx.addContent 不按 id 去重,重复添加会在屏幕上留下两份引导,这里先清一次
|
|
253
|
+
if (hasContent('absolute', zoomTurntableTipId)) {
|
|
254
|
+
deleteContent('absolute', zoomTurntableTipId);
|
|
255
|
+
}
|
|
176
256
|
addContent('absolute', {
|
|
177
257
|
id: zoomTurntableTipId,
|
|
178
258
|
content: tipProps => /*#__PURE__*/React.createElement(ZoomTurntableTip, tipProps),
|
|
@@ -181,9 +261,10 @@ export const ZoomTurntableEntry = props => {
|
|
|
181
261
|
anchorRect: rect
|
|
182
262
|
})
|
|
183
263
|
});
|
|
184
|
-
})
|
|
264
|
+
}, TIP_RESHOW_DELAY);
|
|
185
265
|
return () => {
|
|
186
266
|
cancelled = true;
|
|
267
|
+
clearTimeout(timer);
|
|
187
268
|
};
|
|
188
269
|
}, [disableTip, multiLensReady, playState, screenType, devId]);
|
|
189
270
|
|
|
@@ -254,9 +335,6 @@ export const ZoomTurntableEntry = props => {
|
|
|
254
335
|
'ipc-player-plugin-zoom-turntable-tab-full': screenType === 'full',
|
|
255
336
|
'ipc-player-plugin-zoom-turntable-tab-active': active
|
|
256
337
|
}),
|
|
257
|
-
style: active && dockVisible ? {
|
|
258
|
-
backgroundColor: brandColor
|
|
259
|
-
} : undefined,
|
|
260
338
|
onTouchStart: onTouchStart,
|
|
261
339
|
onTouchMove: onTouchMove,
|
|
262
340
|
onTouchEnd: () => onTouchEnd(index),
|
|
@@ -7,7 +7,7 @@ import { widgetClick, widgetLabs } from '../../ui/constant';
|
|
|
7
7
|
import { Storage } from '../../utils/storage';
|
|
8
8
|
import Strings from '../../i18n';
|
|
9
9
|
import { measurePlayerRect } from './measureVisible';
|
|
10
|
-
import {
|
|
10
|
+
import { FORCE_SHOW_ZOOM_TIP, TIP_LINE_TOTAL, TIP_PANEL_EDGE_GAP, TIP_PANEL_LINE_GAP, TIP_PANEL_WIDTH, TIP_RING_PADDING, zoomTurntableTipId } from './constants';
|
|
11
11
|
import './zoomTurntableTip.less';
|
|
12
12
|
/**
|
|
13
13
|
* 焦距入口圈选引导(一次性)。
|
|
@@ -26,51 +26,63 @@ export const ZoomTurntableTip = props => {
|
|
|
26
26
|
} = useStore({
|
|
27
27
|
playState: props.playState
|
|
28
28
|
});
|
|
29
|
-
const [
|
|
29
|
+
const [layout, setLayout] = useState(null);
|
|
30
30
|
|
|
31
|
-
//
|
|
31
|
+
// 把入口的视口坐标换算成播放器容器内坐标。
|
|
32
|
+
// 圈选框按入口实测 rect 自适应:入口是横向倍率胶囊,宽度随镜头数(2 个约 96px、
|
|
33
|
+
// 3 个约 132px)变化,用固定尺寸框不住。
|
|
32
34
|
useEffect(() => {
|
|
33
35
|
if (!anchorRect) return undefined;
|
|
34
36
|
let cancelled = false;
|
|
35
37
|
measurePlayerRect().then(player => {
|
|
36
38
|
if (cancelled || !player) return;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const ringWidth = anchorRect.width + TIP_RING_PADDING * 2;
|
|
40
|
+
const ringHeight = anchorRect.height + TIP_RING_PADDING * 2;
|
|
41
|
+
const ringLeft = anchorRect.left - player.left - TIP_RING_PADDING;
|
|
42
|
+
const ringBottom = player.bottom - anchorRect.bottom - TIP_RING_PADDING;
|
|
43
|
+
// 文案面板以圈选中心对齐,但不越出播放器左右边缘
|
|
44
|
+
const maxLeft = Math.max(player.width - TIP_PANEL_WIDTH - TIP_PANEL_EDGE_GAP, TIP_PANEL_EDGE_GAP);
|
|
45
|
+
const panelLeft = Math.min(Math.max(ringLeft + ringWidth / 2 - TIP_PANEL_WIDTH / 2, TIP_PANEL_EDGE_GAP), maxLeft);
|
|
46
|
+
setLayout({
|
|
47
|
+
ring: {
|
|
48
|
+
left: `${ringLeft}px`,
|
|
49
|
+
bottom: `${ringBottom}px`,
|
|
50
|
+
width: `${ringWidth}px`,
|
|
51
|
+
height: `${ringHeight}px`
|
|
52
|
+
},
|
|
53
|
+
panel: {
|
|
54
|
+
left: `${panelLeft}px`,
|
|
55
|
+
bottom: `${ringBottom + ringHeight + TIP_LINE_TOTAL + TIP_PANEL_LINE_GAP}px`,
|
|
56
|
+
width: `${TIP_PANEL_WIDTH}px`
|
|
57
|
+
}
|
|
43
58
|
});
|
|
44
59
|
});
|
|
45
60
|
return () => {
|
|
46
61
|
cancelled = true;
|
|
47
62
|
};
|
|
48
63
|
}, [anchorRect]);
|
|
49
|
-
if (playState !== PlayState.PLAYING || !
|
|
64
|
+
if (playState !== PlayState.PLAYING || !layout) {
|
|
50
65
|
return null;
|
|
51
66
|
}
|
|
52
67
|
return /*#__PURE__*/React.createElement(CoverView, null, /*#__PURE__*/React.createElement(View, {
|
|
53
68
|
className: clsx('ipc-player-plugin-zoom-turntable-tip-ring'),
|
|
54
|
-
style:
|
|
55
|
-
}), /*#__PURE__*/React.createElement(
|
|
56
|
-
className: clsx('ipc-player-plugin-zoom-turntable-tip-
|
|
57
|
-
style:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
69
|
+
style: layout.ring
|
|
70
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
71
|
+
className: clsx('ipc-player-plugin-zoom-turntable-tip-panel'),
|
|
72
|
+
style: layout.panel
|
|
73
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
74
|
+
className: clsx('ipc-player-plugin-zoom-turntable-tip-text')
|
|
61
75
|
}, Strings.getLang('ipc_player_zoom_turntable_tip_text')), /*#__PURE__*/React.createElement(View, {
|
|
62
76
|
className: clsx('ipc-player-plugin-zoom-turntable-tip-button'),
|
|
63
|
-
style: {
|
|
64
|
-
left: ringStyle.left,
|
|
65
|
-
bottom: `calc(${ringStyle.bottom} + 56px)`
|
|
66
|
-
},
|
|
67
77
|
onClick: () => {
|
|
68
78
|
props.event.emit(widgetClick, {
|
|
69
79
|
widgetId: widgetLabs.ZOOM_TURNTABLE_TIP
|
|
70
80
|
});
|
|
71
81
|
deleteContent('absolute', zoomTurntableTipId);
|
|
82
|
+
// 调试开关打开时不落已读标记,免得自测一次就再也看不到
|
|
83
|
+
if (FORCE_SHOW_ZOOM_TIP) return;
|
|
72
84
|
const storage = new Storage(devId);
|
|
73
85
|
storage.set(zoomTurntableTipId, true);
|
|
74
86
|
}
|
|
75
|
-
}, Strings.getLang('ipc_player_tip_confirm')));
|
|
87
|
+
}, Strings.getLang('ipc_player_tip_confirm'))));
|
|
76
88
|
};
|
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
font-size: 14px;
|
|
11
11
|
color: #fff;
|
|
12
12
|
|
|
13
|
+
// 圈选框:尺寸与位置按入口实测 rect 由 JS 内联注入。
|
|
14
|
+
// 入口是横向倍率胶囊,用圆角矩形贴合,不用正圆(正圆框不住宽度、上下还会超出)。
|
|
13
15
|
.ipc-player-plugin-zoom-turntable-tip-ring {
|
|
14
16
|
position: absolute;
|
|
17
|
+
box-sizing: border-box;
|
|
15
18
|
border: 1px dashed rgba(255, 255, 255, 0.5);
|
|
16
|
-
border-radius:
|
|
19
|
+
border-radius: 12px;
|
|
17
20
|
// 超大扩散阴影把全屏压暗,只露出被圈选的入口
|
|
18
21
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);
|
|
19
22
|
|
|
@@ -23,13 +26,13 @@
|
|
|
23
26
|
position: absolute;
|
|
24
27
|
left: 50%;
|
|
25
28
|
width: 1px;
|
|
26
|
-
height:
|
|
29
|
+
height: 17px;
|
|
27
30
|
box-sizing: border-box;
|
|
28
31
|
border-left: 1px dashed rgba(255, 255, 255, 0.5);
|
|
29
32
|
transform: translateX(-50%) translateY(-100%);
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
//
|
|
35
|
+
// 引线末端的小圆点:17 虚线 + 4 圆点
|
|
33
36
|
&::before {
|
|
34
37
|
content: '';
|
|
35
38
|
position: absolute;
|
|
@@ -38,18 +41,31 @@
|
|
|
38
41
|
height: 4px;
|
|
39
42
|
border-radius: 50%;
|
|
40
43
|
background-color: rgba(255, 255, 255, 0.5);
|
|
41
|
-
transform: translateX(-50%) translateY(-
|
|
44
|
+
transform: translateX(-50%) translateY(-21px);
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
// 文案 + 按钮面板:整体定位一次并对齐圈选框中心,内部居中堆叠,
|
|
49
|
+
// 间距交给布局,不再靠魔法数各自偏移
|
|
50
|
+
.ipc-player-plugin-zoom-turntable-tip-panel {
|
|
46
51
|
position: absolute;
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.ipc-player-plugin-zoom-turntable-tip-text {
|
|
47
58
|
max-width: 200px;
|
|
59
|
+
line-height: 1.4;
|
|
60
|
+
text-align: center;
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
.ipc-player-plugin-zoom-turntable-tip-button {
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
margin-top: 12px;
|
|
65
|
+
// 比 multiCamera 的 tile-tip(12/32)收紧一圈:引导只是一句短提示,按钮不必那么重
|
|
66
|
+
padding: 7px 20px;
|
|
67
|
+
font-size: 12px;
|
|
68
|
+
line-height: 1.4;
|
|
53
69
|
border: 1px solid rgba(255, 255, 255, 0.5);
|
|
54
70
|
border-radius: 250px;
|
|
55
71
|
}
|