@midscene/visualizer 1.5.8 → 1.5.9-beta-20260325080051.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.
@@ -0,0 +1,47 @@
1
+ function formatCenterKey(center) {
2
+ return `${center[0]}:${center[1]}`;
3
+ }
4
+ function formatRectKey(rect) {
5
+ return `${rect.left}:${rect.top}:${rect.width}:${rect.height}`;
6
+ }
7
+ function getElementLabel(element) {
8
+ if ('content' in element && element.content) return element.content;
9
+ if ("description" in element && element.description) return element.description;
10
+ }
11
+ function normalizeBlackboardHighlights(elements) {
12
+ if (!(null == elements ? void 0 : elements.length)) return [];
13
+ const deduped = new Map();
14
+ elements.forEach((element, index)=>{
15
+ if (!(null == element ? void 0 : element.rect) || !(null == element ? void 0 : element.center)) return;
16
+ const label = getElementLabel(element);
17
+ const dedupeKey = [
18
+ 'id' in element ? element.id : '',
19
+ label || '',
20
+ formatCenterKey(element.center),
21
+ formatRectKey(element.rect)
22
+ ].join('|');
23
+ if (!deduped.has(dedupeKey)) deduped.set(dedupeKey, {
24
+ key: 'id' in element && element.id || `${dedupeKey || 'highlight'}-${index}`,
25
+ label,
26
+ center: element.center,
27
+ rect: element.rect
28
+ });
29
+ });
30
+ return Array.from(deduped.values());
31
+ }
32
+ function roundRect(rect) {
33
+ return {
34
+ left: Math.round(rect.left),
35
+ top: Math.round(rect.top),
36
+ width: Math.round(rect.width),
37
+ height: Math.round(rect.height)
38
+ };
39
+ }
40
+ function formatBlackboardHighlightSummary(highlight) {
41
+ const center = `[${Math.round(highlight.center[0])}, ${Math.round(highlight.center[1])}]`;
42
+ const rect = roundRect(highlight.rect);
43
+ const rectText = `rect=${JSON.stringify(rect)}`;
44
+ if (highlight.label) return `${highlight.label} center=${center}, ${rectText}`;
45
+ return `center=${center}, ${rectText}`;
46
+ }
47
+ export { formatBlackboardHighlightSummary, normalizeBlackboardHighlights };
@@ -44,6 +44,7 @@
44
44
  .blackboard-rect {
45
45
  box-sizing: content-box;
46
46
  pointer-events: none;
47
+ z-index: 1;
47
48
  position: absolute;
48
49
  }
49
50
 
@@ -85,6 +86,7 @@
85
86
  border: calc(2px * var(--ui-scale, 1)) solid #fd5907;
86
87
  box-shadow: 0 0 calc(6px * var(--ui-scale, 1)) rgba(253, 89, 7, .5);
87
88
  pointer-events: none;
89
+ z-index: 2;
88
90
  background: rgba(253, 89, 7, .4);
89
91
  border-radius: 50%;
90
92
  animation: 1.2s ease-in-out infinite blackboard-pulse;
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useMemo } from "react";
3
+ import react from "react";
4
+ import { normalizeBlackboardHighlights } from "./highlights.mjs";
4
5
  import "./index.css";
5
6
  const Blackboard = (props)=>{
6
7
  var _props_uiContext;
@@ -20,7 +21,10 @@ const Blackboard = (props)=>{
20
21
  const { shotSize, screenshot } = context;
21
22
  const screenWidth = shotSize.width;
22
23
  const screenHeight = shotSize.height;
23
- const screenshotBase64 = useMemo(()=>{
24
+ const highlightOverlays = react.useMemo(()=>normalizeBlackboardHighlights(highlightElements), [
25
+ highlightElements
26
+ ]);
27
+ const screenshotBase64 = react.useMemo(()=>{
24
28
  if (!screenshot) return '';
25
29
  if ('object' == typeof screenshot && 'base64' in screenshot) return screenshot.base64;
26
30
  if ('string' == typeof screenshot) return screenshot;
@@ -28,7 +32,7 @@ const Blackboard = (props)=>{
28
32
  }, [
29
33
  screenshot
30
34
  ]);
31
- const highlightElementRects = highlightElements.map((e)=>e.rect);
35
+ const highlightElementRects = highlightOverlays.map((highlight)=>highlight.rect);
32
36
  let bottomTipA = null;
33
37
  if (1 === highlightElementRects.length) bottomTipA = /*#__PURE__*/ jsx("div", {
34
38
  className: "bottom-tip",
@@ -56,7 +60,8 @@ const Blackboard = (props)=>{
56
60
  /*#__PURE__*/ jsxs("div", {
57
61
  className: "blackboard-main-content",
58
62
  style: {
59
- width: '100%',
63
+ width: 'fit-content',
64
+ maxWidth: '100%',
60
65
  position: 'relative'
61
66
  },
62
67
  children: [
@@ -86,19 +91,15 @@ const Blackboard = (props)=>{
86
91
  children: "Search Area"
87
92
  })
88
93
  }),
89
- highlightElements.map((el, idx)=>/*#__PURE__*/ jsx("div", {
94
+ highlightOverlays.map((el)=>/*#__PURE__*/ jsx("div", {
90
95
  className: "blackboard-rect blackboard-rect-highlight",
91
96
  style: {
92
97
  left: `${el.rect.left / screenWidth * 100}%`,
93
98
  top: `${el.rect.top / screenHeight * 100}%`,
94
99
  width: `${el.rect.width / screenWidth * 100}%`,
95
100
  height: `${el.rect.height / screenHeight * 100}%`
96
- },
97
- children: el.content && /*#__PURE__*/ jsx("span", {
98
- className: "blackboard-rect-label",
99
- children: el.content
100
- })
101
- }, el.id || idx))
101
+ }
102
+ }, `${el.key}-rect`))
102
103
  ]
103
104
  })
104
105
  ]
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ formatBlackboardHighlightSummary: ()=>formatBlackboardHighlightSummary,
28
+ normalizeBlackboardHighlights: ()=>normalizeBlackboardHighlights
29
+ });
30
+ function formatCenterKey(center) {
31
+ return `${center[0]}:${center[1]}`;
32
+ }
33
+ function formatRectKey(rect) {
34
+ return `${rect.left}:${rect.top}:${rect.width}:${rect.height}`;
35
+ }
36
+ function getElementLabel(element) {
37
+ if ('content' in element && element.content) return element.content;
38
+ if ("description" in element && element.description) return element.description;
39
+ }
40
+ function normalizeBlackboardHighlights(elements) {
41
+ if (!(null == elements ? void 0 : elements.length)) return [];
42
+ const deduped = new Map();
43
+ elements.forEach((element, index)=>{
44
+ if (!(null == element ? void 0 : element.rect) || !(null == element ? void 0 : element.center)) return;
45
+ const label = getElementLabel(element);
46
+ const dedupeKey = [
47
+ 'id' in element ? element.id : '',
48
+ label || '',
49
+ formatCenterKey(element.center),
50
+ formatRectKey(element.rect)
51
+ ].join('|');
52
+ if (!deduped.has(dedupeKey)) deduped.set(dedupeKey, {
53
+ key: 'id' in element && element.id || `${dedupeKey || 'highlight'}-${index}`,
54
+ label,
55
+ center: element.center,
56
+ rect: element.rect
57
+ });
58
+ });
59
+ return Array.from(deduped.values());
60
+ }
61
+ function roundRect(rect) {
62
+ return {
63
+ left: Math.round(rect.left),
64
+ top: Math.round(rect.top),
65
+ width: Math.round(rect.width),
66
+ height: Math.round(rect.height)
67
+ };
68
+ }
69
+ function formatBlackboardHighlightSummary(highlight) {
70
+ const center = `[${Math.round(highlight.center[0])}, ${Math.round(highlight.center[1])}]`;
71
+ const rect = roundRect(highlight.rect);
72
+ const rectText = `rect=${JSON.stringify(rect)}`;
73
+ if (highlight.label) return `${highlight.label} center=${center}, ${rectText}`;
74
+ return `center=${center}, ${rectText}`;
75
+ }
76
+ exports.formatBlackboardHighlightSummary = __webpack_exports__.formatBlackboardHighlightSummary;
77
+ exports.normalizeBlackboardHighlights = __webpack_exports__.normalizeBlackboardHighlights;
78
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
79
+ "formatBlackboardHighlightSummary",
80
+ "normalizeBlackboardHighlights"
81
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
82
+ Object.defineProperty(exports, '__esModule', {
83
+ value: true
84
+ });
@@ -44,6 +44,7 @@
44
44
  .blackboard-rect {
45
45
  box-sizing: content-box;
46
46
  pointer-events: none;
47
+ z-index: 1;
47
48
  position: absolute;
48
49
  }
49
50
 
@@ -85,6 +86,7 @@
85
86
  border: calc(2px * var(--ui-scale, 1)) solid #fd5907;
86
87
  box-shadow: 0 0 calc(6px * var(--ui-scale, 1)) rgba(253, 89, 7, .5);
87
88
  pointer-events: none;
89
+ z-index: 2;
88
90
  background: rgba(253, 89, 7, .4);
89
91
  border-radius: 50%;
90
92
  animation: 1.2s ease-in-out infinite blackboard-pulse;
@@ -1,6 +1,15 @@
1
1
  "use strict";
2
2
  "use client";
3
3
  var __webpack_require__ = {};
4
+ (()=>{
5
+ __webpack_require__.n = (module)=>{
6
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
7
+ __webpack_require__.d(getter, {
8
+ a: getter
9
+ });
10
+ return getter;
11
+ };
12
+ })();
4
13
  (()=>{
5
14
  __webpack_require__.d = (exports1, definition)=>{
6
15
  for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
@@ -30,6 +39,8 @@ __webpack_require__.d(__webpack_exports__, {
30
39
  });
31
40
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
32
41
  const external_react_namespaceObject = require("react");
42
+ var external_react_default = /*#__PURE__*/ __webpack_require__.n(external_react_namespaceObject);
43
+ const external_highlights_js_namespaceObject = require("./highlights.js");
33
44
  require("./index.css");
34
45
  const Blackboard = (props)=>{
35
46
  var _props_uiContext;
@@ -49,7 +60,10 @@ const Blackboard = (props)=>{
49
60
  const { shotSize, screenshot } = context;
50
61
  const screenWidth = shotSize.width;
51
62
  const screenHeight = shotSize.height;
52
- const screenshotBase64 = (0, external_react_namespaceObject.useMemo)(()=>{
63
+ const highlightOverlays = external_react_default().useMemo(()=>(0, external_highlights_js_namespaceObject.normalizeBlackboardHighlights)(highlightElements), [
64
+ highlightElements
65
+ ]);
66
+ const screenshotBase64 = external_react_default().useMemo(()=>{
53
67
  if (!screenshot) return '';
54
68
  if ('object' == typeof screenshot && 'base64' in screenshot) return screenshot.base64;
55
69
  if ('string' == typeof screenshot) return screenshot;
@@ -57,7 +71,7 @@ const Blackboard = (props)=>{
57
71
  }, [
58
72
  screenshot
59
73
  ]);
60
- const highlightElementRects = highlightElements.map((e)=>e.rect);
74
+ const highlightElementRects = highlightOverlays.map((highlight)=>highlight.rect);
61
75
  let bottomTipA = null;
62
76
  if (1 === highlightElementRects.length) bottomTipA = /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
63
77
  className: "bottom-tip",
@@ -85,7 +99,8 @@ const Blackboard = (props)=>{
85
99
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
86
100
  className: "blackboard-main-content",
87
101
  style: {
88
- width: '100%',
102
+ width: 'fit-content',
103
+ maxWidth: '100%',
89
104
  position: 'relative'
90
105
  },
91
106
  children: [
@@ -115,19 +130,15 @@ const Blackboard = (props)=>{
115
130
  children: "Search Area"
116
131
  })
117
132
  }),
118
- highlightElements.map((el, idx)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
133
+ highlightOverlays.map((el)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
119
134
  className: "blackboard-rect blackboard-rect-highlight",
120
135
  style: {
121
136
  left: `${el.rect.left / screenWidth * 100}%`,
122
137
  top: `${el.rect.top / screenHeight * 100}%`,
123
138
  width: `${el.rect.width / screenWidth * 100}%`,
124
139
  height: `${el.rect.height / screenHeight * 100}%`
125
- },
126
- children: el.content && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
127
- className: "blackboard-rect-label",
128
- children: el.content
129
- })
130
- }, el.id || idx))
140
+ }
141
+ }, `${el.key}-rect`))
131
142
  ]
132
143
  })
133
144
  ]
@@ -0,0 +1,11 @@
1
+ import type { BaseElement, LocateResultElement, Rect } from '@midscene/core';
2
+ type HighlightLikeElement = (Pick<BaseElement, 'center' | 'rect'> & Partial<Pick<BaseElement, 'content' | 'id'>>) | LocateResultElement;
3
+ export interface BlackboardHighlightOverlay {
4
+ key: string;
5
+ label?: string;
6
+ center: [number, number];
7
+ rect: Rect;
8
+ }
9
+ export declare function normalizeBlackboardHighlights(elements: HighlightLikeElement[] | undefined): BlackboardHighlightOverlay[];
10
+ export declare function formatBlackboardHighlightSummary(highlight: BlackboardHighlightOverlay): string;
11
+ export {};
@@ -1,9 +1,10 @@
1
1
  import type { BaseElement, Rect, UIContext } from '@midscene/core';
2
+ import React from 'react';
2
3
  import './index.less';
3
4
  export declare const Blackboard: (props: {
4
5
  uiContext: UIContext | undefined | null;
5
6
  highlightElements?: BaseElement[];
6
7
  highlightRect?: Rect;
7
8
  hideController?: boolean;
8
- }) => import("react").JSX.Element;
9
+ }) => React.JSX.Element;
9
10
  export default Blackboard;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/visualizer",
3
- "version": "1.5.8",
3
+ "version": "1.5.9-beta-20260325080051.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",
@@ -58,10 +58,10 @@
58
58
  "antd": "^5.21.6",
59
59
  "buffer": "6.0.3",
60
60
  "dayjs": "^1.11.11",
61
- "@midscene/core": "1.5.8",
62
- "@midscene/shared": "1.5.8",
63
- "@midscene/web": "1.5.8",
64
- "@midscene/playground": "1.5.8"
61
+ "@midscene/core": "1.5.9-beta-20260325080051.0",
62
+ "@midscene/shared": "1.5.9-beta-20260325080051.0",
63
+ "@midscene/playground": "1.5.9-beta-20260325080051.0",
64
+ "@midscene/web": "1.5.9-beta-20260325080051.0"
65
65
  },
66
66
  "license": "MIT",
67
67
  "scripts": {