med-viewer-sdk 0.1.25 → 0.1.27
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/med-viewer-sdk.mjs +234 -382
- package/dist/med-viewer-sdk.umd.js +1 -1
- package/package.json +1 -1
package/dist/med-viewer-sdk.mjs
CHANGED
|
@@ -12794,6 +12794,15 @@ const CSS_VAR_MAP = {
|
|
|
12794
12794
|
function cssVar(key) {
|
|
12795
12795
|
return `var(${CSS_VAR_MAP[key]})`;
|
|
12796
12796
|
}
|
|
12797
|
+
const GLOBAL_ANNO_EDITOR_KEYS = [
|
|
12798
|
+
"annoEditorBg",
|
|
12799
|
+
"annoEditorText",
|
|
12800
|
+
"annoEditorBorder",
|
|
12801
|
+
"annoEditorInputBg",
|
|
12802
|
+
"annoEditorBtnBg",
|
|
12803
|
+
"annoEditorBtnHoverBg",
|
|
12804
|
+
"annoEditorBtnColor"
|
|
12805
|
+
];
|
|
12797
12806
|
class ThemeManager {
|
|
12798
12807
|
constructor(container, themeConfig) {
|
|
12799
12808
|
__publicField(this, "container");
|
|
@@ -12830,6 +12839,7 @@ class ThemeManager {
|
|
|
12830
12839
|
}
|
|
12831
12840
|
/**
|
|
12832
12841
|
* 将主题颜色应用为 CSS 变量到容器元素
|
|
12842
|
+
* 同时将 annoEditor* 相关变量提升到 :root,供 .r6o-editor(挂载在 body 下)使用
|
|
12833
12843
|
*/
|
|
12834
12844
|
applyTheme(colors) {
|
|
12835
12845
|
const keys = Object.keys(CSS_VAR_MAP);
|
|
@@ -12837,6 +12847,9 @@ class ThemeManager {
|
|
|
12837
12847
|
const value = colors[key];
|
|
12838
12848
|
if (value !== void 0) {
|
|
12839
12849
|
this.container.style.setProperty(CSS_VAR_MAP[key], value);
|
|
12850
|
+
if (GLOBAL_ANNO_EDITOR_KEYS.includes(key)) {
|
|
12851
|
+
document.documentElement.style.setProperty(CSS_VAR_MAP[key], value);
|
|
12852
|
+
}
|
|
12840
12853
|
}
|
|
12841
12854
|
});
|
|
12842
12855
|
}
|
|
@@ -12874,6 +12887,9 @@ class ThemeManager {
|
|
|
12874
12887
|
const keys = Object.keys(CSS_VAR_MAP);
|
|
12875
12888
|
keys.forEach((key) => {
|
|
12876
12889
|
this.container.style.removeProperty(CSS_VAR_MAP[key]);
|
|
12890
|
+
if (GLOBAL_ANNO_EDITOR_KEYS.includes(key)) {
|
|
12891
|
+
document.documentElement.style.removeProperty(CSS_VAR_MAP[key]);
|
|
12892
|
+
}
|
|
12877
12893
|
});
|
|
12878
12894
|
}
|
|
12879
12895
|
}
|
|
@@ -12882,6 +12898,7 @@ class AnnoAnnotator extends BaseAnnotator {
|
|
|
12882
12898
|
super(engine);
|
|
12883
12899
|
__publicField(this, "anno");
|
|
12884
12900
|
__publicField(this, "listeners", /* @__PURE__ */ new Map());
|
|
12901
|
+
__publicField(this, "injectedStyleEl", null);
|
|
12885
12902
|
this.anno = Annotorious(this.engine.viewer, {
|
|
12886
12903
|
...config
|
|
12887
12904
|
// 可以在此配置样式、偏好等
|
|
@@ -12936,7 +12953,10 @@ class AnnoAnnotator extends BaseAnnotator {
|
|
|
12936
12953
|
this.anno.clearAnnotations();
|
|
12937
12954
|
}
|
|
12938
12955
|
destroy() {
|
|
12956
|
+
var _a2;
|
|
12939
12957
|
this.anno.destroy();
|
|
12958
|
+
(_a2 = this.injectedStyleEl) == null ? void 0 : _a2.remove();
|
|
12959
|
+
this.injectedStyleEl = null;
|
|
12940
12960
|
}
|
|
12941
12961
|
initEvents(config) {
|
|
12942
12962
|
if (config.onCreateAnnotation) {
|
|
@@ -12973,11 +12993,9 @@ class AnnoAnnotator extends BaseAnnotator {
|
|
|
12973
12993
|
}
|
|
12974
12994
|
}
|
|
12975
12995
|
injectStyles() {
|
|
12976
|
-
const styleId = "med-anno-v2-7-17-overrides";
|
|
12977
|
-
if (document.getElementById(styleId))
|
|
12978
|
-
return;
|
|
12979
12996
|
const style = document.createElement("style");
|
|
12980
|
-
style.
|
|
12997
|
+
style.setAttribute("data-med-anno-instance", "true");
|
|
12998
|
+
this.injectedStyleEl = style;
|
|
12981
12999
|
style.innerHTML = `
|
|
12982
13000
|
/* ── 标注手柄 ── */
|
|
12983
13001
|
.a9s-handle .a9s-handle-inner {
|
|
@@ -14154,441 +14172,230 @@ function getCurrentLocale() {
|
|
|
14154
14172
|
return currentLocale;
|
|
14155
14173
|
}
|
|
14156
14174
|
function getWithUnit(value, unitSuffix) {
|
|
14157
|
-
|
|
14175
|
+
const isArea = unitSuffix.includes("²");
|
|
14176
|
+
const baseSuffix = unitSuffix.replace("²", "");
|
|
14177
|
+
if (isArea) {
|
|
14178
|
+
if (value >= 1e12) {
|
|
14179
|
+
return (value / 1e12).toFixed(2) + " " + baseSuffix + "²";
|
|
14180
|
+
}
|
|
14181
|
+
if (value >= 1e6) {
|
|
14182
|
+
return (value / 1e6).toFixed(2) + " m" + baseSuffix + "²";
|
|
14183
|
+
}
|
|
14184
|
+
return value.toFixed(2) + " μ" + baseSuffix + "²";
|
|
14185
|
+
} else {
|
|
14186
|
+
if (value >= 1e6) {
|
|
14187
|
+
return (value / 1e6).toFixed(2) + " " + baseSuffix;
|
|
14188
|
+
}
|
|
14189
|
+
if (value >= 1e3) {
|
|
14190
|
+
return (value / 1e3).toFixed(2) + " m" + baseSuffix;
|
|
14191
|
+
}
|
|
14192
|
+
return value.toFixed(2) + " μ" + baseSuffix;
|
|
14193
|
+
}
|
|
14158
14194
|
}
|
|
14159
|
-
function
|
|
14160
|
-
|
|
14161
|
-
|
|
14195
|
+
function pixelsToMicrons(value, pixelsPerMeter) {
|
|
14196
|
+
return value / pixelsPerMeter * 1e6;
|
|
14197
|
+
}
|
|
14198
|
+
function computePolygonArea(pts) {
|
|
14199
|
+
let sum = 0;
|
|
14200
|
+
for (let i2 = 0; i2 < pts.length - 1; i2++) {
|
|
14201
|
+
const [x1, y1] = pts[i2];
|
|
14202
|
+
const [x2, y2] = pts[i2 + 1];
|
|
14203
|
+
sum += x1 * y2 - x2 * y1;
|
|
14204
|
+
}
|
|
14205
|
+
return Math.abs(sum / 2);
|
|
14162
14206
|
}
|
|
14163
14207
|
const ShapeLabelsFormatter = (pixelsPerMeter, showMeasure) => (annotation) => {
|
|
14164
14208
|
var _a2;
|
|
14165
14209
|
const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
|
|
14166
|
-
let toolName = (_a2 = annotation.target.renderedVia) == null ? void 0 : _a2.name;
|
|
14167
|
-
if (!showMeasure)
|
|
14210
|
+
let toolName = ((_a2 = annotation.target.renderedVia) == null ? void 0 : _a2.name) ?? null;
|
|
14211
|
+
if (!showMeasure)
|
|
14168
14212
|
toolName = null;
|
|
14169
|
-
}
|
|
14170
14213
|
const foreignObject = document.createElementNS(
|
|
14171
14214
|
"http://www.w3.org/2000/svg",
|
|
14172
14215
|
"foreignObject"
|
|
14173
14216
|
);
|
|
14174
14217
|
foreignObject.setAttribute("width", "1px");
|
|
14175
14218
|
foreignObject.setAttribute("height", "1px");
|
|
14176
|
-
const firstTag = bodies.find((b2) => b2.purpose
|
|
14219
|
+
const firstTag = bodies.find((b2) => (b2 == null ? void 0 : b2.purpose) === "commenting");
|
|
14220
|
+
const wrapLabel = (rows, remark) => {
|
|
14221
|
+
const remarkRow = remark ? `<p>${t("annotation.remark")}: ${remark}</p>` : "";
|
|
14222
|
+
return `<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14223
|
+
<div class="a9s-shape-label">
|
|
14224
|
+
${rows.map((r2) => `<p>${r2}</p>`).join("")}
|
|
14225
|
+
${remarkRow}
|
|
14226
|
+
</div>
|
|
14227
|
+
</div>`;
|
|
14228
|
+
};
|
|
14177
14229
|
switch (toolName) {
|
|
14178
|
-
case "line":
|
|
14179
|
-
|
|
14180
|
-
|
|
14181
|
-
|
|
14182
|
-
|
|
14183
|
-
|
|
14184
|
-
|
|
14185
|
-
|
|
14186
|
-
);
|
|
14187
|
-
|
|
14188
|
-
|
|
14189
|
-
|
|
14190
|
-
);
|
|
14191
|
-
let x2 = pixelsToPerMeter(
|
|
14192
|
-
Number(line.getAttribute("x2")),
|
|
14193
|
-
pixelsPerMeter
|
|
14194
|
-
);
|
|
14195
|
-
let y2 = pixelsToPerMeter(
|
|
14196
|
-
Number(line.getAttribute("y2")),
|
|
14197
|
-
pixelsPerMeter
|
|
14230
|
+
case "line": {
|
|
14231
|
+
const div = document.createElement("div");
|
|
14232
|
+
div.innerHTML = annotation.target.selector.value;
|
|
14233
|
+
const el = div.getElementsByTagName("line")[0];
|
|
14234
|
+
const x1 = pixelsToMicrons(Number(el.getAttribute("x1")), pixelsPerMeter);
|
|
14235
|
+
const y1 = pixelsToMicrons(Number(el.getAttribute("y1")), pixelsPerMeter);
|
|
14236
|
+
const x2 = pixelsToMicrons(Number(el.getAttribute("x2")), pixelsPerMeter);
|
|
14237
|
+
const y2 = pixelsToMicrons(Number(el.getAttribute("y2")), pixelsPerMeter);
|
|
14238
|
+
const len = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
|
14239
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14240
|
+
[`${t("annotation.length")}: ${getWithUnit(len, "m")}`],
|
|
14241
|
+
firstTag == null ? void 0 : firstTag.value
|
|
14198
14242
|
);
|
|
14199
|
-
let len = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
|
14200
|
-
if (firstTag) {
|
|
14201
|
-
foreignObject.innerHTML = `
|
|
14202
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14203
|
-
<div class="a9s-shape-label" >
|
|
14204
|
-
<p >
|
|
14205
|
-
${t(`annotation.length`)}: ${getWithUnit(
|
|
14206
|
-
len,
|
|
14207
|
-
"m"
|
|
14208
|
-
)} </p> <p >
|
|
14209
|
-
${t(`annotation.remark`)}: ${firstTag.value}
|
|
14210
|
-
</p>
|
|
14211
|
-
</div>
|
|
14212
|
-
</div>`;
|
|
14213
|
-
} else {
|
|
14214
|
-
foreignObject.innerHTML = `
|
|
14215
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14216
|
-
|
|
14217
|
-
<div class="a9s-shape-label" >
|
|
14218
|
-
<p>
|
|
14219
|
-
${t(`annotation.length`)}: ${getWithUnit(len, "m")}
|
|
14220
|
-
</p>
|
|
14221
|
-
</div>
|
|
14222
|
-
</div>`;
|
|
14223
|
-
}
|
|
14224
14243
|
break;
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
const
|
|
14230
|
-
const
|
|
14231
|
-
const
|
|
14232
|
-
const
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
14237
|
-
|
|
14238
|
-
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
"m"
|
|
14242
|
-
)} </p> <p>
|
|
14243
|
-
|
|
14244
|
-
|
|
14245
|
-
${t(`annotation.height`)}: ${getWithUnit(
|
|
14246
|
-
rectHeight,
|
|
14247
|
-
"m"
|
|
14248
|
-
)} </p> <p>
|
|
14249
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14250
|
-
rectPerimeter,
|
|
14251
|
-
"m"
|
|
14252
|
-
)} </p> <p>
|
|
14253
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14254
|
-
rectArea,
|
|
14255
|
-
"m²"
|
|
14256
|
-
)} </p> <p>
|
|
14257
|
-
${t(`annotation.remark`)}: ${firstTag.value}
|
|
14258
|
-
</p>
|
|
14259
|
-
</div>
|
|
14260
|
-
</div>`;
|
|
14261
|
-
} else {
|
|
14262
|
-
foreignObject.innerHTML = `
|
|
14263
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14264
|
-
<div class="a9s-shape-label">
|
|
14265
|
-
<p >
|
|
14266
|
-
${t(`annotation.width`)}: ${getWithUnit(
|
|
14267
|
-
rectWidth,
|
|
14268
|
-
"m"
|
|
14269
|
-
)} </p> <p>
|
|
14270
|
-
${t(`annotation.height`)}: ${getWithUnit(
|
|
14271
|
-
rectHeight,
|
|
14272
|
-
"m"
|
|
14273
|
-
)} </p> <p>
|
|
14274
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14275
|
-
rectPerimeter,
|
|
14276
|
-
"m"
|
|
14277
|
-
)} </p> <p>
|
|
14278
|
-
${t(`annotation.area`)}: ${getWithUnit(rectArea, "m²")}
|
|
14279
|
-
</p>
|
|
14280
|
-
</div>
|
|
14281
|
-
</div>`;
|
|
14282
|
-
}
|
|
14283
|
-
break;
|
|
14284
|
-
case "circle":
|
|
14285
|
-
let circleDiv = document.createElement("div");
|
|
14286
|
-
console.log(annotation);
|
|
14287
|
-
circleDiv.innerHTML = annotation.target.selector.value;
|
|
14288
|
-
let circle = circleDiv.getElementsByTagName("circle")[0];
|
|
14289
|
-
const circleRadius = pixelsToPerMeter(
|
|
14290
|
-
Number(circle.getAttribute("r")),
|
|
14291
|
-
pixelsPerMeter
|
|
14244
|
+
}
|
|
14245
|
+
case "rect": {
|
|
14246
|
+
const str = annotation.target.selector.value.replace(/xywh=pixel:/g, "");
|
|
14247
|
+
const parts = str.split(",");
|
|
14248
|
+
const rw = pixelsToMicrons(Number(parts[2]), pixelsPerMeter);
|
|
14249
|
+
const rh = pixelsToMicrons(Number(parts[3]), pixelsPerMeter);
|
|
14250
|
+
const rp = 2 * (rw + rh);
|
|
14251
|
+
const ra = rw * rh;
|
|
14252
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14253
|
+
[
|
|
14254
|
+
`${t("annotation.width")}: ${getWithUnit(rw, "m")}`,
|
|
14255
|
+
`${t("annotation.height")}: ${getWithUnit(rh, "m")}`,
|
|
14256
|
+
`${t("annotation.perimeter")}: ${getWithUnit(rp, "m")}`,
|
|
14257
|
+
`${t("annotation.area")}: ${getWithUnit(ra, "m²")}`
|
|
14258
|
+
],
|
|
14259
|
+
firstTag == null ? void 0 : firstTag.value
|
|
14292
14260
|
);
|
|
14293
|
-
const circleCircumference = 2 * Math.PI * circleRadius;
|
|
14294
|
-
const circleArea = Math.PI * Math.pow(circleRadius, 2);
|
|
14295
|
-
if (firstTag) {
|
|
14296
|
-
foreignObject.innerHTML = `
|
|
14297
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14298
|
-
|
|
14299
|
-
<div class="a9s-shape-label">
|
|
14300
|
-
<p>
|
|
14301
|
-
${t(`annotation.radius`)}: ${getWithUnit(
|
|
14302
|
-
circleRadius,
|
|
14303
|
-
"m"
|
|
14304
|
-
)} </p><p>
|
|
14305
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14306
|
-
circleCircumference,
|
|
14307
|
-
"m"
|
|
14308
|
-
)} </p><p>
|
|
14309
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14310
|
-
circleArea,
|
|
14311
|
-
"m²"
|
|
14312
|
-
)} </p><p>
|
|
14313
|
-
${t(`annotation.remark`)}: ${firstTag.value}
|
|
14314
|
-
</p>
|
|
14315
|
-
</div>
|
|
14316
|
-
</div>`;
|
|
14317
|
-
} else {
|
|
14318
|
-
foreignObject.innerHTML = `
|
|
14319
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14320
|
-
<div class="a9s-shape-label">
|
|
14321
|
-
<p>
|
|
14322
|
-
${t(`annotation.radius`)}: ${getWithUnit(
|
|
14323
|
-
circleRadius,
|
|
14324
|
-
"m"
|
|
14325
|
-
)} </p><p>
|
|
14326
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14327
|
-
circleCircumference,
|
|
14328
|
-
"m"
|
|
14329
|
-
)} </p><p>
|
|
14330
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14331
|
-
circleArea,
|
|
14332
|
-
"m²"
|
|
14333
|
-
)}
|
|
14334
|
-
|
|
14335
|
-
</p>
|
|
14336
|
-
</div>
|
|
14337
|
-
</div>`;
|
|
14338
|
-
}
|
|
14339
14261
|
break;
|
|
14340
|
-
|
|
14341
|
-
|
|
14342
|
-
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
|
|
14346
|
-
|
|
14262
|
+
}
|
|
14263
|
+
case "circle": {
|
|
14264
|
+
const div = document.createElement("div");
|
|
14265
|
+
div.innerHTML = annotation.target.selector.value;
|
|
14266
|
+
const el = div.getElementsByTagName("circle")[0];
|
|
14267
|
+
const r2 = pixelsToMicrons(Number(el.getAttribute("r")), pixelsPerMeter);
|
|
14268
|
+
const circum = 2 * Math.PI * r2;
|
|
14269
|
+
const area = Math.PI * r2 * r2;
|
|
14270
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14271
|
+
[
|
|
14272
|
+
`${t("annotation.radius")}: ${getWithUnit(r2, "m")}`,
|
|
14273
|
+
`${t("annotation.perimeter")}: ${getWithUnit(circum, "m")}`,
|
|
14274
|
+
`${t("annotation.area")}: ${getWithUnit(area, "m²")}`
|
|
14275
|
+
],
|
|
14276
|
+
firstTag == null ? void 0 : firstTag.value
|
|
14347
14277
|
);
|
|
14348
|
-
|
|
14349
|
-
|
|
14350
|
-
|
|
14278
|
+
break;
|
|
14279
|
+
}
|
|
14280
|
+
case "ellipse": {
|
|
14281
|
+
const div = document.createElement("div");
|
|
14282
|
+
div.innerHTML = annotation.target.selector.value;
|
|
14283
|
+
const el = div.getElementsByTagName("ellipse")[0];
|
|
14284
|
+
const rx = pixelsToMicrons(Number(el.getAttribute("rx")), pixelsPerMeter);
|
|
14285
|
+
const ry = pixelsToMicrons(Number(el.getAttribute("ry")), pixelsPerMeter);
|
|
14286
|
+
const majorAxis = Math.max(rx, ry);
|
|
14287
|
+
const minorAxis = Math.min(rx, ry);
|
|
14288
|
+
const perim = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
|
|
14289
|
+
const area = Math.PI * rx * ry;
|
|
14290
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14291
|
+
[
|
|
14292
|
+
`${t("annotation.majorAxis")}: ${getWithUnit(majorAxis, "m")}`,
|
|
14293
|
+
`${t("annotation.minorAxis")}: ${getWithUnit(minorAxis, "m")}`,
|
|
14294
|
+
`${t("annotation.perimeter")}: ${getWithUnit(perim, "m")}`,
|
|
14295
|
+
`${t("annotation.area")}: ${getWithUnit(area, "m²")}`
|
|
14296
|
+
],
|
|
14297
|
+
firstTag == null ? void 0 : firstTag.value
|
|
14351
14298
|
);
|
|
14352
|
-
let majorAxis = null;
|
|
14353
|
-
let minorAxis = null;
|
|
14354
|
-
if (rx >= ry) {
|
|
14355
|
-
majorAxis = rx;
|
|
14356
|
-
minorAxis = ry;
|
|
14357
|
-
} else {
|
|
14358
|
-
majorAxis = ry;
|
|
14359
|
-
minorAxis = rx;
|
|
14360
|
-
}
|
|
14361
|
-
const ellipsePerimeter = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
|
|
14362
|
-
const ellipseArea = Math.PI * rx * ry;
|
|
14363
|
-
if (firstTag) {
|
|
14364
|
-
foreignObject.innerHTML = `
|
|
14365
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14366
|
-
<div class="a9s-shape-label">
|
|
14367
|
-
<p>
|
|
14368
|
-
${t(`annotation.majorAxis`)}: ${getWithUnit(
|
|
14369
|
-
majorAxis,
|
|
14370
|
-
"m"
|
|
14371
|
-
)} </p> <p>
|
|
14372
|
-
|
|
14373
|
-
${t(`annotation.minorAxis`)}: ${getWithUnit(
|
|
14374
|
-
minorAxis,
|
|
14375
|
-
"m"
|
|
14376
|
-
)} </p> <p>
|
|
14377
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14378
|
-
ellipsePerimeter,
|
|
14379
|
-
"m"
|
|
14380
|
-
)} </p> <p>
|
|
14381
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14382
|
-
ellipseArea,
|
|
14383
|
-
"m²"
|
|
14384
|
-
)} </p> <p>
|
|
14385
|
-
${t(`annotation.remark`)}: ${firstTag.value}
|
|
14386
|
-
</p>
|
|
14387
|
-
</div>
|
|
14388
|
-
</div>`;
|
|
14389
|
-
} else {
|
|
14390
|
-
foreignObject.innerHTML = `
|
|
14391
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14392
|
-
<div class="a9s-shape-label">
|
|
14393
|
-
<p>
|
|
14394
|
-
${t(`annotation.majorAxis`)}: ${getWithUnit(
|
|
14395
|
-
majorAxis,
|
|
14396
|
-
"m"
|
|
14397
|
-
)} </p><p>
|
|
14398
|
-
|
|
14399
|
-
${t(`annotation.minorAxis`)}: ${getWithUnit(
|
|
14400
|
-
minorAxis,
|
|
14401
|
-
"m"
|
|
14402
|
-
)} </p><p>
|
|
14403
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14404
|
-
ellipsePerimeter,
|
|
14405
|
-
"m"
|
|
14406
|
-
)} </p><p>
|
|
14407
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14408
|
-
ellipseArea,
|
|
14409
|
-
"m²"
|
|
14410
|
-
)}
|
|
14411
|
-
</p>
|
|
14412
|
-
</div>
|
|
14413
|
-
</div>`;
|
|
14414
|
-
}
|
|
14415
14299
|
break;
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
|
|
14420
|
-
|
|
14421
|
-
const
|
|
14422
|
-
const [
|
|
14423
|
-
return
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14300
|
+
}
|
|
14301
|
+
case "polygon": {
|
|
14302
|
+
const div = document.createElement("div");
|
|
14303
|
+
div.innerHTML = annotation.target.selector.value;
|
|
14304
|
+
const el = div.getElementsByTagName("polygon")[0];
|
|
14305
|
+
const pts = (el.getAttribute("points") ?? "").trim().split(/\s+/).map((p2) => {
|
|
14306
|
+
const [x2, y2] = p2.split(",").map(parseFloat);
|
|
14307
|
+
return [
|
|
14308
|
+
pixelsToMicrons(x2, pixelsPerMeter),
|
|
14309
|
+
pixelsToMicrons(y2, pixelsPerMeter)
|
|
14310
|
+
];
|
|
14427
14311
|
});
|
|
14428
|
-
let
|
|
14429
|
-
for (let i2 = 0; i2 <
|
|
14430
|
-
const
|
|
14431
|
-
const
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14438
|
-
|
|
14439
|
-
|
|
14440
|
-
|
|
14441
|
-
|
|
14442
|
-
polygonArea = Math.abs(polygonArea) / 2;
|
|
14443
|
-
if (firstTag) {
|
|
14444
|
-
foreignObject.innerHTML = `
|
|
14445
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14446
|
-
<div class="a9s-shape-label">
|
|
14447
|
-
<p>
|
|
14448
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14449
|
-
polygonPerimeter,
|
|
14450
|
-
"m"
|
|
14451
|
-
)} </p> <p>
|
|
14452
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14453
|
-
polygonArea,
|
|
14454
|
-
"m²"
|
|
14455
|
-
)} </p> <p>
|
|
14456
|
-
${t(`annotation.remark`)}: ${firstTag.value}
|
|
14457
|
-
</p>
|
|
14458
|
-
</div>
|
|
14459
|
-
</div>`;
|
|
14460
|
-
} else {
|
|
14461
|
-
foreignObject.innerHTML = `
|
|
14462
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14463
|
-
|
|
14464
|
-
<div class="a9s-shape-label">
|
|
14465
|
-
<p>
|
|
14466
|
-
${t(`annotation.perimeter`)}: ${getWithUnit(
|
|
14467
|
-
polygonPerimeter,
|
|
14468
|
-
"m"
|
|
14469
|
-
)} </p><p>
|
|
14470
|
-
${t(`annotation.area`)}: ${getWithUnit(
|
|
14471
|
-
polygonArea,
|
|
14472
|
-
"m²"
|
|
14473
|
-
)}
|
|
14474
|
-
</p>
|
|
14475
|
-
</div>
|
|
14476
|
-
</div>`;
|
|
14477
|
-
}
|
|
14312
|
+
let polyPerim = 0;
|
|
14313
|
+
for (let i2 = 0; i2 < pts.length; i2++) {
|
|
14314
|
+
const [ax, ay] = pts[i2];
|
|
14315
|
+
const [bx, by] = pts[(i2 + 1) % pts.length];
|
|
14316
|
+
polyPerim += Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
|
|
14317
|
+
}
|
|
14318
|
+
const polyArea = computePolygonArea(pts);
|
|
14319
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14320
|
+
[
|
|
14321
|
+
`${t("annotation.perimeter")}: ${getWithUnit(polyPerim, "m")}`,
|
|
14322
|
+
`${t("annotation.area")}: ${getWithUnit(polyArea, "m²")}`
|
|
14323
|
+
],
|
|
14324
|
+
firstTag == null ? void 0 : firstTag.value
|
|
14325
|
+
);
|
|
14478
14326
|
break;
|
|
14479
|
-
|
|
14480
|
-
|
|
14481
|
-
|
|
14482
|
-
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
let pathDiv = document.createElement("div");
|
|
14490
|
-
pathDiv.innerHTML = annotation.target.selector.value;
|
|
14491
|
-
let path = pathDiv.getElementsByTagName("path")[0];
|
|
14492
|
-
let d2 = path.getAttribute("d");
|
|
14493
|
-
const properties = new N(d2);
|
|
14494
|
-
let pixelPerimeter = properties.getTotalLength();
|
|
14495
|
-
let steps = 300;
|
|
14496
|
-
let freehandPoints = [];
|
|
14327
|
+
}
|
|
14328
|
+
case "freehand": {
|
|
14329
|
+
const div = document.createElement("div");
|
|
14330
|
+
div.innerHTML = annotation.target.selector.value;
|
|
14331
|
+
const el = div.getElementsByTagName("path")[0];
|
|
14332
|
+
const d2 = el.getAttribute("d") ?? "";
|
|
14333
|
+
const props = new N(d2);
|
|
14334
|
+
const pixelPerim = props.getTotalLength();
|
|
14335
|
+
const steps = 300;
|
|
14336
|
+
const fhPts = [];
|
|
14497
14337
|
for (let i2 = 0; i2 <= steps; i2++) {
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
}
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
</div>
|
|
14513
|
-
</div>`;
|
|
14514
|
-
} else {
|
|
14515
|
-
foreignObject.innerHTML = `
|
|
14516
|
-
<div xmlns="http://www.w3.org/1999/xhtml" class="a9s-shape-label-wrapper">
|
|
14517
|
-
<div class="a9s-shape-label">
|
|
14518
|
-
<p>${t(`annotation.length`)}: ${getWithUnit(realPerimeter, "m")}</p>
|
|
14519
|
-
<p>${t(`annotation.area`)}: ${getWithUnit(realArea, "m²")}</p>
|
|
14520
|
-
</div>
|
|
14521
|
-
</div>`;
|
|
14522
|
-
}
|
|
14338
|
+
const pos = props.getPointAtLength(i2 / steps * pixelPerim);
|
|
14339
|
+
fhPts.push([pos.x, pos.y]);
|
|
14340
|
+
}
|
|
14341
|
+
const areaPixel = computePolygonArea(fhPts);
|
|
14342
|
+
const realPerim = pixelsToMicrons(pixelPerim, pixelsPerMeter);
|
|
14343
|
+
const pixelToMicro = pixelsToMicrons(1, pixelsPerMeter);
|
|
14344
|
+
const realArea = areaPixel * pixelToMicro * pixelToMicro;
|
|
14345
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14346
|
+
[
|
|
14347
|
+
`${t("annotation.length")}: ${getWithUnit(realPerim, "m")}`,
|
|
14348
|
+
`${t("annotation.area")}: ${getWithUnit(realArea, "m²")}`
|
|
14349
|
+
],
|
|
14350
|
+
firstTag == null ? void 0 : firstTag.value
|
|
14351
|
+
);
|
|
14523
14352
|
break;
|
|
14353
|
+
}
|
|
14524
14354
|
default:
|
|
14525
14355
|
if (firstTag) {
|
|
14526
|
-
foreignObject.innerHTML =
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
${t(`annotation.remark`)}: ${firstTag.value}
|
|
14531
|
-
</p>
|
|
14532
|
-
</div>
|
|
14533
|
-
</div>`;
|
|
14356
|
+
foreignObject.innerHTML = wrapLabel(
|
|
14357
|
+
[],
|
|
14358
|
+
firstTag.value
|
|
14359
|
+
);
|
|
14534
14360
|
}
|
|
14535
14361
|
}
|
|
14536
|
-
return {
|
|
14537
|
-
element: foreignObject
|
|
14538
|
-
};
|
|
14362
|
+
return { element: foreignObject };
|
|
14539
14363
|
};
|
|
14540
|
-
|
|
14364
|
+
function injectShapeLabelStyles() {
|
|
14541
14365
|
const styleId = "med-anno-default-shapeLabelsFormatter-overrides";
|
|
14542
14366
|
if (document.getElementById(styleId))
|
|
14543
14367
|
return;
|
|
14544
14368
|
const style = document.createElement("style");
|
|
14545
14369
|
style.id = styleId;
|
|
14546
14370
|
style.innerHTML = `
|
|
14547
|
-
|
|
14548
14371
|
.a9s-annotationlayer .a9s-formatter-el,
|
|
14549
14372
|
.a9s-annotationlayer .a9s-formatter-el foreignObject {
|
|
14550
14373
|
overflow: visible;
|
|
14551
14374
|
pointer-events: none;
|
|
14552
14375
|
}
|
|
14553
|
-
|
|
14554
14376
|
.a9s-annotationlayer .a9s-formatter-el foreignObject .a9s-shape-label-wrapper {
|
|
14555
14377
|
position: relative;
|
|
14556
14378
|
transform: translateY(-100%);
|
|
14557
14379
|
padding-bottom: 4px;
|
|
14558
14380
|
}
|
|
14559
|
-
|
|
14560
|
-
.a9s-annotationlayer
|
|
14561
|
-
.a9s-formatter-el
|
|
14562
|
-
foreignObject
|
|
14563
|
-
.a9s-shape-label-wrapper
|
|
14564
|
-
.a9s-shape-label {
|
|
14381
|
+
.a9s-annotationlayer .a9s-formatter-el foreignObject .a9s-shape-label-wrapper .a9s-shape-label {
|
|
14565
14382
|
display: inline-block;
|
|
14566
14383
|
max-width: 24vw !important;
|
|
14567
14384
|
color: #000;
|
|
14568
|
-
/* min-width: 10vw !important; */
|
|
14569
|
-
|
|
14570
14385
|
word-wrap: break-word;
|
|
14571
14386
|
word-break: keep-all;
|
|
14572
|
-
/* white-space: nowrap; */
|
|
14573
|
-
|
|
14574
14387
|
padding: 3px 5px;
|
|
14575
14388
|
margin-bottom: 2px;
|
|
14576
14389
|
background-color: rgba(255, 255, 255, 0.85);
|
|
14577
14390
|
border-radius: 3px;
|
|
14578
14391
|
font-size: 14px;
|
|
14579
14392
|
}
|
|
14580
|
-
|
|
14581
|
-
.a9s-annotationlayer
|
|
14582
|
-
.a9s-formatter-el
|
|
14583
|
-
foreignObject
|
|
14584
|
-
.a9s-shape-label-wrapper
|
|
14585
|
-
.a9s-shape-label
|
|
14586
|
-
p {
|
|
14393
|
+
.a9s-annotationlayer .a9s-formatter-el foreignObject .a9s-shape-label-wrapper .a9s-shape-label p {
|
|
14587
14394
|
margin: 5px !important;
|
|
14588
14395
|
}
|
|
14589
|
-
|
|
14396
|
+
`;
|
|
14590
14397
|
document.head.appendChild(style);
|
|
14591
|
-
}
|
|
14398
|
+
}
|
|
14592
14399
|
var MagnificationPosition = /* @__PURE__ */ ((MagnificationPosition2) => {
|
|
14593
14400
|
MagnificationPosition2["TOP_LEFT"] = "TOP_LEFT";
|
|
14594
14401
|
MagnificationPosition2["TOP_CENTER"] = "TOP_CENTER";
|
|
@@ -16063,6 +15870,12 @@ var ToolbarPosition = /* @__PURE__ */ ((ToolbarPosition2) => {
|
|
|
16063
15870
|
return ToolbarPosition2;
|
|
16064
15871
|
})(ToolbarPosition || {});
|
|
16065
15872
|
const createAnnoDropdownContent = (engine, hide) => {
|
|
15873
|
+
if (!engine.anno) {
|
|
15874
|
+
const tip = document.createElement("div");
|
|
15875
|
+
tip.className = "med-toolbar-dropdown-inner med-plugin-unavailable";
|
|
15876
|
+
tip.innerHTML = `<p>标注插件未启用,请在 plugins.annotorious 中开启</p>`;
|
|
15877
|
+
return tip;
|
|
15878
|
+
}
|
|
16066
15879
|
const container = document.createElement("div");
|
|
16067
15880
|
container.className = "med-toolbar-dropdown-inner";
|
|
16068
15881
|
let selectedColor = "#ff0000";
|
|
@@ -16127,6 +15940,12 @@ const debounce = (fn, delay) => {
|
|
|
16127
15940
|
};
|
|
16128
15941
|
const createColorAdjustDropdownContent = (engine, hide) => {
|
|
16129
15942
|
var _a2;
|
|
15943
|
+
if (!engine.colorAdjust) {
|
|
15944
|
+
const tip = document.createElement("div");
|
|
15945
|
+
tip.className = "med-toolbar-dropdown-inner med-plugin-unavailable";
|
|
15946
|
+
tip.innerHTML = `<p>颜色调整插件未启用,请在 plugins.colorAdjust 中开启</p>`;
|
|
15947
|
+
return tip;
|
|
15948
|
+
}
|
|
16130
15949
|
const container = document.createElement("div");
|
|
16131
15950
|
container.className = "med-toolbar-dropdown-inner med-color-adjust-dropdown";
|
|
16132
15951
|
if (engine.anno)
|
|
@@ -16468,9 +16287,13 @@ const DEFAULT_BUTTONS = [
|
|
|
16468
16287
|
icon: buttonSelection,
|
|
16469
16288
|
label: t("toolbar.screenshot"),
|
|
16470
16289
|
onClick: (engine, hide) => {
|
|
16471
|
-
|
|
16290
|
+
if (!engine.selection) {
|
|
16291
|
+
console.warn("[MedToolbar] 截图插件未启用,请在 plugins.selection 中开启");
|
|
16292
|
+
hide();
|
|
16293
|
+
return;
|
|
16294
|
+
}
|
|
16472
16295
|
console.log("selection toggleState");
|
|
16473
|
-
|
|
16296
|
+
engine.selection.toggleState();
|
|
16474
16297
|
if (engine.anno) {
|
|
16475
16298
|
engine.anno.setEnabled(false);
|
|
16476
16299
|
}
|
|
@@ -17013,6 +16836,17 @@ class MedToolbar {
|
|
|
17013
16836
|
.med-reset-btn:hover {
|
|
17014
16837
|
background: ${cssVar("dangerBgHigh")};
|
|
17015
16838
|
}
|
|
16839
|
+
.med-plugin-unavailable {
|
|
16840
|
+
min-width: 200px;
|
|
16841
|
+
padding: 16px 12px;
|
|
16842
|
+
text-align: center;
|
|
16843
|
+
}
|
|
16844
|
+
.med-plugin-unavailable p {
|
|
16845
|
+
margin: 0;
|
|
16846
|
+
font-size: 13px;
|
|
16847
|
+
color: ${cssVar("textMuted")};
|
|
16848
|
+
line-height: 1.5;
|
|
16849
|
+
}
|
|
17016
16850
|
`;
|
|
17017
16851
|
document.head.appendChild(style);
|
|
17018
16852
|
}
|
|
@@ -17102,6 +16936,7 @@ class MedViewerEngine {
|
|
|
17102
16936
|
this.options = options;
|
|
17103
16937
|
this.viewer = OpenSeadragon(osdOptions);
|
|
17104
16938
|
this.themeManager = new ThemeManager(this.viewer.element, options.theme);
|
|
16939
|
+
this.injectNavigatorStyles();
|
|
17105
16940
|
this.viewer.addOnceHandler("open", () => {
|
|
17106
16941
|
this.viewer.viewport.goHome();
|
|
17107
16942
|
this.emit("ready");
|
|
@@ -17332,6 +17167,23 @@ class MedViewerEngine {
|
|
|
17332
17167
|
var _a2;
|
|
17333
17168
|
return ((_a2 = this.themeManager) == null ? void 0 : _a2.getThemeName()) ?? null;
|
|
17334
17169
|
}
|
|
17170
|
+
/**
|
|
17171
|
+
* 为 Navigator 小图添加圆角样式
|
|
17172
|
+
*/
|
|
17173
|
+
injectNavigatorStyles() {
|
|
17174
|
+
const STYLE_ID2 = "med-navigator-styles";
|
|
17175
|
+
if (document.getElementById(STYLE_ID2))
|
|
17176
|
+
return;
|
|
17177
|
+
const style = document.createElement("style");
|
|
17178
|
+
style.id = STYLE_ID2;
|
|
17179
|
+
style.textContent = `
|
|
17180
|
+
.navigator {
|
|
17181
|
+
border-radius: 8px;
|
|
17182
|
+
overflow: hidden;
|
|
17183
|
+
}
|
|
17184
|
+
`;
|
|
17185
|
+
document.head.appendChild(style);
|
|
17186
|
+
}
|
|
17335
17187
|
/**
|
|
17336
17188
|
* 销毁引擎与所有插件
|
|
17337
17189
|
*/
|