@midscene/visualizer 1.3.7 → 1.3.8-beta-20260206024209.0
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/dist/es/component/player/index.css +30 -0
- package/dist/es/component/player/index.mjs +74 -41
- package/dist/es/store/store.mjs +15 -0
- package/dist/lib/component/player/index.css +30 -0
- package/dist/lib/component/player/index.js +73 -40
- package/dist/lib/store/store.js +15 -0
- package/dist/types/store/store.d.ts +3 -0
- package/package.json +5 -5
|
@@ -209,3 +209,33 @@
|
|
|
209
209
|
background: rgba(255, 255, 255, .08);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
.player-settings-dropdown {
|
|
213
|
+
background-color: #fff;
|
|
214
|
+
border: 1px solid rgba(0, 0, 0, .08);
|
|
215
|
+
border-radius: 8px;
|
|
216
|
+
padding: 4px;
|
|
217
|
+
overflow: hidden;
|
|
218
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, .08);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.player-settings-divider {
|
|
222
|
+
background: rgba(0, 0, 0, .06);
|
|
223
|
+
height: 1px;
|
|
224
|
+
margin: 4px 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.player-speed-option:hover, .player-settings-item:hover {
|
|
228
|
+
background: rgba(0, 0, 0, .04);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
[data-theme="dark"] .player-settings-dropdown {
|
|
232
|
+
color: #f8fafd;
|
|
233
|
+
background-color: #1f1f1f;
|
|
234
|
+
border-color: rgba(255, 255, 255, .08);
|
|
235
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, .3);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
[data-theme="dark"] .player-settings-divider, [data-theme="dark"] .player-speed-option:hover, [data-theme="dark"] .player-settings-item:hover {
|
|
239
|
+
background: rgba(255, 255, 255, .08);
|
|
240
|
+
}
|
|
241
|
+
|
|
@@ -5,7 +5,7 @@ import { Application, Container, Sprite } from "pixi.js";
|
|
|
5
5
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import "./index.css";
|
|
7
7
|
import { mouseLoading, mousePointer } from "../../utils/index.mjs";
|
|
8
|
-
import { CaretRightOutlined, DownloadOutlined, ExportOutlined, LoadingOutlined } from "@ant-design/icons";
|
|
8
|
+
import { CaretRightOutlined, DownloadOutlined, ExportOutlined, LoadingOutlined, ThunderboltOutlined } from "@ant-design/icons";
|
|
9
9
|
import { Dropdown, Spin, Switch, Tooltip, message } from "antd";
|
|
10
10
|
import global_perspective from "../../icons/global-perspective.mjs";
|
|
11
11
|
import player_setting from "../../icons/player-setting.mjs";
|
|
@@ -204,7 +204,7 @@ function Player(props) {
|
|
|
204
204
|
var _scripts_;
|
|
205
205
|
const [titleText, setTitleText] = useState('');
|
|
206
206
|
const [subTitleText, setSubTitleText] = useState('');
|
|
207
|
-
const { autoZoom, setAutoZoom } = useGlobalPreference();
|
|
207
|
+
const { autoZoom, setAutoZoom, playbackSpeed, setPlaybackSpeed } = useGlobalPreference();
|
|
208
208
|
useEffect(()=>{
|
|
209
209
|
if ((null == props ? void 0 : props.autoZoom) !== void 0) setAutoZoom(props.autoZoom);
|
|
210
210
|
}, [
|
|
@@ -549,7 +549,9 @@ function Player(props) {
|
|
|
549
549
|
var _scripts_;
|
|
550
550
|
if (!app || !appInitialized.current) throw new Error('app is not initialized');
|
|
551
551
|
if (!scripts) throw new Error("scripts is required");
|
|
552
|
-
const { frame, cancel, timeout, sleep } = frameKit();
|
|
552
|
+
const { frame, cancel, timeout, sleep: baseSleep } = frameKit();
|
|
553
|
+
const scaleByPlaybackSpeed = (duration)=>duration / playbackSpeed;
|
|
554
|
+
const sleep = (ms)=>baseSleep(scaleByPlaybackSpeed(ms));
|
|
553
555
|
cancelFn = cancel;
|
|
554
556
|
cancelAnimationRef.current = cancel;
|
|
555
557
|
const allImages = scripts.filter((item)=>!!item.img).map((item)=>item.img);
|
|
@@ -562,7 +564,7 @@ function Player(props) {
|
|
|
562
564
|
yield updatePointer(mousePointer, imageWidth / 2, imageHeight / 2);
|
|
563
565
|
yield repaintImage();
|
|
564
566
|
yield updateCamera(_object_spread({}, basicCameraState));
|
|
565
|
-
const totalDuration = scripts.reduce((acc, item)=>acc + item.duration + (item.camera && item.insightCameraDuration ? item.insightCameraDuration : 0), 0);
|
|
567
|
+
const totalDuration = scaleByPlaybackSpeed(scripts.reduce((acc, item)=>acc + item.duration + (item.camera && item.insightCameraDuration ? item.insightCameraDuration : 0), 0));
|
|
566
568
|
const progressUpdateInterval = 200;
|
|
567
569
|
const startTime = performance.now();
|
|
568
570
|
setAnimationProgress(0);
|
|
@@ -598,13 +600,13 @@ function Player(props) {
|
|
|
598
600
|
const highlightElements = item.highlightElement ? [
|
|
599
601
|
item.highlightElement
|
|
600
602
|
] : [];
|
|
601
|
-
yield insightElementsAnimation([], highlightElements, item.searchArea, item.duration, frame);
|
|
603
|
+
yield insightElementsAnimation([], highlightElements, item.searchArea, scaleByPlaybackSpeed(item.duration), frame);
|
|
602
604
|
if (item.camera) {
|
|
603
605
|
if (!item.insightCameraDuration) throw new Error('insightCameraDuration is required');
|
|
604
|
-
yield cameraAnimation(item.camera, item.insightCameraDuration, frame);
|
|
606
|
+
yield cameraAnimation(item.camera, scaleByPlaybackSpeed(item.insightCameraDuration), frame);
|
|
605
607
|
}
|
|
606
608
|
} else if ('clear-insight' === item.type) {
|
|
607
|
-
yield fadeOutItem(insightMarkContainer, item.duration, frame);
|
|
609
|
+
yield fadeOutItem(insightMarkContainer, scaleByPlaybackSpeed(item.duration), frame);
|
|
608
610
|
insightMarkContainer.removeChildren();
|
|
609
611
|
insightMarkContainer.alpha = 1;
|
|
610
612
|
} else if ('img' === item.type) {
|
|
@@ -612,7 +614,7 @@ function Player(props) {
|
|
|
612
614
|
currentImg.current = item.img;
|
|
613
615
|
yield repaintImage(item.imageWidth, item.imageHeight);
|
|
614
616
|
}
|
|
615
|
-
if (item.camera) yield cameraAnimation(item.camera, item.duration, frame);
|
|
617
|
+
if (item.camera) yield cameraAnimation(item.camera, scaleByPlaybackSpeed(item.duration), frame);
|
|
616
618
|
else yield sleep(item.duration);
|
|
617
619
|
} else if ('pointer' === item.type) {
|
|
618
620
|
if (!item.img) throw new Error('pointer img is required');
|
|
@@ -810,36 +812,18 @@ function Player(props) {
|
|
|
810
812
|
overlayStyle: {
|
|
811
813
|
minWidth: '148px'
|
|
812
814
|
},
|
|
813
|
-
dropdownRender: (
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
|
819
|
-
overflow: 'hidden'
|
|
820
|
-
},
|
|
821
|
-
children: menu
|
|
822
|
-
}),
|
|
823
|
-
menu: {
|
|
824
|
-
style: {
|
|
825
|
-
borderRadius: '8px',
|
|
826
|
-
padding: 0
|
|
827
|
-
},
|
|
828
|
-
items: [
|
|
829
|
-
{
|
|
830
|
-
key: 'autoZoom',
|
|
831
|
-
style: {
|
|
832
|
-
height: '39px',
|
|
833
|
-
margin: 0,
|
|
834
|
-
padding: '0 12px'
|
|
835
|
-
},
|
|
836
|
-
label: /*#__PURE__*/ jsxs("div", {
|
|
815
|
+
dropdownRender: ()=>/*#__PURE__*/ jsxs("div", {
|
|
816
|
+
className: "player-settings-dropdown",
|
|
817
|
+
children: [
|
|
818
|
+
/*#__PURE__*/ jsxs("div", {
|
|
819
|
+
className: "player-settings-item",
|
|
837
820
|
style: {
|
|
838
821
|
display: 'flex',
|
|
839
822
|
alignItems: 'center',
|
|
840
823
|
justifyContent: 'space-between',
|
|
841
|
-
|
|
842
|
-
|
|
824
|
+
height: '32px',
|
|
825
|
+
padding: '0 8px',
|
|
826
|
+
borderRadius: '4px'
|
|
843
827
|
},
|
|
844
828
|
children: [
|
|
845
829
|
/*#__PURE__*/ jsxs("div", {
|
|
@@ -870,16 +854,65 @@ function Player(props) {
|
|
|
870
854
|
onChange: (checked)=>{
|
|
871
855
|
setAutoZoom(checked);
|
|
872
856
|
triggerReplay();
|
|
873
|
-
},
|
|
874
|
-
onClick: (_, e)=>{
|
|
875
|
-
var _e_stopPropagation;
|
|
876
|
-
return null == e ? void 0 : null == (_e_stopPropagation = e.stopPropagation) ? void 0 : _e_stopPropagation.call(e);
|
|
877
857
|
}
|
|
878
858
|
})
|
|
879
859
|
]
|
|
880
|
-
})
|
|
881
|
-
|
|
882
|
-
|
|
860
|
+
}),
|
|
861
|
+
/*#__PURE__*/ jsx("div", {
|
|
862
|
+
className: "player-settings-divider"
|
|
863
|
+
}),
|
|
864
|
+
/*#__PURE__*/ jsxs("div", {
|
|
865
|
+
style: {
|
|
866
|
+
display: 'flex',
|
|
867
|
+
alignItems: 'center',
|
|
868
|
+
gap: '4px',
|
|
869
|
+
height: '32px',
|
|
870
|
+
padding: '0 8px'
|
|
871
|
+
},
|
|
872
|
+
children: [
|
|
873
|
+
/*#__PURE__*/ jsx(ThunderboltOutlined, {
|
|
874
|
+
style: {
|
|
875
|
+
width: '16px',
|
|
876
|
+
height: '16px'
|
|
877
|
+
}
|
|
878
|
+
}),
|
|
879
|
+
/*#__PURE__*/ jsx("span", {
|
|
880
|
+
style: {
|
|
881
|
+
fontSize: '12px'
|
|
882
|
+
},
|
|
883
|
+
children: "Playback speed"
|
|
884
|
+
})
|
|
885
|
+
]
|
|
886
|
+
}),
|
|
887
|
+
[
|
|
888
|
+
0.5,
|
|
889
|
+
1,
|
|
890
|
+
1.5,
|
|
891
|
+
2
|
|
892
|
+
].map((speed)=>/*#__PURE__*/ jsxs("div", {
|
|
893
|
+
onClick: ()=>{
|
|
894
|
+
setPlaybackSpeed(speed);
|
|
895
|
+
triggerReplay();
|
|
896
|
+
},
|
|
897
|
+
style: {
|
|
898
|
+
height: '32px',
|
|
899
|
+
lineHeight: '32px',
|
|
900
|
+
padding: '0 8px 0 24px',
|
|
901
|
+
fontSize: '12px',
|
|
902
|
+
fontWeight: playbackSpeed === speed ? 600 : 'normal',
|
|
903
|
+
cursor: 'pointer',
|
|
904
|
+
borderRadius: '4px'
|
|
905
|
+
},
|
|
906
|
+
className: "player-speed-option",
|
|
907
|
+
children: [
|
|
908
|
+
speed,
|
|
909
|
+
"x"
|
|
910
|
+
]
|
|
911
|
+
}, speed))
|
|
912
|
+
]
|
|
913
|
+
}),
|
|
914
|
+
menu: {
|
|
915
|
+
items: []
|
|
883
916
|
},
|
|
884
917
|
children: /*#__PURE__*/ jsx("div", {
|
|
885
918
|
className: "status-icon",
|
package/dist/es/store/store.mjs
CHANGED
|
@@ -32,6 +32,7 @@ const BACKGROUND_VISIBLE_KEY = 'midscene-background-visible';
|
|
|
32
32
|
const ELEMENTS_VISIBLE_KEY = 'midscene-elements-visible';
|
|
33
33
|
const MODEL_CALL_DETAILS_KEY = 'midscene-model-call-details';
|
|
34
34
|
const DARK_MODE_KEY = 'midscene-dark-mode';
|
|
35
|
+
const PLAYBACK_SPEED_KEY = 'midscene-playback-speed';
|
|
35
36
|
const parseBooleanParam = (value)=>{
|
|
36
37
|
if (null === value) return;
|
|
37
38
|
const normalized = value.trim().toLowerCase();
|
|
@@ -59,6 +60,8 @@ const useGlobalPreference = store_create((set)=>{
|
|
|
59
60
|
const savedElementsVisible = 'false' !== localStorage.getItem(ELEMENTS_VISIBLE_KEY);
|
|
60
61
|
const savedModelCallDetails = 'true' === localStorage.getItem(MODEL_CALL_DETAILS_KEY);
|
|
61
62
|
const savedDarkMode = 'true' === localStorage.getItem(DARK_MODE_KEY);
|
|
63
|
+
const parsedPlaybackSpeed = Number.parseFloat(localStorage.getItem(PLAYBACK_SPEED_KEY) || '1');
|
|
64
|
+
const savedPlaybackSpeed = Number.isNaN(parsedPlaybackSpeed) ? 1 : parsedPlaybackSpeed;
|
|
62
65
|
const autoZoomFromQuery = getQueryPreference('focusOnCursor');
|
|
63
66
|
const elementsVisibleFromQuery = getQueryPreference('showElementMarkers');
|
|
64
67
|
const darkModeFromQuery = getQueryPreference('darkMode');
|
|
@@ -70,6 +73,12 @@ const useGlobalPreference = store_create((set)=>{
|
|
|
70
73
|
autoZoom: void 0 === autoZoomFromQuery ? savedAutoZoom : autoZoomFromQuery,
|
|
71
74
|
modelCallDetailsEnabled: savedModelCallDetails,
|
|
72
75
|
darkModeEnabled: initialDarkMode,
|
|
76
|
+
playbackSpeed: [
|
|
77
|
+
0.5,
|
|
78
|
+
1,
|
|
79
|
+
1.5,
|
|
80
|
+
2
|
|
81
|
+
].includes(savedPlaybackSpeed) ? savedPlaybackSpeed : 1,
|
|
73
82
|
setBackgroundVisible: (visible)=>{
|
|
74
83
|
set({
|
|
75
84
|
backgroundVisible: visible
|
|
@@ -99,6 +108,12 @@ const useGlobalPreference = store_create((set)=>{
|
|
|
99
108
|
darkModeEnabled: enabled
|
|
100
109
|
});
|
|
101
110
|
localStorage.setItem(DARK_MODE_KEY, enabled.toString());
|
|
111
|
+
},
|
|
112
|
+
setPlaybackSpeed: (speed)=>{
|
|
113
|
+
set({
|
|
114
|
+
playbackSpeed: speed
|
|
115
|
+
});
|
|
116
|
+
localStorage.setItem(PLAYBACK_SPEED_KEY, speed.toString());
|
|
102
117
|
}
|
|
103
118
|
};
|
|
104
119
|
});
|
|
@@ -209,3 +209,33 @@
|
|
|
209
209
|
background: rgba(255, 255, 255, .08);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
.player-settings-dropdown {
|
|
213
|
+
background-color: #fff;
|
|
214
|
+
border: 1px solid rgba(0, 0, 0, .08);
|
|
215
|
+
border-radius: 8px;
|
|
216
|
+
padding: 4px;
|
|
217
|
+
overflow: hidden;
|
|
218
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, .08);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.player-settings-divider {
|
|
222
|
+
background: rgba(0, 0, 0, .06);
|
|
223
|
+
height: 1px;
|
|
224
|
+
margin: 4px 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.player-speed-option:hover, .player-settings-item:hover {
|
|
228
|
+
background: rgba(0, 0, 0, .04);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
[data-theme="dark"] .player-settings-dropdown {
|
|
232
|
+
color: #f8fafd;
|
|
233
|
+
background-color: #1f1f1f;
|
|
234
|
+
border-color: rgba(255, 255, 255, .08);
|
|
235
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, .3);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
[data-theme="dark"] .player-settings-divider, [data-theme="dark"] .player-speed-option:hover, [data-theme="dark"] .player-settings-item:hover {
|
|
239
|
+
background: rgba(255, 255, 255, .08);
|
|
240
|
+
}
|
|
241
|
+
|
|
@@ -243,7 +243,7 @@ function Player(props) {
|
|
|
243
243
|
var _scripts_;
|
|
244
244
|
const [titleText, setTitleText] = (0, external_react_namespaceObject.useState)('');
|
|
245
245
|
const [subTitleText, setSubTitleText] = (0, external_react_namespaceObject.useState)('');
|
|
246
|
-
const { autoZoom, setAutoZoom } = (0, store_js_namespaceObject.useGlobalPreference)();
|
|
246
|
+
const { autoZoom, setAutoZoom, playbackSpeed, setPlaybackSpeed } = (0, store_js_namespaceObject.useGlobalPreference)();
|
|
247
247
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
248
248
|
if ((null == props ? void 0 : props.autoZoom) !== void 0) setAutoZoom(props.autoZoom);
|
|
249
249
|
}, [
|
|
@@ -588,7 +588,9 @@ function Player(props) {
|
|
|
588
588
|
var _scripts_;
|
|
589
589
|
if (!app || !appInitialized.current) throw new Error('app is not initialized');
|
|
590
590
|
if (!scripts) throw new Error("scripts is required");
|
|
591
|
-
const { frame, cancel, timeout, sleep } = frameKit();
|
|
591
|
+
const { frame, cancel, timeout, sleep: baseSleep } = frameKit();
|
|
592
|
+
const scaleByPlaybackSpeed = (duration)=>duration / playbackSpeed;
|
|
593
|
+
const sleep = (ms)=>baseSleep(scaleByPlaybackSpeed(ms));
|
|
592
594
|
cancelFn = cancel;
|
|
593
595
|
cancelAnimationRef.current = cancel;
|
|
594
596
|
const allImages = scripts.filter((item)=>!!item.img).map((item)=>item.img);
|
|
@@ -601,7 +603,7 @@ function Player(props) {
|
|
|
601
603
|
yield updatePointer(index_js_namespaceObject.mousePointer, imageWidth / 2, imageHeight / 2);
|
|
602
604
|
yield repaintImage();
|
|
603
605
|
yield updateCamera(_object_spread({}, basicCameraState));
|
|
604
|
-
const totalDuration = scripts.reduce((acc, item)=>acc + item.duration + (item.camera && item.insightCameraDuration ? item.insightCameraDuration : 0), 0);
|
|
606
|
+
const totalDuration = scaleByPlaybackSpeed(scripts.reduce((acc, item)=>acc + item.duration + (item.camera && item.insightCameraDuration ? item.insightCameraDuration : 0), 0));
|
|
605
607
|
const progressUpdateInterval = 200;
|
|
606
608
|
const startTime = performance.now();
|
|
607
609
|
setAnimationProgress(0);
|
|
@@ -637,13 +639,13 @@ function Player(props) {
|
|
|
637
639
|
const highlightElements = item.highlightElement ? [
|
|
638
640
|
item.highlightElement
|
|
639
641
|
] : [];
|
|
640
|
-
yield insightElementsAnimation([], highlightElements, item.searchArea, item.duration, frame);
|
|
642
|
+
yield insightElementsAnimation([], highlightElements, item.searchArea, scaleByPlaybackSpeed(item.duration), frame);
|
|
641
643
|
if (item.camera) {
|
|
642
644
|
if (!item.insightCameraDuration) throw new Error('insightCameraDuration is required');
|
|
643
|
-
yield cameraAnimation(item.camera, item.insightCameraDuration, frame);
|
|
645
|
+
yield cameraAnimation(item.camera, scaleByPlaybackSpeed(item.insightCameraDuration), frame);
|
|
644
646
|
}
|
|
645
647
|
} else if ('clear-insight' === item.type) {
|
|
646
|
-
yield fadeOutItem(insightMarkContainer, item.duration, frame);
|
|
648
|
+
yield fadeOutItem(insightMarkContainer, scaleByPlaybackSpeed(item.duration), frame);
|
|
647
649
|
insightMarkContainer.removeChildren();
|
|
648
650
|
insightMarkContainer.alpha = 1;
|
|
649
651
|
} else if ('img' === item.type) {
|
|
@@ -651,7 +653,7 @@ function Player(props) {
|
|
|
651
653
|
currentImg.current = item.img;
|
|
652
654
|
yield repaintImage(item.imageWidth, item.imageHeight);
|
|
653
655
|
}
|
|
654
|
-
if (item.camera) yield cameraAnimation(item.camera, item.duration, frame);
|
|
656
|
+
if (item.camera) yield cameraAnimation(item.camera, scaleByPlaybackSpeed(item.duration), frame);
|
|
655
657
|
else yield sleep(item.duration);
|
|
656
658
|
} else if ('pointer' === item.type) {
|
|
657
659
|
if (!item.img) throw new Error('pointer img is required');
|
|
@@ -849,36 +851,18 @@ function Player(props) {
|
|
|
849
851
|
overlayStyle: {
|
|
850
852
|
minWidth: '148px'
|
|
851
853
|
},
|
|
852
|
-
dropdownRender: (
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)',
|
|
858
|
-
overflow: 'hidden'
|
|
859
|
-
},
|
|
860
|
-
children: menu
|
|
861
|
-
}),
|
|
862
|
-
menu: {
|
|
863
|
-
style: {
|
|
864
|
-
borderRadius: '8px',
|
|
865
|
-
padding: 0
|
|
866
|
-
},
|
|
867
|
-
items: [
|
|
868
|
-
{
|
|
869
|
-
key: 'autoZoom',
|
|
870
|
-
style: {
|
|
871
|
-
height: '39px',
|
|
872
|
-
margin: 0,
|
|
873
|
-
padding: '0 12px'
|
|
874
|
-
},
|
|
875
|
-
label: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
854
|
+
dropdownRender: ()=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
855
|
+
className: "player-settings-dropdown",
|
|
856
|
+
children: [
|
|
857
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
858
|
+
className: "player-settings-item",
|
|
876
859
|
style: {
|
|
877
860
|
display: 'flex',
|
|
878
861
|
alignItems: 'center',
|
|
879
862
|
justifyContent: 'space-between',
|
|
880
|
-
|
|
881
|
-
|
|
863
|
+
height: '32px',
|
|
864
|
+
padding: '0 8px',
|
|
865
|
+
borderRadius: '4px'
|
|
882
866
|
},
|
|
883
867
|
children: [
|
|
884
868
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
@@ -909,16 +893,65 @@ function Player(props) {
|
|
|
909
893
|
onChange: (checked)=>{
|
|
910
894
|
setAutoZoom(checked);
|
|
911
895
|
triggerReplay();
|
|
912
|
-
},
|
|
913
|
-
onClick: (_, e)=>{
|
|
914
|
-
var _e_stopPropagation;
|
|
915
|
-
return null == e ? void 0 : null == (_e_stopPropagation = e.stopPropagation) ? void 0 : _e_stopPropagation.call(e);
|
|
916
896
|
}
|
|
917
897
|
})
|
|
918
898
|
]
|
|
919
|
-
})
|
|
920
|
-
|
|
921
|
-
|
|
899
|
+
}),
|
|
900
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
901
|
+
className: "player-settings-divider"
|
|
902
|
+
}),
|
|
903
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
904
|
+
style: {
|
|
905
|
+
display: 'flex',
|
|
906
|
+
alignItems: 'center',
|
|
907
|
+
gap: '4px',
|
|
908
|
+
height: '32px',
|
|
909
|
+
padding: '0 8px'
|
|
910
|
+
},
|
|
911
|
+
children: [
|
|
912
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(icons_namespaceObject.ThunderboltOutlined, {
|
|
913
|
+
style: {
|
|
914
|
+
width: '16px',
|
|
915
|
+
height: '16px'
|
|
916
|
+
}
|
|
917
|
+
}),
|
|
918
|
+
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
|
|
919
|
+
style: {
|
|
920
|
+
fontSize: '12px'
|
|
921
|
+
},
|
|
922
|
+
children: "Playback speed"
|
|
923
|
+
})
|
|
924
|
+
]
|
|
925
|
+
}),
|
|
926
|
+
[
|
|
927
|
+
0.5,
|
|
928
|
+
1,
|
|
929
|
+
1.5,
|
|
930
|
+
2
|
|
931
|
+
].map((speed)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
|
|
932
|
+
onClick: ()=>{
|
|
933
|
+
setPlaybackSpeed(speed);
|
|
934
|
+
triggerReplay();
|
|
935
|
+
},
|
|
936
|
+
style: {
|
|
937
|
+
height: '32px',
|
|
938
|
+
lineHeight: '32px',
|
|
939
|
+
padding: '0 8px 0 24px',
|
|
940
|
+
fontSize: '12px',
|
|
941
|
+
fontWeight: playbackSpeed === speed ? 600 : 'normal',
|
|
942
|
+
cursor: 'pointer',
|
|
943
|
+
borderRadius: '4px'
|
|
944
|
+
},
|
|
945
|
+
className: "player-speed-option",
|
|
946
|
+
children: [
|
|
947
|
+
speed,
|
|
948
|
+
"x"
|
|
949
|
+
]
|
|
950
|
+
}, speed))
|
|
951
|
+
]
|
|
952
|
+
}),
|
|
953
|
+
menu: {
|
|
954
|
+
items: []
|
|
922
955
|
},
|
|
923
956
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
924
957
|
className: "status-icon",
|
package/dist/lib/store/store.js
CHANGED
|
@@ -34,6 +34,7 @@ const BACKGROUND_VISIBLE_KEY = 'midscene-background-visible';
|
|
|
34
34
|
const ELEMENTS_VISIBLE_KEY = 'midscene-elements-visible';
|
|
35
35
|
const MODEL_CALL_DETAILS_KEY = 'midscene-model-call-details';
|
|
36
36
|
const DARK_MODE_KEY = 'midscene-dark-mode';
|
|
37
|
+
const PLAYBACK_SPEED_KEY = 'midscene-playback-speed';
|
|
37
38
|
const parseBooleanParam = (value)=>{
|
|
38
39
|
if (null === value) return;
|
|
39
40
|
const normalized = value.trim().toLowerCase();
|
|
@@ -61,6 +62,8 @@ const useGlobalPreference = create((set)=>{
|
|
|
61
62
|
const savedElementsVisible = 'false' !== localStorage.getItem(ELEMENTS_VISIBLE_KEY);
|
|
62
63
|
const savedModelCallDetails = 'true' === localStorage.getItem(MODEL_CALL_DETAILS_KEY);
|
|
63
64
|
const savedDarkMode = 'true' === localStorage.getItem(DARK_MODE_KEY);
|
|
65
|
+
const parsedPlaybackSpeed = Number.parseFloat(localStorage.getItem(PLAYBACK_SPEED_KEY) || '1');
|
|
66
|
+
const savedPlaybackSpeed = Number.isNaN(parsedPlaybackSpeed) ? 1 : parsedPlaybackSpeed;
|
|
64
67
|
const autoZoomFromQuery = getQueryPreference('focusOnCursor');
|
|
65
68
|
const elementsVisibleFromQuery = getQueryPreference('showElementMarkers');
|
|
66
69
|
const darkModeFromQuery = getQueryPreference('darkMode');
|
|
@@ -72,6 +75,12 @@ const useGlobalPreference = create((set)=>{
|
|
|
72
75
|
autoZoom: void 0 === autoZoomFromQuery ? savedAutoZoom : autoZoomFromQuery,
|
|
73
76
|
modelCallDetailsEnabled: savedModelCallDetails,
|
|
74
77
|
darkModeEnabled: initialDarkMode,
|
|
78
|
+
playbackSpeed: [
|
|
79
|
+
0.5,
|
|
80
|
+
1,
|
|
81
|
+
1.5,
|
|
82
|
+
2
|
|
83
|
+
].includes(savedPlaybackSpeed) ? savedPlaybackSpeed : 1,
|
|
75
84
|
setBackgroundVisible: (visible)=>{
|
|
76
85
|
set({
|
|
77
86
|
backgroundVisible: visible
|
|
@@ -101,6 +110,12 @@ const useGlobalPreference = create((set)=>{
|
|
|
101
110
|
darkModeEnabled: enabled
|
|
102
111
|
});
|
|
103
112
|
localStorage.setItem(DARK_MODE_KEY, enabled.toString());
|
|
113
|
+
},
|
|
114
|
+
setPlaybackSpeed: (speed)=>{
|
|
115
|
+
set({
|
|
116
|
+
playbackSpeed: speed
|
|
117
|
+
});
|
|
118
|
+
localStorage.setItem(PLAYBACK_SPEED_KEY, speed.toString());
|
|
104
119
|
}
|
|
105
120
|
};
|
|
106
121
|
});
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import * as Z from 'zustand';
|
|
2
|
+
export type PlaybackSpeedType = 0.5 | 1 | 1.5 | 2;
|
|
2
3
|
export declare const useGlobalPreference: Z.UseBoundStore<Z.StoreApi<{
|
|
3
4
|
backgroundVisible: boolean;
|
|
4
5
|
elementsVisible: boolean;
|
|
5
6
|
autoZoom: boolean;
|
|
6
7
|
modelCallDetailsEnabled: boolean;
|
|
7
8
|
darkModeEnabled: boolean;
|
|
9
|
+
playbackSpeed: PlaybackSpeedType;
|
|
8
10
|
setBackgroundVisible: (visible: boolean) => void;
|
|
9
11
|
setElementsVisible: (visible: boolean) => void;
|
|
10
12
|
setAutoZoom: (enabled: boolean) => void;
|
|
11
13
|
setModelCallDetailsEnabled: (enabled: boolean) => void;
|
|
12
14
|
setDarkModeEnabled: (enabled: boolean) => void;
|
|
15
|
+
setPlaybackSpeed: (speed: PlaybackSpeedType) => void;
|
|
13
16
|
}>>;
|
|
14
17
|
/**
|
|
15
18
|
* Service Mode
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/visualizer",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8-beta-20260206024209.0",
|
|
4
4
|
"repository": "https://github.com/web-infra-dev/midscene",
|
|
5
5
|
"homepage": "https://midscenejs.com/",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"antd": "^5.21.6",
|
|
61
61
|
"buffer": "6.0.3",
|
|
62
62
|
"dayjs": "^1.11.11",
|
|
63
|
-
"@midscene/core": "1.3.
|
|
64
|
-
"@midscene/
|
|
65
|
-
"@midscene/
|
|
66
|
-
"@midscene/
|
|
63
|
+
"@midscene/core": "1.3.8-beta-20260206024209.0",
|
|
64
|
+
"@midscene/playground": "1.3.8-beta-20260206024209.0",
|
|
65
|
+
"@midscene/web": "1.3.8-beta-20260206024209.0",
|
|
66
|
+
"@midscene/shared": "1.3.8-beta-20260206024209.0"
|
|
67
67
|
},
|
|
68
68
|
"license": "MIT",
|
|
69
69
|
"scripts": {
|