@8btc/whiteboard 0.0.10 → 0.0.12
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/index.css +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +82 -36
- package/dist/index.umd.js +92 -36
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
55
55
|
--color-red-500: oklch(63.7% .237 25.331);
|
|
56
56
|
--color-red-600: oklch(57.7% .245 27.325);
|
|
57
|
+
--color-orange-500: oklch(70.5% .213 47.604);
|
|
58
|
+
--color-orange-600: oklch(64.6% .222 41.116);
|
|
57
59
|
--color-green-500: oklch(72.3% .219 149.579);
|
|
58
60
|
--color-green-600: oklch(62.7% .194 149.214);
|
|
59
61
|
--color-cyan-500: oklch(71.5% .143 215.221);
|
|
@@ -643,6 +645,10 @@
|
|
|
643
645
|
background-color: var(--color-indigo-500);
|
|
644
646
|
}
|
|
645
647
|
|
|
648
|
+
.bg-orange-500 {
|
|
649
|
+
background-color: var(--color-orange-500);
|
|
650
|
+
}
|
|
651
|
+
|
|
646
652
|
.bg-primary {
|
|
647
653
|
background-color: var(--primary);
|
|
648
654
|
}
|
|
@@ -820,6 +826,10 @@
|
|
|
820
826
|
background-color: var(--color-indigo-600);
|
|
821
827
|
}
|
|
822
828
|
|
|
829
|
+
.hover\:bg-orange-600:hover {
|
|
830
|
+
background-color: var(--color-orange-600);
|
|
831
|
+
}
|
|
832
|
+
|
|
823
833
|
.hover\:bg-primary\/90:hover {
|
|
824
834
|
background-color: var(--primary);
|
|
825
835
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export declare class CanvasApi extends CanvasCore {
|
|
|
19
19
|
* 如果你不知道自己在干什么,请使用更高层的封装方法,如 createImageNode
|
|
20
20
|
*/
|
|
21
21
|
createNodes(nodes: INode[]): void;
|
|
22
|
+
/**
|
|
23
|
+
* 根据 ID 获取节点
|
|
24
|
+
*/
|
|
25
|
+
getNodeById<T extends INode = INode>(id: string): T | null;
|
|
22
26
|
/**
|
|
23
27
|
* 更新视口位置
|
|
24
28
|
*/
|
|
@@ -51,6 +55,12 @@ export declare class CanvasApi extends CanvasCore {
|
|
|
51
55
|
quality?: number;
|
|
52
56
|
padding?: number;
|
|
53
57
|
}): string | null;
|
|
58
|
+
/**
|
|
59
|
+
* 导出带有标注的图片节点为图片
|
|
60
|
+
* @param id - 图片节点 ID
|
|
61
|
+
* @returns DataURL 格式的图片数据,如果节点不存在则返回 null
|
|
62
|
+
*/
|
|
63
|
+
exportImageWithMarker(id: string): string | null;
|
|
54
64
|
/**
|
|
55
65
|
* 删除当前选中的节点
|
|
56
66
|
* 如果删除的是 image 节点,会同步删除所有关联的 image-marker
|
package/dist/index.js
CHANGED
|
@@ -518,12 +518,14 @@ const IMAGE = {
|
|
|
518
518
|
MIN_SIZE: 10
|
|
519
519
|
};
|
|
520
520
|
class BaseCanvasNode {
|
|
521
|
-
constructor(core, node) {
|
|
521
|
+
constructor(core, node, isDraft = false) {
|
|
522
522
|
__publicField(this, "core");
|
|
523
523
|
__publicField(this, "node");
|
|
524
524
|
__publicField(this, "element");
|
|
525
|
+
__publicField(this, "isDraft");
|
|
525
526
|
this.core = core;
|
|
526
527
|
this.node = node;
|
|
528
|
+
this.isDraft = isDraft;
|
|
527
529
|
this.element = this.createElement();
|
|
528
530
|
}
|
|
529
531
|
/**
|
|
@@ -546,8 +548,8 @@ function getRectSize(rect) {
|
|
|
546
548
|
};
|
|
547
549
|
}
|
|
548
550
|
class RectNode extends BaseCanvasNode {
|
|
549
|
-
constructor(core, node) {
|
|
550
|
-
super(core, node);
|
|
551
|
+
constructor(core, node, isDraft = false) {
|
|
552
|
+
super(core, node, isDraft);
|
|
551
553
|
__privateAdd(this, _RectNode_instances);
|
|
552
554
|
__privateAdd(this, _toolTypeChangeHandler, (toolType) => {
|
|
553
555
|
const isSelect = toolType === "select";
|
|
@@ -672,8 +674,8 @@ setupEventHandlers_fn = function(rect) {
|
|
|
672
674
|
});
|
|
673
675
|
};
|
|
674
676
|
class ImageNode extends BaseCanvasNode {
|
|
675
|
-
constructor(core, node) {
|
|
676
|
-
super(core, node);
|
|
677
|
+
constructor(core, node, isDraft = false) {
|
|
678
|
+
super(core, node, isDraft);
|
|
677
679
|
__privateAdd(this, _ImageNode_instances);
|
|
678
680
|
__privateAdd(this, _toolTypeChangeHandler2, (toolType) => {
|
|
679
681
|
const isSelect = toolType === "select";
|
|
@@ -880,8 +882,8 @@ syncImageMarkersToState_fn = function() {
|
|
|
880
882
|
});
|
|
881
883
|
};
|
|
882
884
|
class ImageMarkerNode extends BaseCanvasNode {
|
|
883
|
-
constructor(core, node) {
|
|
884
|
-
super(core, node);
|
|
885
|
+
constructor(core, node, isDraft = false) {
|
|
886
|
+
super(core, node, isDraft);
|
|
885
887
|
__privateAdd(this, _ImageMarkerNode_instances);
|
|
886
888
|
__privateAdd(this, _rect);
|
|
887
889
|
__privateAdd(this, _markerGroup);
|
|
@@ -905,12 +907,11 @@ class ImageMarkerNode extends BaseCanvasNode {
|
|
|
905
907
|
);
|
|
906
908
|
const group = new Konva.Group({
|
|
907
909
|
id: this.node.id,
|
|
908
|
-
name: `static ${this.node.meta.parent}`,
|
|
910
|
+
name: `static ${this.node.meta.parent} imageMarker`,
|
|
909
911
|
x: this.node.props.x,
|
|
910
912
|
y: this.node.props.y,
|
|
911
913
|
width,
|
|
912
|
-
height
|
|
913
|
-
listening: false
|
|
914
|
+
height
|
|
914
915
|
});
|
|
915
916
|
const rect = new Konva.Rect({
|
|
916
917
|
name: "rect",
|
|
@@ -922,12 +923,14 @@ class ImageMarkerNode extends BaseCanvasNode {
|
|
|
922
923
|
strokeWidth: 2,
|
|
923
924
|
dash: [5, 5],
|
|
924
925
|
fill: "transparent",
|
|
925
|
-
cornerRadius: RECT.CORNER_RADIUS
|
|
926
|
+
cornerRadius: RECT.CORNER_RADIUS,
|
|
927
|
+
listening: false
|
|
926
928
|
});
|
|
927
929
|
const markerGroup = new Konva.Group({
|
|
928
930
|
name: "marker-group",
|
|
929
931
|
x: width,
|
|
930
|
-
y: height
|
|
932
|
+
y: height,
|
|
933
|
+
visible: this.isDraft ? false : true
|
|
931
934
|
});
|
|
932
935
|
const stageScale = this.core.getStageScale();
|
|
933
936
|
const radius = 16 / stageScale;
|
|
@@ -1014,7 +1017,7 @@ class ImageMarkerNode extends BaseCanvasNode {
|
|
|
1014
1017
|
* 更新焦点状态(hover 或 selected)
|
|
1015
1018
|
*/
|
|
1016
1019
|
setFocusState(isFocus) {
|
|
1017
|
-
const strokeWidth = isFocus ?
|
|
1020
|
+
const strokeWidth = isFocus ? 4 : 2;
|
|
1018
1021
|
const scale = isFocus ? 1.2 : 1;
|
|
1019
1022
|
__privateGet(this, _rect).strokeWidth(strokeWidth);
|
|
1020
1023
|
__privateGet(this, _circle).strokeWidth(strokeWidth);
|
|
@@ -1045,14 +1048,14 @@ setupEventHandlers_fn3 = function() {
|
|
|
1045
1048
|
this.core.selectNode(this.node.id);
|
|
1046
1049
|
});
|
|
1047
1050
|
};
|
|
1048
|
-
function createCanvasNodeByType(core, type, config) {
|
|
1051
|
+
function createCanvasNodeByType(core, type, config, isDraft = false) {
|
|
1049
1052
|
switch (type) {
|
|
1050
1053
|
case "rectangle":
|
|
1051
|
-
return new RectNode(core, config);
|
|
1054
|
+
return new RectNode(core, config, isDraft);
|
|
1052
1055
|
case "image":
|
|
1053
|
-
return new ImageNode(core, config);
|
|
1056
|
+
return new ImageNode(core, config, isDraft);
|
|
1054
1057
|
case "image-marker":
|
|
1055
|
-
return new ImageMarkerNode(core, config);
|
|
1058
|
+
return new ImageMarkerNode(core, config, isDraft);
|
|
1056
1059
|
default:
|
|
1057
1060
|
return null;
|
|
1058
1061
|
}
|
|
@@ -1283,7 +1286,7 @@ class CanvasCore extends CanvasState {
|
|
|
1283
1286
|
__privateGet(this, _canvasTransformer).emitPositionChange();
|
|
1284
1287
|
}
|
|
1285
1288
|
createNodes(nodes) {
|
|
1286
|
-
const canvasNodes = nodes.map((node) => createCanvasNodeByType(this, node.type, node)).filter((node) => node !== null);
|
|
1289
|
+
const canvasNodes = nodes.map((node) => createCanvasNodeByType(this, node.type, node, false)).filter((node) => node !== null);
|
|
1287
1290
|
canvasNodes.forEach((node) => {
|
|
1288
1291
|
__privateGet(this, _mainLayer).add(node.getElement());
|
|
1289
1292
|
});
|
|
@@ -1354,26 +1357,25 @@ class CanvasCore extends CanvasState {
|
|
|
1354
1357
|
* @internal 仅供内部使用
|
|
1355
1358
|
*/
|
|
1356
1359
|
findImageAtPosition(position) {
|
|
1357
|
-
const layer = __privateGet(this, _mainLayer)
|
|
1358
|
-
const
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
const originalListeningStates = imageShapes.map(
|
|
1362
|
-
(shape) => shape.listening()
|
|
1360
|
+
const layer = __privateGet(this, _mainLayer);
|
|
1361
|
+
const shapes = layer.getChildren();
|
|
1362
|
+
const filteredShapes = shapes.filter(
|
|
1363
|
+
(shape) => !shape.name().includes("imageMarker")
|
|
1363
1364
|
);
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
const
|
|
1368
|
-
|
|
1369
|
-
|
|
1365
|
+
const sortedShapes = filteredShapes.slice().sort((a, b) => b.zIndex() - a.zIndex());
|
|
1366
|
+
for (const shape of sortedShapes) {
|
|
1367
|
+
const x = shape.x();
|
|
1368
|
+
const y = shape.y();
|
|
1369
|
+
const width = shape.width();
|
|
1370
|
+
const height = shape.height();
|
|
1371
|
+
if (position.x >= x && position.x <= x + width && position.y >= y && position.y <= y + height) {
|
|
1372
|
+
if (shape.getClassName() === "Image") {
|
|
1373
|
+
return shape;
|
|
1374
|
+
}
|
|
1375
|
+
return null;
|
|
1370
1376
|
}
|
|
1371
|
-
return null;
|
|
1372
|
-
} finally {
|
|
1373
|
-
imageShapes.forEach((shape, index) => {
|
|
1374
|
-
shape.listening(originalListeningStates[index]);
|
|
1375
|
-
});
|
|
1376
1377
|
}
|
|
1378
|
+
return null;
|
|
1377
1379
|
}
|
|
1378
1380
|
/**
|
|
1379
1381
|
* @internal 仅供内部使用
|
|
@@ -1383,7 +1385,7 @@ class CanvasCore extends CanvasState {
|
|
|
1383
1385
|
__privateGet(this, _draftNode).destroy();
|
|
1384
1386
|
}
|
|
1385
1387
|
const node = createNodeByType(type, position, void 0, meta);
|
|
1386
|
-
__privateSet(this, _draftNode, createCanvasNodeByType(this, type, node));
|
|
1388
|
+
__privateSet(this, _draftNode, createCanvasNodeByType(this, type, node, true));
|
|
1387
1389
|
if (!__privateGet(this, _draftNode)) return;
|
|
1388
1390
|
__privateGet(this, _mainLayer).add(__privateGet(this, _draftNode).getElement());
|
|
1389
1391
|
}
|
|
@@ -1586,6 +1588,14 @@ class CanvasApi extends CanvasCore {
|
|
|
1586
1588
|
createNodes(nodes) {
|
|
1587
1589
|
super.createNodes(nodes);
|
|
1588
1590
|
}
|
|
1591
|
+
/**
|
|
1592
|
+
* 根据 ID 获取节点
|
|
1593
|
+
*/
|
|
1594
|
+
getNodeById(id) {
|
|
1595
|
+
const nodes = this.getState().nodes || [];
|
|
1596
|
+
const node = nodes.find((n) => n.id === id);
|
|
1597
|
+
return node || null;
|
|
1598
|
+
}
|
|
1589
1599
|
/**
|
|
1590
1600
|
* 更新视口位置
|
|
1591
1601
|
*/
|
|
@@ -1670,6 +1680,42 @@ class CanvasApi extends CanvasCore {
|
|
|
1670
1680
|
transformer.visible(transformerVisible);
|
|
1671
1681
|
}
|
|
1672
1682
|
}
|
|
1683
|
+
/**
|
|
1684
|
+
* 导出带有标注的图片节点为图片
|
|
1685
|
+
* @param id - 图片节点 ID
|
|
1686
|
+
* @returns DataURL 格式的图片数据,如果节点不存在则返回 null
|
|
1687
|
+
*/
|
|
1688
|
+
exportImageWithMarker(id) {
|
|
1689
|
+
const imageShape = this.getStage().findOne(`#${id}`);
|
|
1690
|
+
if (!imageShape) {
|
|
1691
|
+
console.warn("Image shape not found on stage");
|
|
1692
|
+
return null;
|
|
1693
|
+
}
|
|
1694
|
+
const nodes = this.getState().nodes || [];
|
|
1695
|
+
const markerNodes = nodes.filter(
|
|
1696
|
+
(n) => n.type === "image-marker" && n.meta.parent === id
|
|
1697
|
+
);
|
|
1698
|
+
const tempGroup = new Konva.Group();
|
|
1699
|
+
const imageClone = imageShape.clone();
|
|
1700
|
+
tempGroup.add(imageClone);
|
|
1701
|
+
markerNodes.forEach((markerNode) => {
|
|
1702
|
+
const markerShape = this.getStage().findOne(`#${markerNode.id}`);
|
|
1703
|
+
if (markerShape) {
|
|
1704
|
+
const markerClone = markerShape.clone();
|
|
1705
|
+
tempGroup.add(markerClone);
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
const box = tempGroup.getClientRect();
|
|
1709
|
+
const dataURL = tempGroup.toDataURL({
|
|
1710
|
+
x: box.x,
|
|
1711
|
+
y: box.y,
|
|
1712
|
+
width: box.width,
|
|
1713
|
+
height: box.height,
|
|
1714
|
+
pixelRatio: 2
|
|
1715
|
+
});
|
|
1716
|
+
tempGroup.destroy();
|
|
1717
|
+
return dataURL;
|
|
1718
|
+
}
|
|
1673
1719
|
/**
|
|
1674
1720
|
* 删除当前选中的节点
|
|
1675
1721
|
* 如果删除的是 image 节点,会同步删除所有关联的 image-marker
|
package/dist/index.umd.js
CHANGED
|
@@ -71,6 +71,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
71
71
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
72
72
|
--color-red-500: oklch(63.7% .237 25.331);
|
|
73
73
|
--color-red-600: oklch(57.7% .245 27.325);
|
|
74
|
+
--color-orange-500: oklch(70.5% .213 47.604);
|
|
75
|
+
--color-orange-600: oklch(64.6% .222 41.116);
|
|
74
76
|
--color-green-500: oklch(72.3% .219 149.579);
|
|
75
77
|
--color-green-600: oklch(62.7% .194 149.214);
|
|
76
78
|
--color-cyan-500: oklch(71.5% .143 215.221);
|
|
@@ -660,6 +662,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
660
662
|
background-color: var(--color-indigo-500);
|
|
661
663
|
}
|
|
662
664
|
|
|
665
|
+
.bg-orange-500 {
|
|
666
|
+
background-color: var(--color-orange-500);
|
|
667
|
+
}
|
|
668
|
+
|
|
663
669
|
.bg-primary {
|
|
664
670
|
background-color: var(--primary);
|
|
665
671
|
}
|
|
@@ -837,6 +843,10 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
837
843
|
background-color: var(--color-indigo-600);
|
|
838
844
|
}
|
|
839
845
|
|
|
846
|
+
.hover\\:bg-orange-600:hover {
|
|
847
|
+
background-color: var(--color-orange-600);
|
|
848
|
+
}
|
|
849
|
+
|
|
840
850
|
.hover\\:bg-primary\\/90:hover {
|
|
841
851
|
background-color: var(--primary);
|
|
842
852
|
}
|
|
@@ -1829,12 +1839,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
1829
1839
|
MIN_SIZE: 10
|
|
1830
1840
|
};
|
|
1831
1841
|
class BaseCanvasNode {
|
|
1832
|
-
constructor(core, node) {
|
|
1842
|
+
constructor(core, node, isDraft = false) {
|
|
1833
1843
|
__publicField(this, "core");
|
|
1834
1844
|
__publicField(this, "node");
|
|
1835
1845
|
__publicField(this, "element");
|
|
1846
|
+
__publicField(this, "isDraft");
|
|
1836
1847
|
this.core = core;
|
|
1837
1848
|
this.node = node;
|
|
1849
|
+
this.isDraft = isDraft;
|
|
1838
1850
|
this.element = this.createElement();
|
|
1839
1851
|
}
|
|
1840
1852
|
/**
|
|
@@ -1857,8 +1869,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
1857
1869
|
};
|
|
1858
1870
|
}
|
|
1859
1871
|
class RectNode extends BaseCanvasNode {
|
|
1860
|
-
constructor(core, node) {
|
|
1861
|
-
super(core, node);
|
|
1872
|
+
constructor(core, node, isDraft = false) {
|
|
1873
|
+
super(core, node, isDraft);
|
|
1862
1874
|
__privateAdd(this, _RectNode_instances);
|
|
1863
1875
|
__privateAdd(this, _toolTypeChangeHandler, (toolType) => {
|
|
1864
1876
|
const isSelect = toolType === "select";
|
|
@@ -1983,8 +1995,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
1983
1995
|
});
|
|
1984
1996
|
};
|
|
1985
1997
|
class ImageNode extends BaseCanvasNode {
|
|
1986
|
-
constructor(core, node) {
|
|
1987
|
-
super(core, node);
|
|
1998
|
+
constructor(core, node, isDraft = false) {
|
|
1999
|
+
super(core, node, isDraft);
|
|
1988
2000
|
__privateAdd(this, _ImageNode_instances);
|
|
1989
2001
|
__privateAdd(this, _toolTypeChangeHandler2, (toolType) => {
|
|
1990
2002
|
const isSelect = toolType === "select";
|
|
@@ -2191,8 +2203,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2191
2203
|
});
|
|
2192
2204
|
};
|
|
2193
2205
|
class ImageMarkerNode extends BaseCanvasNode {
|
|
2194
|
-
constructor(core, node) {
|
|
2195
|
-
super(core, node);
|
|
2206
|
+
constructor(core, node, isDraft = false) {
|
|
2207
|
+
super(core, node, isDraft);
|
|
2196
2208
|
__privateAdd(this, _ImageMarkerNode_instances);
|
|
2197
2209
|
__privateAdd(this, _rect);
|
|
2198
2210
|
__privateAdd(this, _markerGroup);
|
|
@@ -2216,12 +2228,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2216
2228
|
);
|
|
2217
2229
|
const group = new Konva.Group({
|
|
2218
2230
|
id: this.node.id,
|
|
2219
|
-
name: `static ${this.node.meta.parent}`,
|
|
2231
|
+
name: `static ${this.node.meta.parent} imageMarker`,
|
|
2220
2232
|
x: this.node.props.x,
|
|
2221
2233
|
y: this.node.props.y,
|
|
2222
2234
|
width,
|
|
2223
|
-
height
|
|
2224
|
-
listening: false
|
|
2235
|
+
height
|
|
2225
2236
|
});
|
|
2226
2237
|
const rect = new Konva.Rect({
|
|
2227
2238
|
name: "rect",
|
|
@@ -2233,12 +2244,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2233
2244
|
strokeWidth: 2,
|
|
2234
2245
|
dash: [5, 5],
|
|
2235
2246
|
fill: "transparent",
|
|
2236
|
-
cornerRadius: RECT.CORNER_RADIUS
|
|
2247
|
+
cornerRadius: RECT.CORNER_RADIUS,
|
|
2248
|
+
listening: false
|
|
2237
2249
|
});
|
|
2238
2250
|
const markerGroup = new Konva.Group({
|
|
2239
2251
|
name: "marker-group",
|
|
2240
2252
|
x: width,
|
|
2241
|
-
y: height
|
|
2253
|
+
y: height,
|
|
2254
|
+
visible: this.isDraft ? false : true
|
|
2242
2255
|
});
|
|
2243
2256
|
const stageScale = this.core.getStageScale();
|
|
2244
2257
|
const radius = 16 / stageScale;
|
|
@@ -2325,7 +2338,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2325
2338
|
* 更新焦点状态(hover 或 selected)
|
|
2326
2339
|
*/
|
|
2327
2340
|
setFocusState(isFocus) {
|
|
2328
|
-
const strokeWidth = isFocus ?
|
|
2341
|
+
const strokeWidth = isFocus ? 4 : 2;
|
|
2329
2342
|
const scale = isFocus ? 1.2 : 1;
|
|
2330
2343
|
__privateGet(this, _rect).strokeWidth(strokeWidth);
|
|
2331
2344
|
__privateGet(this, _circle).strokeWidth(strokeWidth);
|
|
@@ -2356,14 +2369,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2356
2369
|
this.core.selectNode(this.node.id);
|
|
2357
2370
|
});
|
|
2358
2371
|
};
|
|
2359
|
-
function createCanvasNodeByType(core, type, config) {
|
|
2372
|
+
function createCanvasNodeByType(core, type, config, isDraft = false) {
|
|
2360
2373
|
switch (type) {
|
|
2361
2374
|
case "rectangle":
|
|
2362
|
-
return new RectNode(core, config);
|
|
2375
|
+
return new RectNode(core, config, isDraft);
|
|
2363
2376
|
case "image":
|
|
2364
|
-
return new ImageNode(core, config);
|
|
2377
|
+
return new ImageNode(core, config, isDraft);
|
|
2365
2378
|
case "image-marker":
|
|
2366
|
-
return new ImageMarkerNode(core, config);
|
|
2379
|
+
return new ImageMarkerNode(core, config, isDraft);
|
|
2367
2380
|
default:
|
|
2368
2381
|
return null;
|
|
2369
2382
|
}
|
|
@@ -2594,7 +2607,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2594
2607
|
__privateGet(this, _canvasTransformer).emitPositionChange();
|
|
2595
2608
|
}
|
|
2596
2609
|
createNodes(nodes) {
|
|
2597
|
-
const canvasNodes = nodes.map((node) => createCanvasNodeByType(this, node.type, node)).filter((node) => node !== null);
|
|
2610
|
+
const canvasNodes = nodes.map((node) => createCanvasNodeByType(this, node.type, node, false)).filter((node) => node !== null);
|
|
2598
2611
|
canvasNodes.forEach((node) => {
|
|
2599
2612
|
__privateGet(this, _mainLayer).add(node.getElement());
|
|
2600
2613
|
});
|
|
@@ -2665,26 +2678,25 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2665
2678
|
* @internal 仅供内部使用
|
|
2666
2679
|
*/
|
|
2667
2680
|
findImageAtPosition(position) {
|
|
2668
|
-
const layer = __privateGet(this, _mainLayer)
|
|
2669
|
-
const
|
|
2670
|
-
|
|
2681
|
+
const layer = __privateGet(this, _mainLayer);
|
|
2682
|
+
const shapes = layer.getChildren();
|
|
2683
|
+
const filteredShapes = shapes.filter(
|
|
2684
|
+
(shape) => !shape.name().includes("imageMarker")
|
|
2671
2685
|
);
|
|
2672
|
-
const
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2686
|
+
const sortedShapes = filteredShapes.slice().sort((a, b) => b.zIndex() - a.zIndex());
|
|
2687
|
+
for (const shape of sortedShapes) {
|
|
2688
|
+
const x = shape.x();
|
|
2689
|
+
const y = shape.y();
|
|
2690
|
+
const width = shape.width();
|
|
2691
|
+
const height = shape.height();
|
|
2692
|
+
if (position.x >= x && position.x <= x + width && position.y >= y && position.y <= y + height) {
|
|
2693
|
+
if (shape.getClassName() === "Image") {
|
|
2694
|
+
return shape;
|
|
2695
|
+
}
|
|
2696
|
+
return null;
|
|
2681
2697
|
}
|
|
2682
|
-
return null;
|
|
2683
|
-
} finally {
|
|
2684
|
-
imageShapes.forEach((shape, index) => {
|
|
2685
|
-
shape.listening(originalListeningStates[index]);
|
|
2686
|
-
});
|
|
2687
2698
|
}
|
|
2699
|
+
return null;
|
|
2688
2700
|
}
|
|
2689
2701
|
/**
|
|
2690
2702
|
* @internal 仅供内部使用
|
|
@@ -2694,7 +2706,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2694
2706
|
__privateGet(this, _draftNode).destroy();
|
|
2695
2707
|
}
|
|
2696
2708
|
const node = createNodeByType(type, position, void 0, meta);
|
|
2697
|
-
__privateSet(this, _draftNode, createCanvasNodeByType(this, type, node));
|
|
2709
|
+
__privateSet(this, _draftNode, createCanvasNodeByType(this, type, node, true));
|
|
2698
2710
|
if (!__privateGet(this, _draftNode)) return;
|
|
2699
2711
|
__privateGet(this, _mainLayer).add(__privateGet(this, _draftNode).getElement());
|
|
2700
2712
|
}
|
|
@@ -2897,6 +2909,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2897
2909
|
createNodes(nodes) {
|
|
2898
2910
|
super.createNodes(nodes);
|
|
2899
2911
|
}
|
|
2912
|
+
/**
|
|
2913
|
+
* 根据 ID 获取节点
|
|
2914
|
+
*/
|
|
2915
|
+
getNodeById(id) {
|
|
2916
|
+
const nodes = this.getState().nodes || [];
|
|
2917
|
+
const node = nodes.find((n) => n.id === id);
|
|
2918
|
+
return node || null;
|
|
2919
|
+
}
|
|
2900
2920
|
/**
|
|
2901
2921
|
* 更新视口位置
|
|
2902
2922
|
*/
|
|
@@ -2981,6 +3001,42 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
2981
3001
|
transformer.visible(transformerVisible);
|
|
2982
3002
|
}
|
|
2983
3003
|
}
|
|
3004
|
+
/**
|
|
3005
|
+
* 导出带有标注的图片节点为图片
|
|
3006
|
+
* @param id - 图片节点 ID
|
|
3007
|
+
* @returns DataURL 格式的图片数据,如果节点不存在则返回 null
|
|
3008
|
+
*/
|
|
3009
|
+
exportImageWithMarker(id) {
|
|
3010
|
+
const imageShape = this.getStage().findOne(`#${id}`);
|
|
3011
|
+
if (!imageShape) {
|
|
3012
|
+
console.warn("Image shape not found on stage");
|
|
3013
|
+
return null;
|
|
3014
|
+
}
|
|
3015
|
+
const nodes = this.getState().nodes || [];
|
|
3016
|
+
const markerNodes = nodes.filter(
|
|
3017
|
+
(n) => n.type === "image-marker" && n.meta.parent === id
|
|
3018
|
+
);
|
|
3019
|
+
const tempGroup = new Konva.Group();
|
|
3020
|
+
const imageClone = imageShape.clone();
|
|
3021
|
+
tempGroup.add(imageClone);
|
|
3022
|
+
markerNodes.forEach((markerNode) => {
|
|
3023
|
+
const markerShape = this.getStage().findOne(`#${markerNode.id}`);
|
|
3024
|
+
if (markerShape) {
|
|
3025
|
+
const markerClone = markerShape.clone();
|
|
3026
|
+
tempGroup.add(markerClone);
|
|
3027
|
+
}
|
|
3028
|
+
});
|
|
3029
|
+
const box = tempGroup.getClientRect();
|
|
3030
|
+
const dataURL = tempGroup.toDataURL({
|
|
3031
|
+
x: box.x,
|
|
3032
|
+
y: box.y,
|
|
3033
|
+
width: box.width,
|
|
3034
|
+
height: box.height,
|
|
3035
|
+
pixelRatio: 2
|
|
3036
|
+
});
|
|
3037
|
+
tempGroup.destroy();
|
|
3038
|
+
return dataURL;
|
|
3039
|
+
}
|
|
2984
3040
|
/**
|
|
2985
3041
|
* 删除当前选中的节点
|
|
2986
3042
|
* 如果删除的是 image 节点,会同步删除所有关联的 image-marker
|