med-viewer-sdk 0.1.23 → 0.1.25

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.
@@ -7,7 +7,7 @@ var __publicField = (obj, key, value) => {
7
7
  var _a, _b, _c, _d, _e;
8
8
  import OpenSeadragon from "openseadragon";
9
9
  import { default as default2 } from "openseadragon";
10
- import { defineComponent, shallowRef, onMounted, onBeforeUnmount, h as h$1 } from "vue";
10
+ import { defineComponent, shallowRef, onMounted, watch, onBeforeUnmount, h as h$1 } from "vue";
11
11
  function getDefaultExportFromCjs(x2) {
12
12
  return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
13
13
  }
@@ -12545,6 +12545,338 @@ class BaseAnnotator {
12545
12545
  this.engine = engine;
12546
12546
  }
12547
12547
  }
12548
+ const DEFAULT_COLORS = {
12549
+ // 面板
12550
+ panelBackground: "rgba(24, 28, 36, 0.85)",
12551
+ panelBackgroundSolid: "#181c24",
12552
+ panelBorder: "rgba(255, 255, 255, 0.1)",
12553
+ panelShadow: "0 8px 32px rgba(0, 0, 0, 0.3)",
12554
+ // 文字
12555
+ textPrimary: "#f2f5f8",
12556
+ textSecondary: "rgba(255, 255, 255, 0.7)",
12557
+ textMuted: "rgba(255, 255, 255, 0.4)",
12558
+ // 强调色
12559
+ accentColor: "#31d0aa",
12560
+ accentHover: "#25a084",
12561
+ accentBgLow: "rgba(49, 208, 170, 0.15)",
12562
+ accentBgHigh: "rgba(49, 208, 170, 0.2)",
12563
+ // 按钮
12564
+ btnBackground: "rgba(255, 255, 255, 0.08)",
12565
+ btnHoverBackground: "rgba(49, 208, 170, 0.2)",
12566
+ // 危险
12567
+ dangerColor: "#ff6b6b",
12568
+ dangerBgLow: "rgba(200, 50, 50, 0.1)",
12569
+ dangerBgHigh: "rgba(200, 50, 50, 0.3)",
12570
+ // 选区
12571
+ selectionColor: "#4CAF50",
12572
+ selectionHandleBorder: "#4CAF50",
12573
+ // 标注手柄
12574
+ annoHandleInnerFill: "#FF9800",
12575
+ annoHandleInnerStroke: "#FFEB3B",
12576
+ annoHandleOuterFill: "#fff",
12577
+ annoHandleOuterStroke: "#000",
12578
+ // 标注图形
12579
+ annoInnerStroke: "#31d0aa",
12580
+ annoOuterStroke: "rgba(0, 0, 0, 0.35)",
12581
+ annoInnerHoverStroke: "#31d0aa",
12582
+ annoHandleHoverFill: "#FFEB3B",
12583
+ // 标注编辑器
12584
+ annoEditorBg: "#181c24",
12585
+ annoEditorText: "#f2f5f8",
12586
+ annoEditorBorder: "rgba(255,255,255,0.1)",
12587
+ annoEditorInputBg: "rgba(255,255,255,0.06)",
12588
+ annoEditorBtnBg: "#31d0aa",
12589
+ annoEditorBtnHoverBg: "#25a084",
12590
+ annoEditorBtnColor: "#fff",
12591
+ // 滑块
12592
+ sliderTrackBg: "rgba(255, 255, 255, 0.2)",
12593
+ sliderThumbColor: "#31d0aa",
12594
+ sliderThumbHover: "#25a084",
12595
+ // 复选框
12596
+ checkboxBorder: "rgba(255, 255, 255, 0.4)",
12597
+ checkboxCheckedBg: "#31d0aa",
12598
+ // 工具网格
12599
+ toolItemBg: "rgba(255, 255, 255, 0.05)",
12600
+ toolItemBorder: "rgba(255, 255, 255, 0.05)",
12601
+ toolItemHoverBg: "rgba(49, 208, 170, 0.2)",
12602
+ toolItemHoverBorder: "rgba(49, 208, 170, 0.4)",
12603
+ // 颜色选择
12604
+ colorItemActiveBorder: "#fff",
12605
+ colorItemActiveShadow: "0 0 10px rgba(255, 255, 255, 0.3)",
12606
+ // Tooltip
12607
+ tooltipBg: "rgba(0, 0, 0, 0.75)",
12608
+ tooltipColor: "#fff",
12609
+ // 图标 filter
12610
+ iconFilter: "none"
12611
+ };
12612
+ const LIGHT_COLORS = {
12613
+ // 面板
12614
+ panelBackground: "rgba(255, 255, 255, 0.92)",
12615
+ panelBackgroundSolid: "#ffffff",
12616
+ panelBorder: "rgba(0, 0, 0, 0.08)",
12617
+ panelShadow: "0 4px 24px rgba(0, 0, 0, 0.1)",
12618
+ // 文字
12619
+ textPrimary: "#1a1a2e",
12620
+ textSecondary: "rgba(0, 0, 0, 0.55)",
12621
+ textMuted: "rgba(0, 0, 0, 0.35)",
12622
+ // 强调色
12623
+ accentColor: "#1890ff",
12624
+ accentHover: "#096dd9",
12625
+ accentBgLow: "rgba(24, 144, 255, 0.08)",
12626
+ accentBgHigh: "rgba(24, 144, 255, 0.15)",
12627
+ // 按钮
12628
+ btnBackground: "rgba(0, 0, 0, 0.04)",
12629
+ btnHoverBackground: "rgba(24, 144, 255, 0.1)",
12630
+ // 危险
12631
+ dangerColor: "#ff4d4f",
12632
+ dangerBgLow: "rgba(255, 77, 79, 0.06)",
12633
+ dangerBgHigh: "rgba(255, 77, 79, 0.15)",
12634
+ // 选区
12635
+ selectionColor: "#1890ff",
12636
+ selectionHandleBorder: "#1890ff",
12637
+ // 标注手柄
12638
+ annoHandleInnerFill: "#FF9800",
12639
+ annoHandleInnerStroke: "#E65100",
12640
+ annoHandleOuterFill: "#fff",
12641
+ annoHandleOuterStroke: "#333",
12642
+ // 标注图形
12643
+ annoInnerStroke: "#1890ff",
12644
+ annoOuterStroke: "rgba(0, 0, 0, 0.2)",
12645
+ annoInnerHoverStroke: "#096dd9",
12646
+ annoHandleHoverFill: "#E65100",
12647
+ // 标注编辑器
12648
+ annoEditorBg: "#ffffff",
12649
+ annoEditorText: "#1a1a2e",
12650
+ annoEditorBorder: "rgba(0, 0, 0, 0.08)",
12651
+ annoEditorInputBg: "#f5f5f5",
12652
+ annoEditorBtnBg: "#1890ff",
12653
+ annoEditorBtnHoverBg: "#096dd9",
12654
+ annoEditorBtnColor: "#fff",
12655
+ // 滑块
12656
+ sliderTrackBg: "rgba(0, 0, 0, 0.1)",
12657
+ sliderThumbColor: "#1890ff",
12658
+ sliderThumbHover: "#096dd9",
12659
+ // 复选框
12660
+ checkboxBorder: "rgba(0, 0, 0, 0.25)",
12661
+ checkboxCheckedBg: "#1890ff",
12662
+ // 工具网格
12663
+ toolItemBg: "rgba(0, 0, 0, 0.03)",
12664
+ toolItemBorder: "rgba(0, 0, 0, 0.06)",
12665
+ toolItemHoverBg: "rgba(24, 144, 255, 0.08)",
12666
+ toolItemHoverBorder: "rgba(24, 144, 255, 0.3)",
12667
+ // 颜色选择
12668
+ colorItemActiveBorder: "#1890ff",
12669
+ colorItemActiveShadow: "0 0 8px rgba(24, 144, 255, 0.3)",
12670
+ // Tooltip
12671
+ tooltipBg: "rgba(0, 0, 0, 0.75)",
12672
+ tooltipColor: "#fff",
12673
+ // 图标 filter
12674
+ iconFilter: "invert(1)"
12675
+ };
12676
+ const DARK_COLORS = {
12677
+ // 面板
12678
+ panelBackground: "rgba(10, 10, 14, 0.92)",
12679
+ panelBackgroundSolid: "#0a0a0e",
12680
+ panelBorder: "rgba(255, 255, 255, 0.06)",
12681
+ panelShadow: "0 8px 32px rgba(0, 0, 0, 0.6)",
12682
+ // 文字
12683
+ textPrimary: "#e8eaed",
12684
+ textSecondary: "rgba(255, 255, 255, 0.6)",
12685
+ textMuted: "rgba(255, 255, 255, 0.3)",
12686
+ // 强调色
12687
+ accentColor: "#bb86fc",
12688
+ accentHover: "#9b59b6",
12689
+ accentBgLow: "rgba(187, 134, 252, 0.1)",
12690
+ accentBgHigh: "rgba(187, 134, 252, 0.2)",
12691
+ // 按钮
12692
+ btnBackground: "rgba(255, 255, 255, 0.06)",
12693
+ btnHoverBackground: "rgba(187, 134, 252, 0.15)",
12694
+ // 危险
12695
+ dangerColor: "#cf6679",
12696
+ dangerBgLow: "rgba(207, 102, 121, 0.1)",
12697
+ dangerBgHigh: "rgba(207, 102, 121, 0.25)",
12698
+ // 选区
12699
+ selectionColor: "#bb86fc",
12700
+ selectionHandleBorder: "#bb86fc",
12701
+ // 标注手柄
12702
+ annoHandleInnerFill: "#FF9800",
12703
+ annoHandleInnerStroke: "#FFEB3B",
12704
+ annoHandleOuterFill: "#222",
12705
+ annoHandleOuterStroke: "#888",
12706
+ // 标注图形
12707
+ annoInnerStroke: "#bb86fc",
12708
+ annoOuterStroke: "rgba(0, 0, 0, 0.5)",
12709
+ annoInnerHoverStroke: "#9b59b6",
12710
+ annoHandleHoverFill: "#FFEB3B",
12711
+ // 标注编辑器
12712
+ annoEditorBg: "#0a0a0e",
12713
+ annoEditorText: "#e8eaed",
12714
+ annoEditorBorder: "rgba(255,255,255,0.06)",
12715
+ annoEditorInputBg: "rgba(255,255,255,0.06)",
12716
+ annoEditorBtnBg: "#bb86fc",
12717
+ annoEditorBtnHoverBg: "#9b59b6",
12718
+ annoEditorBtnColor: "#fff",
12719
+ // 滑块
12720
+ sliderTrackBg: "rgba(255, 255, 255, 0.15)",
12721
+ sliderThumbColor: "#bb86fc",
12722
+ sliderThumbHover: "#9b59b6",
12723
+ // 复选框
12724
+ checkboxBorder: "rgba(255, 255, 255, 0.3)",
12725
+ checkboxCheckedBg: "#bb86fc",
12726
+ // 工具网格
12727
+ toolItemBg: "rgba(255, 255, 255, 0.04)",
12728
+ toolItemBorder: "rgba(255, 255, 255, 0.04)",
12729
+ toolItemHoverBg: "rgba(187, 134, 252, 0.15)",
12730
+ toolItemHoverBorder: "rgba(187, 134, 252, 0.3)",
12731
+ // 颜色选择
12732
+ colorItemActiveBorder: "#bb86fc",
12733
+ colorItemActiveShadow: "0 0 10px rgba(187, 134, 252, 0.4)",
12734
+ // Tooltip
12735
+ tooltipBg: "rgba(0, 0, 0, 0.85)",
12736
+ tooltipColor: "#e8eaed",
12737
+ // 图标 filter
12738
+ iconFilter: "none"
12739
+ };
12740
+ const PRESET_THEMES = {
12741
+ default: { name: "default", colors: DEFAULT_COLORS },
12742
+ light: { name: "light", colors: LIGHT_COLORS },
12743
+ dark: { name: "dark", colors: DARK_COLORS }
12744
+ };
12745
+ const CSS_VAR_MAP = {
12746
+ panelBackground: "--med-panel-bg",
12747
+ panelBackgroundSolid: "--med-panel-bg-solid",
12748
+ panelBorder: "--med-panel-border",
12749
+ panelShadow: "--med-panel-shadow",
12750
+ textPrimary: "--med-text-primary",
12751
+ textSecondary: "--med-text-secondary",
12752
+ textMuted: "--med-text-muted",
12753
+ accentColor: "--med-accent",
12754
+ accentHover: "--med-accent-hover",
12755
+ accentBgLow: "--med-accent-bg-low",
12756
+ accentBgHigh: "--med-accent-bg-high",
12757
+ btnBackground: "--med-btn-bg",
12758
+ btnHoverBackground: "--med-btn-hover-bg",
12759
+ dangerColor: "--med-danger",
12760
+ dangerBgLow: "--med-danger-bg-low",
12761
+ dangerBgHigh: "--med-danger-bg-high",
12762
+ selectionColor: "--med-selection",
12763
+ selectionHandleBorder: "--med-selection-handle-border",
12764
+ annoHandleInnerFill: "--med-anno-handle-inner-fill",
12765
+ annoHandleInnerStroke: "--med-anno-handle-inner-stroke",
12766
+ annoHandleOuterFill: "--med-anno-handle-outer-fill",
12767
+ annoHandleOuterStroke: "--med-anno-handle-outer-stroke",
12768
+ annoInnerStroke: "--med-anno-inner-stroke",
12769
+ annoOuterStroke: "--med-anno-outer-stroke",
12770
+ annoInnerHoverStroke: "--med-anno-inner-hover-stroke",
12771
+ annoHandleHoverFill: "--med-anno-handle-hover-fill",
12772
+ annoEditorBg: "--med-anno-editor-bg",
12773
+ annoEditorText: "--med-anno-editor-text",
12774
+ annoEditorBorder: "--med-anno-editor-border",
12775
+ annoEditorInputBg: "--med-anno-editor-input-bg",
12776
+ annoEditorBtnBg: "--med-anno-editor-btn-bg",
12777
+ annoEditorBtnHoverBg: "--med-anno-editor-btn-hover-bg",
12778
+ annoEditorBtnColor: "--med-anno-editor-btn-color",
12779
+ sliderTrackBg: "--med-slider-track-bg",
12780
+ sliderThumbColor: "--med-slider-thumb",
12781
+ sliderThumbHover: "--med-slider-thumb-hover",
12782
+ checkboxBorder: "--med-checkbox-border",
12783
+ checkboxCheckedBg: "--med-checkbox-checked-bg",
12784
+ toolItemBg: "--med-tool-item-bg",
12785
+ toolItemBorder: "--med-tool-item-border",
12786
+ toolItemHoverBg: "--med-tool-item-hover-bg",
12787
+ toolItemHoverBorder: "--med-tool-item-hover-border",
12788
+ colorItemActiveBorder: "--med-color-item-active-border",
12789
+ colorItemActiveShadow: "--med-color-item-active-shadow",
12790
+ tooltipBg: "--med-tooltip-bg",
12791
+ tooltipColor: "--med-tooltip-color",
12792
+ iconFilter: "--med-icon-filter"
12793
+ };
12794
+ function cssVar(key) {
12795
+ return `var(${CSS_VAR_MAP[key]})`;
12796
+ }
12797
+ class ThemeManager {
12798
+ constructor(container, themeConfig) {
12799
+ __publicField(this, "container");
12800
+ __publicField(this, "currentTheme");
12801
+ __publicField(this, "currentName");
12802
+ this.container = container;
12803
+ const resolved = this.resolveConfig(themeConfig);
12804
+ this.currentTheme = resolved;
12805
+ this.currentName = resolved.name;
12806
+ this.applyTheme(resolved.colors);
12807
+ }
12808
+ /**
12809
+ * 解析主题配置
12810
+ */
12811
+ resolveConfig(config) {
12812
+ if (!config) {
12813
+ return PRESET_THEMES.default;
12814
+ }
12815
+ if (typeof config === "string") {
12816
+ const preset = PRESET_THEMES[config];
12817
+ if (!preset) {
12818
+ console.warn(`[ThemeManager] Unknown preset theme "${config}", falling back to default`);
12819
+ return PRESET_THEMES.default;
12820
+ }
12821
+ return preset;
12822
+ }
12823
+ if ("name" in config && "colors" in config) {
12824
+ return config;
12825
+ }
12826
+ return {
12827
+ name: "custom",
12828
+ colors: { ...DEFAULT_COLORS, ...config }
12829
+ };
12830
+ }
12831
+ /**
12832
+ * 将主题颜色应用为 CSS 变量到容器元素
12833
+ */
12834
+ applyTheme(colors) {
12835
+ const keys = Object.keys(CSS_VAR_MAP);
12836
+ keys.forEach((key) => {
12837
+ const value = colors[key];
12838
+ if (value !== void 0) {
12839
+ this.container.style.setProperty(CSS_VAR_MAP[key], value);
12840
+ }
12841
+ });
12842
+ }
12843
+ /**
12844
+ * 切换主题
12845
+ */
12846
+ setTheme(config) {
12847
+ const resolved = this.resolveConfig(config);
12848
+ this.currentTheme = resolved;
12849
+ this.currentName = resolved.name;
12850
+ this.applyTheme(resolved.colors);
12851
+ }
12852
+ /**
12853
+ * 获取当前主题名称
12854
+ */
12855
+ getThemeName() {
12856
+ return this.currentName;
12857
+ }
12858
+ /**
12859
+ * 获取当前主题颜色
12860
+ */
12861
+ getColors() {
12862
+ return { ...this.currentTheme.colors };
12863
+ }
12864
+ /**
12865
+ * 获取指定颜色值(当前主题)
12866
+ */
12867
+ getColor(key) {
12868
+ return this.currentTheme.colors[key];
12869
+ }
12870
+ /**
12871
+ * 销毁(清除 CSS 变量)
12872
+ */
12873
+ destroy() {
12874
+ const keys = Object.keys(CSS_VAR_MAP);
12875
+ keys.forEach((key) => {
12876
+ this.container.style.removeProperty(CSS_VAR_MAP[key]);
12877
+ });
12878
+ }
12879
+ }
12548
12880
  class AnnoAnnotator extends BaseAnnotator {
12549
12881
  constructor(engine, config = {}) {
12550
12882
  super(engine);
@@ -12647,13 +12979,115 @@ class AnnoAnnotator extends BaseAnnotator {
12647
12979
  const style = document.createElement("style");
12648
12980
  style.id = styleId;
12649
12981
  style.innerHTML = `
12982
+ /* ── 标注手柄 ── */
12650
12983
  .a9s-handle .a9s-handle-inner {
12651
- stroke: #FFEB3B;
12652
- fill: #FF9800;
12984
+ stroke: ${cssVar("annoHandleInnerStroke")};
12985
+ fill: ${cssVar("annoHandleInnerFill")};
12653
12986
  }
12654
12987
  .a9s-handle .a9s-handle-outer {
12655
- stroke: #000;
12656
- fill: #fff;
12988
+ stroke: ${cssVar("annoHandleOuterStroke")};
12989
+ fill: ${cssVar("annoHandleOuterFill")};
12990
+ }
12991
+ .a9s-handle:hover .a9s-handle-inner {
12992
+ fill: ${cssVar("annoHandleHoverFill")};
12993
+ }
12994
+
12995
+ /* ── 标注图形边框 ── */
12996
+ .a9s-annotation .a9s-inner,
12997
+ .a9s-selection .a9s-inner {
12998
+ stroke: ${cssVar("annoInnerStroke")};
12999
+ }
13000
+ .a9s-annotation .a9s-inner:hover,
13001
+ .a9s-selection .a9s-inner:hover {
13002
+ stroke: ${cssVar("annoInnerHoverStroke")};
13003
+ }
13004
+ .a9s-annotation .a9s-outer,
13005
+ .a9s-selection .a9s-outer {
13006
+ stroke: ${cssVar("annoOuterStroke")};
13007
+ }
13008
+ .a9s-annotation.selected .a9s-inner,
13009
+ .a9s-annotation.editable .a9s-inner {
13010
+ stroke: ${cssVar("annoInnerHoverStroke")};
13011
+ }
13012
+
13013
+ /* ── improved-polygon ── */
13014
+ .a9s-selection.improved-polygon .a9s-inner,
13015
+ .a9s-annotation.improved-polygon.editable .a9s-inner {
13016
+ stroke: ${cssVar("annoInnerStroke")};
13017
+ }
13018
+ .a9s-selection.improved-polygon .a9s-outer,
13019
+ .a9s-annotation.improved-polygon.editable .a9s-outer {
13020
+ stroke: ${cssVar("annoOuterStroke")};
13021
+ }
13022
+ .a9s-selection.improved-polygon .a9s-handle .a9s-handle-outer,
13023
+ .a9s-annotation.improved-polygon.editable .a9s-handle .a9s-handle-outer {
13024
+ stroke: ${cssVar("annoHandleOuterStroke")};
13025
+ }
13026
+ .a9s-selection.improved-polygon .a9s-handle .a9s-handle-inner,
13027
+ .a9s-annotation.improved-polygon.editable .a9s-handle .a9s-handle-inner {
13028
+ stroke: ${cssVar("annoHandleInnerStroke")};
13029
+ fill: ${cssVar("annoHandleInnerFill")};
13030
+ }
13031
+ .a9s-selection.improved-polygon .a9s-handle .a9s-handle-inner:hover,
13032
+ .a9s-annotation.improved-polygon.editable .a9s-handle.selected .a9s-handle-inner,
13033
+ .a9s-annotation.improved-polygon.editable .a9s-handle .a9s-handle-inner:hover {
13034
+ fill: ${cssVar("annoHandleHoverFill")};
13035
+ }
13036
+
13037
+ /* ── 标注编辑器 ── */
13038
+ .r6o-editor {
13039
+ color: ${cssVar("annoEditorText")};
13040
+ }
13041
+ .r6o-editor .r6o-editor-inner {
13042
+ background-color: ${cssVar("annoEditorBg")};
13043
+ box-shadow: 2px 2px 42px rgba(0,0,0,0.4);
13044
+ }
13045
+ .r6o-editor .r6o-editor-inner .r6o-widget {
13046
+ border-bottom: 1px solid ${cssVar("annoEditorBorder")};
13047
+ }
13048
+ .r6o-editor .r6o-arrow:after {
13049
+ background-color: ${cssVar("annoEditorBg")};
13050
+ }
13051
+
13052
+ /* ── 编辑器按钮 ── */
13053
+ .r6o-btn {
13054
+ background-color: ${cssVar("annoEditorBtnBg")};
13055
+ border: 1px solid ${cssVar("annoEditorBtnBg")};
13056
+ color: ${cssVar("annoEditorBtnColor")};
13057
+ }
13058
+ .r6o-btn:hover {
13059
+ background-color: ${cssVar("annoEditorBtnHoverBg")};
13060
+ border-color: ${cssVar("annoEditorBtnHoverBg")};
13061
+ }
13062
+ .r6o-btn.outline {
13063
+ border: 1px solid ${cssVar("annoEditorBtnBg")};
13064
+ color: ${cssVar("annoEditorBtnBg")};
13065
+ background-color: transparent;
13066
+ }
13067
+
13068
+ /* ── 编辑器输入框 ── */
13069
+ .r6o-autocomplete input,
13070
+ .r6o-widget.r6o-tag input,
13071
+ .r6o-editable-text {
13072
+ color: ${cssVar("annoEditorText")};
13073
+ }
13074
+ .r6o-widget.comment.editable {
13075
+ background-color: ${cssVar("annoEditorInputBg")};
13076
+ }
13077
+ .r6o-widget.r6o-tag {
13078
+ background-color: ${cssVar("annoEditorInputBg")};
13079
+ border-bottom: 1px solid ${cssVar("annoEditorBorder")};
13080
+ }
13081
+ .r6o-widget.r6o-tag ul.r6o-taglist li {
13082
+ background-color: ${cssVar("annoEditorBg")};
13083
+ border: 1px solid ${cssVar("annoEditorBorder")};
13084
+ }
13085
+ .r6o-widget .r6o-lastmodified {
13086
+ border: 1px solid ${cssVar("annoEditorBorder")};
13087
+ }
13088
+ .r6o-widget .r6o-arrow-down {
13089
+ background-color: ${cssVar("annoEditorBg")};
13090
+ border: 1px solid ${cssVar("annoEditorBorder")};
12657
13091
  }`;
12658
13092
  document.head.appendChild(style);
12659
13093
  }
@@ -13716,6 +14150,9 @@ function t(path) {
13716
14150
  }
13717
14151
  return typeof value === "string" ? value : path;
13718
14152
  }
14153
+ function getCurrentLocale() {
14154
+ return currentLocale;
14155
+ }
13719
14156
  function getWithUnit(value, unitSuffix) {
13720
14157
  return value.toFixed(2) + "μ" + unitSuffix;
13721
14158
  }
@@ -14347,11 +14784,11 @@ class MagnificationPlugin {
14347
14784
  gap: 8px;
14348
14785
  padding: 10px;
14349
14786
  z-index: 100;
14350
- background: rgba(24, 28, 36, 0.85);
14787
+ background: ${cssVar("panelBackground")};
14351
14788
  border-radius: 12px;
14352
14789
  backdrop-filter: blur(10px);
14353
- border: 1px solid rgba(255,255,255,0.1);
14354
- box-shadow: 0 8px 32px rgba(0,0,0,0.3);
14790
+ border: 1px solid ${cssVar("panelBorder")};
14791
+ box-shadow: ${cssVar("panelShadow")};
14355
14792
  }
14356
14793
  .med-magnification--TOP_LEFT { top: calc(18px + ${this.options.offsetY || 0}px); left: calc(18px + ${this.options.offsetX || 0}px); }
14357
14794
  .med-magnification--TOP_CENTER { top: calc(18px + ${this.options.offsetY || 0}px); left: 50%; transform: translateX(-50%) translateX(${this.options.offsetX || 0}px); }
@@ -14363,10 +14800,10 @@ class MagnificationPlugin {
14363
14800
  .med-magnification--MIDDLE_RIGHT { top: 50%; right: calc(18px - ${this.options.offsetX || 0}px); transform: translateY(-50%) translateY(${this.options.offsetY || 0}px); }
14364
14801
 
14365
14802
  .med-magnification-display {
14366
- background: rgba(255,255,255,0.08);
14367
- color: #f2f5f8;
14803
+ background: ${cssVar("btnBackground")};
14804
+ color: ${cssVar("textPrimary")};
14368
14805
  font-size: 14px;
14369
- border: 1px dashed rgba(255,255,255,0.3);
14806
+ border: 1px dashed ${cssVar("sliderTrackBg")};
14370
14807
  padding: 8px 0px;
14371
14808
  border-radius: 8px;
14372
14809
  text-align: center;
@@ -14379,8 +14816,8 @@ class MagnificationPlugin {
14379
14816
  gap: 6px;
14380
14817
  }
14381
14818
  .med-magnification-btn {
14382
- background: rgba(49, 208, 170, 0.15);
14383
- color: #f2f5f8;
14819
+ background: ${cssVar("accentBgLow")};
14820
+ color: ${cssVar("textPrimary")};
14384
14821
  border: none;
14385
14822
  padding: 8px 16px;
14386
14823
  border-radius: 8px;
@@ -14389,7 +14826,7 @@ class MagnificationPlugin {
14389
14826
  font-weight: bold;
14390
14827
  }
14391
14828
  .med-magnification-btn:hover {
14392
- background: rgba(49, 208, 170, 0.3);
14829
+ background: ${cssVar("accentBgHigh")};
14393
14830
  }
14394
14831
  .med-magnification-btn:active {
14395
14832
  transform: scale(0.95);
@@ -14937,6 +15374,24 @@ class ScalebarPlugin {
14937
15374
  this.viewer.scalebar(this.options);
14938
15375
  this.scalebar = this.viewer.scalebarInstance;
14939
15376
  }
15377
+ /**
15378
+ * 更新主题颜色(动态切换主题时调用)
15379
+ */
15380
+ updateTheme(colors) {
15381
+ if (this.scalebar) {
15382
+ const scalebarEl = this.scalebar.element || this.scalebar.divElt;
15383
+ if (scalebarEl) {
15384
+ scalebarEl.style.color = colors.textPrimary;
15385
+ scalebarEl.style.borderColor = colors.textPrimary;
15386
+ }
15387
+ const labels = scalebarEl == null ? void 0 : scalebarEl.querySelectorAll(".scalebar-label");
15388
+ if (labels) {
15389
+ labels.forEach((label) => {
15390
+ label.style.color = colors.textPrimary;
15391
+ });
15392
+ }
15393
+ }
15394
+ }
14940
15395
  destroy() {
14941
15396
  if (this.scalebar && typeof this.scalebar.destroy === "function") {
14942
15397
  this.scalebar.destroy();
@@ -15387,28 +15842,22 @@ class SelectionPlugin {
15387
15842
  },
15388
15843
  borderStyle: {
15389
15844
  width: "2px",
15390
- // 稍微加粗,更有质感
15391
- color: "#4CAF50"
15392
- // 使用经典的“激活蓝”
15845
+ color: cssVar("selectionColor")
15393
15846
  },
15394
15847
  handleStyle: {
15395
15848
  top: "50%",
15396
15849
  left: "50%",
15397
15850
  width: "10px",
15398
- // 增大触点,方便鼠标点击
15399
15851
  height: "10px",
15400
15852
  margin: "-6px 0 0 -6px",
15401
- background: "#4CAF50",
15402
- // 白色背景
15403
- border: "2px solid #4CAF50"
15404
- // 蓝色边框
15853
+ background: cssVar("selectionColor"),
15854
+ border: `2px solid ${cssVar("selectionHandleBorder")}`
15405
15855
  },
15406
15856
  cornersStyle: {
15407
15857
  width: "12px",
15408
- // 角部手柄稍微比边部大一点
15409
15858
  height: "12px",
15410
- background: "#4CAF50",
15411
- border: "2px solid #4CAF50"
15859
+ background: cssVar("selectionColor"),
15860
+ border: `2px solid ${cssVar("selectionHandleBorder")}`
15412
15861
  },
15413
15862
  ...options,
15414
15863
  // Override onSelection to provide a blob
@@ -15559,6 +16008,35 @@ class SelectionPlugin {
15559
16008
  }
15560
16009
  return false;
15561
16010
  }
16011
+ /**
16012
+ * 更新主题颜色(动态切换主题时调用)
16013
+ */
16014
+ updateTheme(colors) {
16015
+ if (this.selection) {
16016
+ if (this.selection.border) {
16017
+ this.selection.border.style.width = "2px";
16018
+ this.selection.border.style.borderColor = colors.selectionColor;
16019
+ }
16020
+ if (this.selection.handles) {
16021
+ const handles = this.selection.handles;
16022
+ Object.values(handles).forEach((handle) => {
16023
+ if (handle && handle.style) {
16024
+ handle.style.background = colors.selectionColor;
16025
+ handle.style.border = `2px solid ${colors.selectionHandleBorder}`;
16026
+ }
16027
+ });
16028
+ }
16029
+ if (this.selection.corners) {
16030
+ const corners = this.selection.corners;
16031
+ Object.values(corners).forEach((corner) => {
16032
+ if (corner && corner.style) {
16033
+ corner.style.background = colors.selectionColor;
16034
+ corner.style.border = `2px solid ${colors.selectionHandleBorder}`;
16035
+ }
16036
+ });
16037
+ }
16038
+ }
16039
+ }
15562
16040
  /**
15563
16041
  * 销毁插件
15564
16042
  */
@@ -16258,11 +16736,11 @@ class MedToolbar {
16258
16736
  gap: 12px;
16259
16737
  padding: 10px;
16260
16738
  z-index: 100;
16261
- background: rgba(24, 28, 36, 0.85);
16739
+ background: ${cssVar("panelBackground")};
16262
16740
  border-radius: 12px;
16263
16741
  backdrop-filter: blur(10px);
16264
- border: 1px solid rgba(255,255,255,0.1);
16265
- box-shadow: 0 8px 32px rgba(0,0,0,0.3);
16742
+ border: 1px solid ${cssVar("panelBorder")};
16743
+ box-shadow: ${cssVar("panelShadow")};
16266
16744
  }
16267
16745
 
16268
16746
  /* 定位 */
@@ -16279,8 +16757,8 @@ class MedToolbar {
16279
16757
 
16280
16758
  /* 按钮及动画 */
16281
16759
  .med-main-btn {
16282
- background: rgba(255,255,255,0.08);
16283
- color: #f2f5f8;
16760
+ background: ${cssVar("btnBackground")};
16761
+ color: ${cssVar("textPrimary")};
16284
16762
  border: none;
16285
16763
  padding: 8px 16px;
16286
16764
  border-radius: 8px;
@@ -16290,20 +16768,20 @@ class MedToolbar {
16290
16768
  align-items: center;
16291
16769
  justify-content: center;
16292
16770
  }
16293
- .med-main-btn:hover, .med-main-btn.active { background: rgba(49, 208, 170, 0.2); }
16771
+ .med-main-btn:hover, .med-main-btn.active { background: ${cssVar("accentBgHigh")}; }
16294
16772
  .med-main-btn:active { transform: scale(0.9); }
16295
- .med-main-btn img { width: 24px; height: 24px; }
16773
+ .med-main-btn img { width: 24px; height: 24px; filter: ${cssVar("iconFilter")}; }
16296
16774
 
16297
16775
  /* 下拉框基础及进场动画 */
16298
16776
  .med-toolbar-dropdown {
16299
16777
  position: absolute;
16300
16778
  bottom: calc(100% + 12px);
16301
16779
  left: 50%;
16302
- background: #181c24;
16303
- border: 1px solid rgba(255,255,255,0.1);
16780
+ background: ${cssVar("panelBackgroundSolid")};
16781
+ border: 1px solid ${cssVar("panelBorder")};
16304
16782
  border-radius: 12px;
16305
16783
  padding: 16px;
16306
- box-shadow: 0 10px 40px rgba(0,0,0,0.5);
16784
+ box-shadow: ${cssVar("panelShadow")};
16307
16785
  min-width: 220px;
16308
16786
  z-index: 101;
16309
16787
 
@@ -16348,8 +16826,8 @@ class MedToolbar {
16348
16826
  .med-tooltip {
16349
16827
  position: absolute;
16350
16828
  padding: 6px 10px;
16351
- background: rgba(0, 0, 0, 0.75);
16352
- color: #fff;
16829
+ background: ${cssVar("tooltipBg")};
16830
+ color: ${cssVar("tooltipColor")};
16353
16831
  border-radius: 6px;
16354
16832
  font-size: 12px;
16355
16833
  white-space: nowrap;
@@ -16410,13 +16888,13 @@ class MedToolbar {
16410
16888
  }
16411
16889
 
16412
16890
  /* 内容样式 */
16413
- .med-toolbar-section-title { font-size: 11px; color: rgba(255,255,255,0.4); margin-bottom: 10px; letter-spacing: 1px; }
16891
+ .med-toolbar-section-title { font-size: 11px; color: ${cssVar("textMuted")}; margin-bottom: 10px; letter-spacing: 1px; }
16414
16892
  .med-color-grid { display: flex; gap: 10px; margin-bottom: 20px; }
16415
16893
  .med-color-item { width: 24px; height: 24px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; transition: 0.2s; }
16416
- .med-color-item.active { border-color: #fff; transform: scale(1.15); box-shadow: 0 0 10px rgba(255,255,255,0.3); }
16894
+ .med-color-item.active { border-color: ${cssVar("colorItemActiveBorder")}; transform: scale(1.15); box-shadow: ${cssVar("colorItemActiveShadow")}; }
16417
16895
  .med-tool-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
16418
- .med-tool-item { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.05); color: #fff; padding: 8px 4px; border-radius: 6px; cursor: pointer; font-size: 12px; transition: 0.2s; }
16419
- .med-tool-item:hover { background: rgba(49, 208, 170, 0.2); border-color: rgba(49, 208, 170, 0.4); }
16896
+ .med-tool-item { background: ${cssVar("toolItemBg")}; border: 1px solid ${cssVar("toolItemBorder")}; color: ${cssVar("textPrimary")}; padding: 8px 4px; border-radius: 6px; cursor: pointer; font-size: 12px; transition: 0.2s; }
16897
+ .med-tool-item:hover { background: ${cssVar("toolItemHoverBg")}; border-color: ${cssVar("toolItemHoverBorder")}; }
16420
16898
 
16421
16899
  /* 颜色调整下拉框样式 */
16422
16900
  .med-color-adjust-dropdown {
@@ -16446,14 +16924,14 @@ class MedToolbar {
16446
16924
  .med-toolbar-section-title {
16447
16925
  margin-bottom: 8px;
16448
16926
  font-size: 13px;
16449
- color: #f2f5f8;
16927
+ color: ${cssVar("textPrimary")};
16450
16928
  }
16451
16929
 
16452
16930
  .med-toolbar-section input[type="range"] {
16453
16931
  width: 100%;
16454
16932
  -webkit-appearance: none;
16455
16933
  height: 4px;
16456
- background: rgba(255,255,255,0.2);
16934
+ background: ${cssVar("sliderTrackBg")};
16457
16935
  border-radius: 2px;
16458
16936
  outline: none;
16459
16937
  margin-top: 5px;
@@ -16465,19 +16943,19 @@ class MedToolbar {
16465
16943
  width: 16px;
16466
16944
  height: 16px;
16467
16945
  border-radius: 50%;
16468
- background: #31d0aa;
16946
+ background: ${cssVar("sliderThumbColor")};
16469
16947
  cursor: pointer;
16470
- border: 2px solid #181c24;
16948
+ border: 2px solid ${cssVar("panelBackgroundSolid")};
16471
16949
  transition: background 0.15s ease-in-out;
16472
16950
  }
16473
16951
 
16474
16952
  .med-toolbar-section input[type="range"]::-webkit-slider-thumb:hover {
16475
- background: #25a084;
16953
+ background: ${cssVar("sliderThumbHover")};
16476
16954
  }
16477
16955
 
16478
16956
  .med-slider-value {
16479
16957
  font-size: 12px;
16480
- color: rgba(255,255,255,0.7);
16958
+ color: ${cssVar("textSecondary")};
16481
16959
  align-self: flex-end;
16482
16960
  }
16483
16961
 
@@ -16490,7 +16968,7 @@ class MedToolbar {
16490
16968
 
16491
16969
  .med-checkbox-section label {
16492
16970
  font-size: 13px;
16493
- color: #f2f5f8;
16971
+ color: ${cssVar("textPrimary")};
16494
16972
  cursor: pointer;
16495
16973
  }
16496
16974
 
@@ -16500,7 +16978,7 @@ class MedToolbar {
16500
16978
  appearance: none;
16501
16979
  width: 18px;
16502
16980
  height: 18px;
16503
- border: 1px solid rgba(255,255,255,0.4);
16981
+ border: 1px solid ${cssVar("checkboxBorder")};
16504
16982
  border-radius: 4px;
16505
16983
  background-color: transparent;
16506
16984
  cursor: pointer;
@@ -16509,8 +16987,8 @@ class MedToolbar {
16509
16987
  }
16510
16988
 
16511
16989
  .med-checkbox-section input[type="checkbox"]:checked {
16512
- background-color: #31d0aa;
16513
- border-color: #31d0aa;
16990
+ background-color: ${cssVar("checkboxCheckedBg")};
16991
+ border-color: ${cssVar("checkboxCheckedBg")};
16514
16992
  }
16515
16993
 
16516
16994
  .med-checkbox-section input[type="checkbox"]:checked::after {
@@ -16528,12 +17006,12 @@ class MedToolbar {
16528
17006
  .med-reset-btn {
16529
17007
  width: 100%;
16530
17008
  margin-top: 15px;
16531
- background: rgba(200, 50, 50, 0.1);
16532
- color: #ff6b6b;
16533
- border: 1px solid rgba(255, 100, 100, 0.2);
17009
+ background: ${cssVar("dangerBgLow")};
17010
+ color: ${cssVar("dangerColor")};
17011
+ border: 1px solid ${cssVar("dangerBgHigh")};
16534
17012
  }
16535
17013
  .med-reset-btn:hover {
16536
- background: rgba(200, 50, 50, 0.3);
17014
+ background: ${cssVar("dangerBgHigh")};
16537
17015
  }
16538
17016
  `;
16539
17017
  document.head.appendChild(style);
@@ -16549,6 +17027,7 @@ class MedViewerEngine {
16549
17027
  __publicField(this, "selection", null);
16550
17028
  __publicField(this, "scalebar", null);
16551
17029
  __publicField(this, "magnification", null);
17030
+ __publicField(this, "themeManager", null);
16552
17031
  __publicField(this, "options");
16553
17032
  __publicField(this, "events", /* @__PURE__ */ new Map());
16554
17033
  var _a2;
@@ -16622,6 +17101,7 @@ class MedViewerEngine {
16622
17101
  options.osdOptions = osdOptions;
16623
17102
  this.options = options;
16624
17103
  this.viewer = OpenSeadragon(osdOptions);
17104
+ this.themeManager = new ThemeManager(this.viewer.element, options.theme);
16625
17105
  this.viewer.addOnceHandler("open", () => {
16626
17106
  this.viewer.viewport.goHome();
16627
17107
  this.emit("ready");
@@ -16824,16 +17304,45 @@ class MedViewerEngine {
16824
17304
  var _a2;
16825
17305
  (_a2 = this.events.get(event2)) == null ? void 0 : _a2.forEach((fn) => fn(payload));
16826
17306
  }
17307
+ /**
17308
+ * 动态设置主题
17309
+ * @param config 主题配置:预设名称 / ThemeDefinition / Partial<ThemeColors>
17310
+ */
17311
+ setTheme(config) {
17312
+ var _a2;
17313
+ if (this.themeManager) {
17314
+ this.themeManager.setTheme(config);
17315
+ if (this.selection) {
17316
+ this.selection.updateTheme(this.themeManager.getColors());
17317
+ }
17318
+ if (this.scalebar) {
17319
+ this.scalebar.updateTheme(this.themeManager.getColors());
17320
+ }
17321
+ }
17322
+ console.log(`[MedEngine] Theme changed to ${(_a2 = this.themeManager) == null ? void 0 : _a2.getThemeName()}`);
17323
+ }
17324
+ /**
17325
+ * 获取当前主题颜色
17326
+ */
17327
+ getThemeColors() {
17328
+ var _a2;
17329
+ return ((_a2 = this.themeManager) == null ? void 0 : _a2.getColors()) ?? null;
17330
+ }
17331
+ getThemeName() {
17332
+ var _a2;
17333
+ return ((_a2 = this.themeManager) == null ? void 0 : _a2.getThemeName()) ?? null;
17334
+ }
16827
17335
  /**
16828
17336
  * 销毁引擎与所有插件
16829
17337
  */
16830
17338
  destroy() {
16831
- var _a2, _b2, _c2, _d2, _e2;
17339
+ var _a2, _b2, _c2, _d2, _e2, _f;
16832
17340
  (_a2 = this.anno) == null ? void 0 : _a2.destroy();
16833
17341
  (_b2 = this.toolbar) == null ? void 0 : _b2.destroy();
16834
17342
  (_c2 = this.selection) == null ? void 0 : _c2.destroy();
16835
17343
  (_d2 = this.scalebar) == null ? void 0 : _d2.destroy();
16836
17344
  (_e2 = this.colorAdjust) == null ? void 0 : _e2.destroy();
17345
+ (_f = this.themeManager) == null ? void 0 : _f.destroy();
16837
17346
  this.viewer.destroy();
16838
17347
  }
16839
17348
  /**
@@ -16853,6 +17362,9 @@ class MedViewerEngine {
16853
17362
  ;
16854
17363
  console.log(`[MedEngine] Locale changed to ${locale}`);
16855
17364
  }
17365
+ getLocale() {
17366
+ return getCurrentLocale();
17367
+ }
16856
17368
  }
16857
17369
  const MedViewer = defineComponent({
16858
17370
  name: "MedViewer",
@@ -16860,6 +17372,10 @@ const MedViewer = defineComponent({
16860
17372
  options: {
16861
17373
  type: Object,
16862
17374
  required: true
17375
+ },
17376
+ theme: {
17377
+ type: [String, Object],
17378
+ default: void 0
16863
17379
  }
16864
17380
  },
16865
17381
  emits: ["ready"],
@@ -16869,13 +17385,20 @@ const MedViewer = defineComponent({
16869
17385
  onMounted(() => {
16870
17386
  if (!containerRef.value)
16871
17387
  return;
16872
- engineRef.value = new MedViewerEngine({
17388
+ const engineOptions = {
16873
17389
  osdOptions: props.options.osdOptions,
16874
17390
  locale: props.options.locale,
17391
+ theme: props.theme || props.options.theme,
16875
17392
  plugins: props.options.plugins
16876
- });
17393
+ };
17394
+ engineRef.value = new MedViewerEngine(engineOptions);
16877
17395
  emit("ready", engineRef.value);
16878
17396
  });
17397
+ watch(() => props.theme, (newTheme) => {
17398
+ if (newTheme !== void 0 && engineRef.value) {
17399
+ engineRef.value.setTheme(newTheme);
17400
+ }
17401
+ });
16879
17402
  onBeforeUnmount(() => {
16880
17403
  var _a2;
16881
17404
  (_a2 = engineRef.value) == null ? void 0 : _a2.destroy();
@@ -16895,7 +17418,9 @@ if (typeof window !== "undefined") {
16895
17418
  MedToolbar,
16896
17419
  SelectionPlugin,
16897
17420
  ColorAdjustPlugin,
16898
- MagnificationPlugin
17421
+ MagnificationPlugin,
17422
+ ThemeManager,
17423
+ PRESET_THEMES
16899
17424
  };
16900
17425
  }
16901
17426
  export {
@@ -16908,8 +17433,11 @@ export {
16908
17433
  MedViewer,
16909
17434
  MedViewerEngine,
16910
17435
  default2 as OpenSeadragon,
17436
+ PRESET_THEMES,
16911
17437
  ScalebarLocation,
16912
17438
  ScalebarType,
16913
17439
  SelectionPlugin,
16914
- ToolbarPosition
17440
+ ThemeManager,
17441
+ ToolbarPosition,
17442
+ cssVar
16915
17443
  };