@ray-js/ipc-player-integration 0.0.50-beta.1 → 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.
Files changed (39) hide show
  1. package/README.md +11 -11
  2. package/lib/ctx/ctx.composition.js +5 -5
  3. package/lib/hooks/useBattery/index.js +7 -1
  4. package/lib/iconfont/iconfont.css +127 -7
  5. package/lib/iconfont/iconfont.js +10 -10
  6. package/lib/iconfont/iconfont.json +234 -24
  7. package/lib/iconfont/iconfont.ttf +0 -0
  8. package/lib/iconfont/iconfont.woff +0 -0
  9. package/lib/iconfont/iconfont.woff2 +0 -0
  10. package/lib/interface.d.ts +1 -1
  11. package/lib/interface.js +1 -1
  12. package/lib/ports.output.d.ts +13 -0
  13. package/lib/ports.output.js +13 -0
  14. package/lib/ui/bottomLeftContent.js +141 -27
  15. package/lib/ui/bottomRightContent.d.ts +6 -1
  16. package/lib/ui/bottomRightContent.js +43 -5
  17. package/lib/ui/ui.js +101 -21
  18. package/lib/ui/ui.less +17 -0
  19. package/lib/widgets/battery/battery.js +11 -3
  20. package/lib/widgets/battery/battery.less +11 -0
  21. package/lib/widgets/battery/batteryFull.js +11 -3
  22. package/lib/widgets/voiceIntercom/voiceIntercom.js +6 -1
  23. package/lib/widgets/zoomTurntable/constants.d.ts +187 -32
  24. package/lib/widgets/zoomTurntable/constants.js +306 -45
  25. package/lib/widgets/zoomTurntable/measureVisible.d.ts +9 -0
  26. package/lib/widgets/zoomTurntable/measureVisible.js +10 -0
  27. package/lib/widgets/zoomTurntable/turntable/index.js +9 -1
  28. package/lib/widgets/zoomTurntable/turntable/rjs/index.js +27 -4
  29. package/lib/widgets/zoomTurntable/turntable/rjs/index.rjs +265 -36
  30. package/lib/widgets/zoomTurntable/turntable/rjs/index.tyml +1 -0
  31. package/lib/widgets/zoomTurntable/turntable/type.d.ts +41 -2
  32. package/lib/widgets/zoomTurntable/useLensZoom.d.ts +3 -0
  33. package/lib/widgets/zoomTurntable/useLensZoom.js +96 -4
  34. package/lib/widgets/zoomTurntable/zoomTurntableDock.js +143 -13
  35. package/lib/widgets/zoomTurntable/zoomTurntableEntry.js +116 -23
  36. package/lib/widgets/zoomTurntable/zoomTurntableEntry.less +11 -1
  37. package/lib/widgets/zoomTurntable/zoomTurntableTip.js +34 -22
  38. package/lib/widgets/zoomTurntable/zoomTurntableTip.less +23 -7
  39. package/package.json +2 -2
@@ -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, ZOOM_DOCK_BOTTOM, ZOOM_DOCK_HEIGHT, ZOOM_DOCK_RIGHT, ZOOM_DOCK_Z_INDEX, zoomTurntableClose, zoomTurntableDockId, zoomTurntableOpen, zoomTurntableTipId } from './constants';
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,19 +39,36 @@ export const ZoomTurntableEntry = props => {
39
39
  const {
40
40
  playState,
41
41
  screenType,
42
- brandColor
42
+ isVerticalFullLayout
43
43
  } = useStore({
44
44
  playState: props.playState,
45
45
  screenType: props.screenType,
46
- brandColor: props.brandColor
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,
51
61
  lensIndex,
62
+ switchingIndex,
52
63
  curM,
53
64
  switchToLens
54
65
  } = useLensZoom(props);
66
+
67
+ // 切换真空期(下发成功 ~ channelChange / 超时收尾)里镜头下标还没动,
68
+ // 高亮提前落到目标镜头,且各 tab 一律显示自己的光学倍数:
69
+ // 否则原镜头的 tab 上会先冒出目标镜头的读数,收尾后再跳回去。
70
+ const isLensSwitching = switchingIndex >= 0;
71
+ const activeIndex = isLensSwitching ? switchingIndex : lensIndex;
55
72
  const [dockVisible, setDockVisible] = useState(false);
56
73
  const timerRef = useRef();
57
74
  const startRef = useRef();
@@ -61,6 +78,9 @@ export const ZoomTurntableEntry = props => {
61
78
  const cancelledRef = useRef(false);
62
79
  const dockVisibleRef = useRef(false);
63
80
  const tipCheckedRef = useRef(false);
81
+ /** onTouchEnd 是稳定引用,用 ref 取最新的高亮下标 */
82
+ const activeIndexRef = useRef(activeIndex);
83
+ activeIndexRef.current = activeIndex;
64
84
  const clearTimer = () => {
65
85
  if (timerRef.current) {
66
86
  clearTimeout(timerRef.current);
@@ -72,22 +92,39 @@ export const ZoomTurntableEntry = props => {
72
92
  dockVisibleRef.current = false;
73
93
  setDockVisible(false);
74
94
  deleteContent('absolute', zoomTurntableDockId);
95
+ // 竖屏没藏过,这一发是幂等的(横屏才真正需要它恢复右侧控件)
75
96
  event.emit(showAllComponent);
76
97
  event.emit(startTimeToHideAllComponent);
77
98
  });
78
- const openDock = useMemoizedFn(() => {
99
+ const openDock = useMemoizedFn(async () => {
79
100
  if (dockVisibleRef.current) {
80
101
  closeDock();
81
102
  return;
82
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;
83
111
  event.emit(widgetClick, {
84
112
  widgetId: widgetLabs.ZOOM_TURNTABLE
85
113
  });
86
114
  // PTZ 与转盘都占底部 / 右侧,互斥
87
115
  event.emit('ptzControlHide');
88
- // 其余元素隐藏并暂停自动隐藏倒计时。
89
- // 不要 emit('disablePlayerTap', true):点播放器收起转盘依赖 ui.tsx 正常派发 playerTap。
90
- event.emit(hideAllComponent);
116
+ /**
117
+ * 只有竖屏全屏**不隐藏**其余元素:底部工具条常驻,转盘停在它上方 ——
118
+ * 这样能看到当前在哪个镜头,也能直接点右下角那排按钮,收起不必先点画面。
119
+ *
120
+ * 普通竖屏与横屏仍旧先藏:前者转盘要贴播放器底边、正压在工具条位置上,
121
+ * 后者转盘占右侧、与右侧控件正面重叠。
122
+ *
123
+ * 不要 emit('disablePlayerTap', true):点播放器收起转盘依赖 ui.tsx 正常派发 playerTap。
124
+ */
125
+ if (!isVerticalFull) {
126
+ event.emit(hideAllComponent);
127
+ }
91
128
  event.emit(pauseTimeToHideAllComponent);
92
129
  if (!hasContent('absolute', zoomTurntableDockId)) {
93
130
  // 必须用 CoverView 承载(不能设 absoluteNoCoverView):播放器是原生组件、层级更高,
@@ -97,14 +134,17 @@ export const ZoomTurntableEntry = props => {
97
134
  content: dockProps => /*#__PURE__*/React.createElement(ZoomTurntableDock, dockProps),
98
135
  absolutePosition: screenType === 'full' ? {
99
136
  top: 0,
100
- right: ZOOM_DOCK_RIGHT,
137
+ right: getZoomDockRight(),
101
138
  bottom: 0,
102
139
  zIndex: ZOOM_DOCK_Z_INDEX
103
140
  } : {
104
141
  left: 0,
105
142
  right: 0,
106
- bottom: ZOOM_DOCK_BOTTOM,
107
- height: ZOOM_DOCK_HEIGHT,
143
+ // 一律是带单位的 px 字符串 —— 裸数字会被当 rpx,见 constants 里 px() 的说明。
144
+ // 竖屏全屏让出底部工具条(实测高度,避免与 ui.tsx 的写死值不同步);
145
+ // 普通竖屏工具条已藏,直接下沉一份底部触摸余量贴住播放器底边。
146
+ bottom: getZoomDockBottom(isVerticalFull, barHeight),
147
+ height: getZoomDockHeight(isVerticalFull),
108
148
  zIndex: ZOOM_DOCK_Z_INDEX
109
149
  },
110
150
  initProps: _objectSpread(_objectSpread({}, props), {}, {
@@ -128,6 +168,17 @@ export const ZoomTurntableEntry = props => {
128
168
  };
129
169
  }, [event, closeDock]);
130
170
 
171
+ /**
172
+ * 横竖屏切换、竖屏布局切换(展开/收起竖屏全屏)时都先收起转盘。
173
+ *
174
+ * dock 的 absolutePosition 只在 addContent 那一刻定死,三套落位差别很大
175
+ * (横屏右侧 / 竖屏全屏的工具条之上 / 普通竖屏贴播放器底边),
176
+ * 不收起的话浮层会留在旧位置上 —— 横竖屏之间尤其明显,连朝向都不对。
177
+ */
178
+ useEffect(() => {
179
+ if (dockVisibleRef.current) closeDock();
180
+ }, [screenType, isVerticalFull, closeDock]);
181
+
131
182
  // 卸载 / 停流时兜底收起
132
183
  useEffect(() => {
133
184
  if (playState !== PlayState.PLAYING && dockVisibleRef.current) {
@@ -150,19 +201,58 @@ export const ZoomTurntableEntry = props => {
150
201
  }, [multiLensReady, lenses.length, event]);
151
202
 
152
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
+
153
235
  // 入口在横向 ScrollView 内可能被裁掉,只有真正可见时才提示;能力异步就绪,故判定在 multiLensReady 之后
154
236
  useEffect(() => {
155
237
  if (disableTip || !multiLensReady || playState !== PlayState.PLAYING) return undefined;
156
238
  if (tipCheckedRef.current) return undefined;
157
239
  let cancelled = false;
158
240
  const storage = new Storage(devId);
159
- (async () => {
241
+ // 刚出流时布局还在沉降(左下角元素陆续渲染、宽度还在长),等一小会儿再测再展示,
242
+ // 免得引导刚画好就因为入口位置变化而歪掉,也避免出流瞬间弹出来
243
+ const timer = setTimeout(async () => {
160
244
  // key 不存在时 getStorage 会 fail,这里不能让它把整条链路带崩
161
245
  const read = await storage.get(zoomTurntableTipId).catch(() => null);
162
- if (cancelled || read) return;
246
+ if (cancelled) return;
247
+ // 调试开关打开时忽略已读记录,每次都展示
248
+ if (read && !FORCE_SHOW_ZOOM_TIP) return;
163
249
  const rect = await measureEntryVisible();
164
250
  if (cancelled || !rect) return;
165
251
  tipCheckedRef.current = true;
252
+ // ctx.addContent 不按 id 去重,重复添加会在屏幕上留下两份引导,这里先清一次
253
+ if (hasContent('absolute', zoomTurntableTipId)) {
254
+ deleteContent('absolute', zoomTurntableTipId);
255
+ }
166
256
  addContent('absolute', {
167
257
  id: zoomTurntableTipId,
168
258
  content: tipProps => /*#__PURE__*/React.createElement(ZoomTurntableTip, tipProps),
@@ -171,9 +261,10 @@ export const ZoomTurntableEntry = props => {
171
261
  anchorRect: rect
172
262
  })
173
263
  });
174
- })();
264
+ }, TIP_RESHOW_DELAY);
175
265
  return () => {
176
266
  cancelled = true;
267
+ clearTimeout(timer);
177
268
  };
178
269
  }, [disableTip, multiLensReady, playState, screenType, devId]);
179
270
 
@@ -211,13 +302,17 @@ export const ZoomTurntableEntry = props => {
211
302
  clearTimer();
212
303
  // firedRef:长按已出转盘,不再当作点击处理
213
304
  if (!firedRef.current && !cancelledRef.current) {
214
- if (index !== lensIndex) {
305
+ // activeIndex 比:正在切往的那个 tab 再点一次不该重复下发
306
+ if (index !== activeIndexRef.current) {
215
307
  event.emit(widgetClick, {
216
308
  widgetId: widgetLabs.ZOOM_TURNTABLE
217
309
  });
218
310
  switchToLens(index);
219
311
  }
220
- event.emit(startTimeToHideAllComponent);
312
+ // 点过 tab 之后不重启自动隐藏倒计时(onTouchStart 已 pause,这里保持暂停):
313
+ // 切镜头真正生效要等 channelChange / 超时收尾,5s 倒计时会在切换过程中把工具条藏掉,
314
+ // 用户看不到读数落位。收起交给用户点播放器(ui.tsx handPlayerTap 直接置隐藏,
315
+ // 不依赖倒计时,暂停状态下照常生效)。
221
316
  }
222
317
  });
223
318
  if (playState !== PlayState.PLAYING || !multiLensReady) {
@@ -230,18 +325,16 @@ export const ZoomTurntableEntry = props => {
230
325
  'ipc-player-plugin-zoom-turntable-tabs-full': screenType === 'full'
231
326
  })
232
327
  }, lenses.map((lens, index) => {
233
- const active = index === lensIndex;
234
- // 当前镜头实时显示画面绝对倍率(手势放大时 1.0X → 2.5X),其余显示各自光学倍数
235
- const text = `${(active ? curM : lens.basicRatio).toFixed(1)}X`;
328
+ const active = index === activeIndex;
329
+ // 当前镜头实时显示画面绝对倍率(手势放大时 1.0X → 2.5X),其余显示各自光学倍数;
330
+ // 切换进行中则一律显示光学倍数 —— 此时 curM 已指向目标值,挂谁身上都是跳变
331
+ const text = `${(active && !isLensSwitching ? curM : lens.basicRatio).toFixed(1)}X`;
236
332
  return /*#__PURE__*/React.createElement(View, {
237
333
  key: lens.id,
238
334
  className: clsx('ipc-player-plugin-zoom-turntable-tab', {
239
335
  'ipc-player-plugin-zoom-turntable-tab-full': screenType === 'full',
240
336
  'ipc-player-plugin-zoom-turntable-tab-active': active
241
337
  }),
242
- style: active && dockVisible ? {
243
- backgroundColor: brandColor
244
- } : undefined,
245
338
  onTouchStart: onTouchStart,
246
339
  onTouchMove: onTouchMove,
247
340
  onTouchEnd: () => onTouchEnd(index),
@@ -27,18 +27,28 @@
27
27
  align-items: center;
28
28
  padding: calc(4px * var(--ipc-player-size-scale, 1)) calc(5px * var(--ipc-player-size-scale, 1));
29
29
  background-color: rgba(255, 255, 255, 0.3);
30
+ // 读数每帧都在变(4.1X → 4.8X),比例字体下 1 比 8 窄,胶囊宽度会跟着抖,
31
+ // 还会连带触发左下角工具条的重测。min-width 撑住 "N.NX" 的最宽排布,
32
+ // 加上 box-sizing 让 padding 计入,宽度就不再随数字变化。
33
+ // 超过 4 字符(10.0X)时自然撑开,那是跨十倍才发生一次的变化。
34
+ box-sizing: border-box;
35
+ min-width: calc(38px * var(--ipc-player-size-scale, 1));
30
36
 
31
37
  .ipc-player-plugin-zoom-turntable-tab-text {
32
38
  color: var(--iconColor);
33
39
  font-weight: 600;
34
40
  font-size: calc(12px * var(--ipc-player-size-scale, 1));
41
+ // 等宽数字:让 0-9 占同样的字身宽,从根上消掉逐帧抖动(渲染层支持时生效)
42
+ font-variant-numeric: tabular-nums;
43
+ font-feature-settings: 'tnum';
35
44
  }
36
45
  }
37
46
 
38
- // 横屏:左右 padding 放宽,同 RealTimeMagnification 的 full
47
+ // 横屏:左右 padding 放宽,同 RealTimeMagnification 的 full 态;min-width 同步加宽
39
48
  .ipc-player-plugin-zoom-turntable-tab-full {
40
49
  padding-left: calc(8px * var(--ipc-player-size-scale, 1));
41
50
  padding-right: calc(8px * var(--ipc-player-size-scale, 1));
51
+ min-width: calc(44px * var(--ipc-player-size-scale, 1));
42
52
  }
43
53
 
44
54
  // 选中态:白底黑字(须在基础态之后定义,同优先级下后者生效)
@@ -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 { TIP_RING_SIZE, zoomTurntableTipId } from './constants';
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 [ringStyle, setRingStyle] = useState(null);
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 centerX = anchorRect.left - player.left + anchorRect.width / 2;
38
- setRingStyle({
39
- left: `${centerX - TIP_RING_SIZE / 2}px`,
40
- bottom: `${player.bottom - anchorRect.bottom - (TIP_RING_SIZE - anchorRect.height) / 2}px`,
41
- width: `${TIP_RING_SIZE}px`,
42
- height: `${TIP_RING_SIZE}px`
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 || !ringStyle) {
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: ringStyle
55
- }), /*#__PURE__*/React.createElement(Text, {
56
- className: clsx('ipc-player-plugin-zoom-turntable-tip-text'),
57
- style: {
58
- left: ringStyle.left,
59
- bottom: `calc(${ringStyle.bottom} + 116px)`
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: 50%;
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: 40px;
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(-44px);
44
+ transform: translateX(-50%) translateY(-21px);
42
45
  }
43
46
  }
44
47
 
45
- .ipc-player-plugin-zoom-turntable-tip-text {
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
- position: absolute;
52
- padding: 12px 32px;
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ipc-player-integration",
3
- "version": "0.0.50-beta.1",
3
+ "version": "0.0.50-beta.3",
4
4
  "description": "IPC 融合播放器",
5
5
  "main": "lib/index",
6
6
  "files": [
@@ -48,7 +48,7 @@
48
48
  "@commitlint/cli": "^7.2.1",
49
49
  "@commitlint/config-conventional": "^9.0.1",
50
50
  "@ray-js/cli": "^1.7.61",
51
- "@ray-js/ray": "1.7.83-beta.0",
51
+ "@ray-js/ray": "^1.7.83",
52
52
  "@testing-library/react-hooks": "^8.0.1",
53
53
  "@types/jest": "^29.5.14",
54
54
  "ahooks": "^3.8.4",