@zzalai/leafer-point-annotation 1.1.2 → 1.1.4

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/docs/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Leafer Point Annotation</title>
8
- <script type="module" crossorigin src="./assets/index-D7LeHdrN.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-BgRWhBwU.css">
8
+ <script type="module" crossorigin src="./assets/index-DJUbn3Yd.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-BICV4seT.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzalai/leafer-point-annotation",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "A Vue3 component for point annotation and brush painting on images using LeaferJS, supporting COCO/YOLO/JSON export, designed for AI model training dataset annotation",
5
5
  "type": "module",
6
6
  "publishConfig": {
package/src/App.vue CHANGED
@@ -2,7 +2,7 @@
2
2
  <div class="app">
3
3
  <h1>LeaferJS Point Annotation Test</h1>
4
4
 
5
- <div class="editor-container">
5
+ <div class="editor-container" :class="{ 'multi-instance': enableMultiInstance }">
6
6
  <PointAnnotation
7
7
  ref="pointAnnotation"
8
8
  :imageSource="imageSource"
@@ -14,6 +14,13 @@
14
14
  @loadError="handleLoadError"
15
15
  @update:currentLayer="handleLayerChange"
16
16
  />
17
+ <PointAnnotation
18
+ v-if="enableMultiInstance"
19
+ ref="pointAnnotation2"
20
+ :imageSource="imageSource2"
21
+ :options="editorOptions2"
22
+ @pointChange="handlePointChange2"
23
+ />
17
24
  </div>
18
25
 
19
26
  <div class="controls">
@@ -73,6 +80,7 @@
73
80
  <label><input type="checkbox" v-model="showToolbar" /> 显示组件工具栏</label>
74
81
  <label><input type="checkbox" v-model="showZoomController" /> 显示缩放控制器</label>
75
82
  <label><input type="checkbox" v-model="enableBrush" /> 启用笔刷功能</label>
83
+ <label><input type="checkbox" v-model="enableMultiInstance" /> 双实例测试(验证多实例快捷键不冲突)</label>
76
84
  </div>
77
85
  <div class="multi-layer-row">
78
86
  <label>背景色: <input type="color" v-model="canvasBackground" style="width: 40px; height: 28px; vertical-align: middle; margin-left: 6px;" /></label>
@@ -315,6 +323,35 @@ const canvasBackground = ref('#f6f6f6')
315
323
  const zoomMin = ref(0.2)
316
324
  const zoomMax = ref(4)
317
325
  const enableBrush = ref(true)
326
+ const enableMultiInstance = ref(false)
327
+
328
+ const imageSource2 = computed(() => {
329
+ if (!imageUrl.value) return undefined
330
+ return { id: 'test-image-2', url: imageUrl.value }
331
+ })
332
+
333
+ const editorOptions2 = computed<OptionsSource>(() => {
334
+ return {
335
+ pointStyle: {
336
+ circleFill: '#00ff00',
337
+ circleStroke: '#fff',
338
+ selectedCircleFill: '#ff0',
339
+ selectedCircleStroke: '#000'
340
+ },
341
+ brushStyle: {
342
+ color: '#00ff00',
343
+ opacity: 0.55,
344
+ size: 100
345
+ },
346
+ showToolbar: true,
347
+ showZoomController: true,
348
+ enableBrush: enableBrush.value
349
+ }
350
+ })
351
+
352
+ const handlePointChange2 = (points: any[]) => {
353
+ console.log('Editor 2 - Points changed:', points)
354
+ }
318
355
 
319
356
  const editorOptions = computed<OptionsSource>(() => {
320
357
  if (useMultiLayer.value) {
@@ -757,6 +794,22 @@ h1 {
757
794
  margin-bottom: 30px;
758
795
  }
759
796
 
797
+ .editor-container.multi-instance {
798
+ display: flex;
799
+ gap: 12px;
800
+ height: auto;
801
+ }
802
+
803
+ .editor-container.multi-instance > :deep(.point-annotation),
804
+ .editor-container.multi-instance > .point-annotation {
805
+ flex: 1;
806
+ min-width: 0;
807
+ height: 600px;
808
+ border: 1px solid #ddd;
809
+ border-radius: 8px;
810
+ overflow: hidden;
811
+ }
812
+
760
813
  .controls {
761
814
  margin-bottom: 30px;
762
815
  padding: 20px;
@@ -524,6 +524,9 @@ const isDrawing = ref(false);
524
524
  // 撤销/重做管理器
525
525
  let commandManager: CommandManager | null = null;
526
526
 
527
+ // 🔧 多实例支持:tinykeys 解绑函数(保存在组件作用域,避免多个实例互相覆盖 window.__pointAnnotationHotkeysUnsubscribe)
528
+ let hotkeysUnsubscribe: (() => void) | null = null;
529
+
527
530
  // 根据配置强制【标注点】不跟随画布Scale变化
528
531
  const changePointScaleRelativeCanvas = (pointAnnotationLayer: Group | null) => {
529
532
  // 检查是否开启固定大小功能
@@ -1091,7 +1094,8 @@ onMounted(() => {
1091
1094
  },
1092
1095
  });
1093
1096
 
1094
- window.__pointAnnotationHotkeysUnsubscribe = unsubscribe;
1097
+ // 🔧 多实例支持:unsubscribe 保存在当前组件作用域,不再使用全局 window 存储
1098
+ hotkeysUnsubscribe = unsubscribe;
1095
1099
  });
1096
1100
  });
1097
1101
 
@@ -1179,9 +1183,10 @@ onUnmounted(() => {
1179
1183
  window.removeEventListener("mousemove", handleMouseMove);
1180
1184
  window.removeEventListener('focusout', handleFocusOut);
1181
1185
 
1182
- if (window.__pointAnnotationHotkeysUnsubscribe) {
1183
- window.__pointAnnotationHotkeysUnsubscribe();
1184
- delete window.__pointAnnotationHotkeysUnsubscribe;
1186
+ // 🔧 多实例支持:调用当前实例自己的 unsubscribe,不再使用全局 window
1187
+ if (hotkeysUnsubscribe) {
1188
+ hotkeysUnsubscribe();
1189
+ hotkeysUnsubscribe = null;
1185
1190
  }
1186
1191
  });
1187
1192
 
@@ -1194,7 +1199,7 @@ const selectTool = () => {
1194
1199
  app.editor.config.resizeable = false
1195
1200
  app.editor.config.multipleSelect = true
1196
1201
  Object.values(canvasBrushesByLayer.value).forEach(brush => brush.setPointerEvents(false));
1197
- updateLabelEditable(true);
1202
+ updateLabelEditable(false);
1198
1203
  };
1199
1204
 
1200
1205
  const pointTool = () => {
@@ -1204,7 +1209,7 @@ const pointTool = () => {
1204
1209
  app.editor.config.moveable = true
1205
1210
  app.editor.config.multipleSelect = false
1206
1211
  Object.values(canvasBrushesByLayer.value).forEach(brush => brush.setPointerEvents(false));
1207
- updateLabelEditable(true);
1212
+ updateLabelEditable(false);
1208
1213
  };
1209
1214
 
1210
1215
  const brushTool = (openPanel?: boolean) => {