drawui-core 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -3
- package/dist/icons-catalog-LG6WL446.cjs +4 -0
- package/dist/icons-catalog-TDWDJPEW.js +4 -0
- package/dist/index.cjs +41 -32
- package/dist/index.d.cts +255 -20
- package/dist/index.d.ts +255 -20
- package/dist/index.js +41 -32
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -80,6 +80,13 @@ interface HexagonShape extends BaseShape {
|
|
|
80
80
|
type: 'hexagon';
|
|
81
81
|
width: number;
|
|
82
82
|
height: number;
|
|
83
|
+
/**
|
|
84
|
+
* 六边形朝向(缺省 `'pointy'`,老文档行为不变):
|
|
85
|
+
* - `'pointy'`:上下为尖、左右为竖边(原行为)
|
|
86
|
+
* - `'flat'`:上下为平边、左右为尖 —— 蜂窝图要用这个,
|
|
87
|
+
* 它的六个邻居正好落在 30°/90°/150°/210°/270°/330°,上下左右都能拼上。
|
|
88
|
+
*/
|
|
89
|
+
orientation?: 'pointy' | 'flat';
|
|
83
90
|
}
|
|
84
91
|
interface ParallelogramShape extends BaseShape {
|
|
85
92
|
type: 'parallelogram';
|
|
@@ -90,6 +97,13 @@ interface TrapezoidShape extends BaseShape {
|
|
|
90
97
|
type: 'trapezoid';
|
|
91
98
|
width: number;
|
|
92
99
|
height: number;
|
|
100
|
+
/**
|
|
101
|
+
* 上边每侧内缩的距离(页面单位)。缺省 = `width * 0.15`(老文档行为不变)。
|
|
102
|
+
*
|
|
103
|
+
* 用来堆金字塔:每层给出精确的缩进量,侧边才能连成**同一条斜线**;
|
|
104
|
+
* 靠默认的 15% 比例会让每层斜率各不相同,堆起来像歪的楼梯。
|
|
105
|
+
*/
|
|
106
|
+
topInset?: number;
|
|
93
107
|
}
|
|
94
108
|
interface PentagonShape extends BaseShape {
|
|
95
109
|
type: 'pentagon';
|
|
@@ -239,6 +253,10 @@ interface LineShape extends BaseShape {
|
|
|
239
253
|
start: Vec2;
|
|
240
254
|
end: Vec2;
|
|
241
255
|
};
|
|
256
|
+
/** 手工艺状态的自动走线基线(见 ArrowShape.userPointsBase) */
|
|
257
|
+
userPointsBase?: Vec2[];
|
|
258
|
+
/** 纯装饰线(见 ArrowShape.freeform) */
|
|
259
|
+
freeform?: boolean;
|
|
242
260
|
}
|
|
243
261
|
type ConnectionType = 'straight' | 'polyline' | 'orthogonal' | 'curve';
|
|
244
262
|
/** 生成点位创建上下文:from 为源点(生成点位),to 为目标落点 */
|
|
@@ -328,6 +346,22 @@ interface ArrowShape extends BaseShape {
|
|
|
328
346
|
start: Vec2;
|
|
329
347
|
end: Vec2;
|
|
330
348
|
};
|
|
349
|
+
/**
|
|
350
|
+
* 写下手工艺状态那一刻的**自动走线**(世界坐标,含两端)。
|
|
351
|
+
*
|
|
352
|
+
* 只用来判断手工折点是否已经过期:自动走线的形状签名(折点数 + 首末段轴向)只由布局决定,
|
|
353
|
+
* 一旦当前自动走线的签名和这里记的不一样,说明「当初为了绕开什么而折」的前提没了 ——
|
|
354
|
+
* 这时折点只会让线凭空多绕一圈(见 connectorEdit.userPointsAreStale)。
|
|
355
|
+
*/
|
|
356
|
+
userPointsBase?: Vec2[];
|
|
357
|
+
/**
|
|
358
|
+
* 纯装饰线/箭头:**不把端点吸附到附近图形的轮廓上**。
|
|
359
|
+
*
|
|
360
|
+
* 模板里的分隔线、网格线、肋骨、标注线往往是**故意画在容器图形内部**的;
|
|
361
|
+
* 默认的「端点落进图形就吸到轮廓」会把它们拽到容器边上(画布上看是"线自己跑了"),
|
|
362
|
+
* 而且导出侧从不做这个吸附 → 画布与导出还会对不上。
|
|
363
|
+
*/
|
|
364
|
+
freeform?: boolean;
|
|
331
365
|
}
|
|
332
366
|
interface TextShape extends BaseShape {
|
|
333
367
|
type: 'text';
|
|
@@ -673,11 +707,11 @@ declare const zhCN: {
|
|
|
673
707
|
readonly 'toolbar.grid': "网格";
|
|
674
708
|
readonly 'toolbar.undo': "撤销 (Ctrl+Z)";
|
|
675
709
|
readonly 'toolbar.redo': "重做 (Ctrl+Shift+Z)";
|
|
676
|
-
readonly 'toolbar.arrow': "箭头";
|
|
677
|
-
readonly 'toolbar.text': "文本";
|
|
710
|
+
readonly 'toolbar.arrow': "箭头 (A)";
|
|
711
|
+
readonly 'toolbar.text': "文本 (T)";
|
|
678
712
|
readonly 'toolbar.pen': "画笔";
|
|
679
713
|
readonly 'toolbar.highlighter': "荧光笔";
|
|
680
|
-
readonly 'toolbar.eraser': "橡皮擦";
|
|
714
|
+
readonly 'toolbar.eraser': "橡皮擦 (E)";
|
|
681
715
|
readonly 'toolbar.uml-class': "UML 类图";
|
|
682
716
|
readonly 'toolbar.uml-interface': "UML 接口";
|
|
683
717
|
readonly 'zoom.in': "放大";
|
|
@@ -698,7 +732,7 @@ declare const zhCN: {
|
|
|
698
732
|
readonly 'style.solid': "实线";
|
|
699
733
|
readonly 'style.opacity': "不透明度";
|
|
700
734
|
readonly 'style.connection.straight': "直线";
|
|
701
|
-
readonly 'style.connection.polyline': "
|
|
735
|
+
readonly 'style.connection.polyline': "圆角折线";
|
|
702
736
|
readonly 'style.connection.orthogonal': "直角折线";
|
|
703
737
|
readonly 'style.connection.curve': "曲线";
|
|
704
738
|
readonly 'style.arrowhead.none': "无箭头";
|
|
@@ -788,7 +822,6 @@ declare const zhCN: {
|
|
|
788
822
|
readonly 'table.insertColRight': "在右侧插入列";
|
|
789
823
|
readonly 'table.pickHint': "拖选行列数";
|
|
790
824
|
readonly 'ctx.copy': "复制";
|
|
791
|
-
readonly 'ctx.copyAsImage': "复制为图片";
|
|
792
825
|
readonly 'ctx.paste': "粘贴";
|
|
793
826
|
readonly 'ctx.duplicate': "创建副本";
|
|
794
827
|
readonly 'ctx.layer': "层级";
|
|
@@ -806,8 +839,13 @@ declare const zhCN: {
|
|
|
806
839
|
readonly 'ctx.ungroup': "解组";
|
|
807
840
|
readonly 'ctx.lock': "锁定";
|
|
808
841
|
readonly 'ctx.unlock': "解锁";
|
|
842
|
+
readonly 'ctx.unlockAll': "全部解锁";
|
|
809
843
|
readonly 'ctx.delete': "删除";
|
|
810
|
-
readonly 'toolbar.icon': "图标";
|
|
844
|
+
readonly 'toolbar.icon': "图标 (S)";
|
|
845
|
+
readonly 'toolbar.template': "模板";
|
|
846
|
+
readonly 'template.search': "搜索模板";
|
|
847
|
+
readonly 'template.all': "全部";
|
|
848
|
+
readonly 'template.empty': "没有匹配的模板";
|
|
811
849
|
readonly 'toolbar.image': "图片";
|
|
812
850
|
readonly 'toolbar.more': "更多";
|
|
813
851
|
readonly 'toolbar.pageTheme': "页面主题";
|
|
@@ -835,6 +873,7 @@ declare const zhCN: {
|
|
|
835
873
|
readonly 'iconCat.arrow': "箭头方向";
|
|
836
874
|
readonly 'iconCat.misc': "常用";
|
|
837
875
|
readonly 'iconCat.emoji': "表情";
|
|
876
|
+
readonly 'iconCat.sticker': "贴纸";
|
|
838
877
|
readonly 'iconCat.device': "电脑设备";
|
|
839
878
|
readonly 'iconCat.weather': "天气";
|
|
840
879
|
readonly 'iconCat.transport': "交通";
|
|
@@ -859,12 +898,24 @@ declare function t(key: MessageKey, params?: Record<string, string | number>): s
|
|
|
859
898
|
|
|
860
899
|
type ExportFormat = 'png' | 'svg' | 'pdf';
|
|
861
900
|
interface ExportOptions {
|
|
862
|
-
/**
|
|
901
|
+
/**
|
|
902
|
+
* 输出缩放倍数(仅位图 PNG 生效,默认 2,矢量 SVG 始终无损)。
|
|
903
|
+
* 语义:内容 1 个页面单位 → 输出 scale 个设备像素(就是最终图与内容的尺寸比)。
|
|
904
|
+
*/
|
|
863
905
|
scale?: number;
|
|
864
906
|
/** 内容四周留白(页面坐标,默认 24) */
|
|
865
907
|
padding?: number;
|
|
866
908
|
/** 背景色,null = 透明;不传默认白色('#ffffff') */
|
|
867
909
|
background?: string | null;
|
|
910
|
+
/**
|
|
911
|
+
* 输出最长边的像素上限(默认不限制)。超过时按比例压低 scale,**保证整幅内容完整、不裁切**。
|
|
912
|
+
*
|
|
913
|
+
* 缩略图 / 预览图这类"显示尺寸远小于内容尺寸"的场景务必传:
|
|
914
|
+
* 内容跨度大时(把一个图形拖到几千像素外)输出画布面积会平方增长,
|
|
915
|
+
* 不仅编码要几百毫秒,还会触及浏览器 canvas 面积上限(Chrome 约 16384×16384,
|
|
916
|
+
* 约 2.68 亿像素 / 1GB),超限后 toDataURL 直接返回 `data:,` —— 图变空白。
|
|
917
|
+
*/
|
|
918
|
+
maxSize?: number;
|
|
868
919
|
}
|
|
869
920
|
/** 计算所有图形的并集包围盒(含留白),用于导出画布尺寸与视口 */
|
|
870
921
|
declare function getContentBounds(shapes: Shape[], padding?: number): {
|
|
@@ -1066,7 +1117,20 @@ declare class Editor {
|
|
|
1066
1117
|
private genPreview;
|
|
1067
1118
|
private hoverAnchorShapeId;
|
|
1068
1119
|
private hoverConnectorId;
|
|
1120
|
+
/**
|
|
1121
|
+
* 悬停中的**锁定**图形:锁标记不再常驻(一屏三把锁比锁本身更吵),
|
|
1122
|
+
* 只在指针落在这个锁定图形上时才亮出来 —— 顺带告诉用户「它为什么点不动」,
|
|
1123
|
+
* 而且那枚锁是可以直接点开解锁的(见 pointerdown 里的锁徽标命中)。
|
|
1124
|
+
*/
|
|
1125
|
+
private hoverLockedShapeId;
|
|
1069
1126
|
private eraserPoint;
|
|
1127
|
+
/**
|
|
1128
|
+
* 橡皮擦「渐隐」中的图形:id → 开始时间戳。
|
|
1129
|
+
* 命中后不立刻从 shapes 里删掉,而是先让不透明度在 ERASE_FADE_MS 内降到 0,
|
|
1130
|
+
* 到点再真正移除(这样擦除是「变浅 → 消失」而不是「啪一下不见」)。
|
|
1131
|
+
*/
|
|
1132
|
+
private eraseFades;
|
|
1133
|
+
private eraseFadeRaf;
|
|
1070
1134
|
private mindMapEditingShapeId;
|
|
1071
1135
|
private mindMapSelectedNode;
|
|
1072
1136
|
private mindMapHoverNode;
|
|
@@ -1147,6 +1211,17 @@ declare class Editor {
|
|
|
1147
1211
|
private handlePointerUp;
|
|
1148
1212
|
/** 根据当前工具的命中结果更新鼠标样式(伸缩手柄↔/↕、拖拽 grabbing 等) */
|
|
1149
1213
|
private updateCursor;
|
|
1214
|
+
/**
|
|
1215
|
+
* 锁定图形的悬停跟踪:只有悬停中的锁定图形才亮出锁徽标(默认不画,见 Renderer.visibleLockBadges)。
|
|
1216
|
+
*
|
|
1217
|
+
* 除了"指针在图形上",还要认"指针在锁徽标上" —— 徽标压在包围盒外侧,
|
|
1218
|
+
* 指针移过去的瞬间已经离开了图形本身,不认就会闪掉、点不到。
|
|
1219
|
+
*/
|
|
1220
|
+
private updateLockHover;
|
|
1221
|
+
/** 命中「锁徽标」(世界坐标点);返回要解锁的目标。命中范围比视觉上略大一圈,好点 */
|
|
1222
|
+
private lockBadgeAtPoint;
|
|
1223
|
+
/** 点锁徽标 → 解锁(组锁整组解),一步撤销 */
|
|
1224
|
+
private unlockFromBadge;
|
|
1150
1225
|
/**
|
|
1151
1226
|
* 滚轮:普通滚动平移视口(内容跟随常规滚动方向),
|
|
1152
1227
|
* Ctrl/Cmd + 滚轮以光标为中心缩放,Shift + 滚轮水平平移。
|
|
@@ -1156,7 +1231,24 @@ declare class Editor {
|
|
|
1156
1231
|
private handleKeyUp;
|
|
1157
1232
|
private handleResize;
|
|
1158
1233
|
private screenToPage;
|
|
1234
|
+
/**
|
|
1235
|
+
* 插入一组图形(模板库的落地入口)。
|
|
1236
|
+
*
|
|
1237
|
+
* - 模板坐标是「相对自己的中心」,这里整体平移到**当前视口中心**,插到用户正在看的地方;
|
|
1238
|
+
* - 整批插入只打**一个**历史快照,撤销一次就整块拿掉;
|
|
1239
|
+
* - 插入后自动选中这批图形,用户可以直接拖动/改样式;
|
|
1240
|
+
* - 连线要平移 `points`(`shape.x/y` 对连线只是渲染原点,平移它视觉上不动)。
|
|
1241
|
+
*/
|
|
1242
|
+
insertTemplate(shapes: Shape[]): void;
|
|
1159
1243
|
private addShape;
|
|
1244
|
+
/**
|
|
1245
|
+
* 文档里出现了「大目录」里的图标(表情/贴纸/补充图标)就把它拉回来,回来后重绘一次。
|
|
1246
|
+
*
|
|
1247
|
+
* 图标目录是懒加载的:首包只带手绘线稿那部分。打开一份含表情的文档时,
|
|
1248
|
+
* 第一次渲染会短暂缺图 —— 这里补一次加载,加载完 requestRender 补画上。
|
|
1249
|
+
* 全部图标都在首包时 `ensureIcons` 是纯同步空转,不会产生任何网络请求。
|
|
1250
|
+
*/
|
|
1251
|
+
private prefetchShapeIcons;
|
|
1160
1252
|
private updateShape;
|
|
1161
1253
|
/**
|
|
1162
1254
|
* 表格尺寸变化时保持「左上角」不动:行高变化向下伸缩、列宽变化向右伸缩,
|
|
@@ -1170,6 +1262,20 @@ declare class Editor {
|
|
|
1170
1262
|
private updateBoundArrows;
|
|
1171
1263
|
private getBindingPosition;
|
|
1172
1264
|
private deleteShape;
|
|
1265
|
+
/**
|
|
1266
|
+
* 橡皮擦命中:图形先进入「渐隐」再被真正删除(见 eraseFades)。
|
|
1267
|
+
* 历史快照在拖拽开始时已经打过,所以整段擦除仍然只占一个撤销点。
|
|
1268
|
+
*/
|
|
1269
|
+
private eraseShape;
|
|
1270
|
+
/** 渐隐时钟:每帧推进,到点的图形才真正删除;整批结束后停表 */
|
|
1271
|
+
private tickEraseFade;
|
|
1272
|
+
/** 当前帧各渐隐图形的不透明度(0~1);没有渐隐时返回 undefined,避免每帧建 Map */
|
|
1273
|
+
private eraseFadeMap;
|
|
1274
|
+
/**
|
|
1275
|
+
* 丢弃所有未完成的渐隐(撤销 / 重做 / 整体换数据时调用)。
|
|
1276
|
+
* 否则「撤销把图形救回来 → 渐隐计时器到点又把它删掉」会凭空吃掉一次撤销。
|
|
1277
|
+
*/
|
|
1278
|
+
private clearEraseFades;
|
|
1173
1279
|
/**
|
|
1174
1280
|
* 选中图形(additive=true 时切换选中态);id 为空串清空选中。右键菜单/外部控制用。
|
|
1175
1281
|
* ⚠️ 组感知:点任一成员都会选中它所属的整组(同组的绑行为一致),additive 时整组一起加减。
|
|
@@ -1177,6 +1283,15 @@ declare class Editor {
|
|
|
1177
1283
|
selectShape(id: string, additive: boolean): void;
|
|
1178
1284
|
/** 整体替换选中集(右键菜单/外部控制用);框选结果同样按组扩张 */
|
|
1179
1285
|
selectShapes(ids: string[]): void;
|
|
1286
|
+
/**
|
|
1287
|
+
* 全选(Ctrl/Cmd + A):选中画布上所有图形。
|
|
1288
|
+
*
|
|
1289
|
+
* 锁定图形**跳过** —— 它们本来就不接受选中(点不中、拖不动),
|
|
1290
|
+
* 混进选区只会让「删除/移动/改样式」这些操作对它们做无用功,
|
|
1291
|
+
* 还会让状态栏的「已选 N 个」数字对不上能操作的图形数。
|
|
1292
|
+
* 要处理锁定的图形,先解锁(悬停点锁 / 右键解锁 / 空白右键「全部解锁」)。
|
|
1293
|
+
*/
|
|
1294
|
+
selectAll(): boolean;
|
|
1180
1295
|
/** 某图形所在的整组 id 列表(不在组里就只有它自己) */
|
|
1181
1296
|
private getGroupMembers;
|
|
1182
1297
|
/** 选中集是否恰好是完整的一个组(返回 groupId,否则 null) */
|
|
@@ -1312,6 +1427,14 @@ declare class Editor {
|
|
|
1312
1427
|
setShapeLocked(id: string, locked: boolean): boolean;
|
|
1313
1428
|
/** 某个图形是否被锁定 */
|
|
1314
1429
|
isShapeLocked(id: string): boolean;
|
|
1430
|
+
/** 画布上是否存在锁定图形(右键菜单决定要不要显示「全部解锁」) */
|
|
1431
|
+
hasLockedShapes(): boolean;
|
|
1432
|
+
/**
|
|
1433
|
+
* 全部解锁(一步撤销)。
|
|
1434
|
+
* 兜底入口:锁定的图形点不中、框选也框不中,如果用户忘了自己锁过什么、
|
|
1435
|
+
* 或者锁的量比较多,挨个悬停点锁太麻烦 —— 空白处右键就能一次清掉。
|
|
1436
|
+
*/
|
|
1437
|
+
unlockAll(): boolean;
|
|
1315
1438
|
/** 置于顶层:选中的图形整体移到最上面(保持它们之间的相对顺序) */
|
|
1316
1439
|
bringToFront(): boolean;
|
|
1317
1440
|
/** 置于底层:选中的图形整体移到最下面 */
|
|
@@ -1774,6 +1897,8 @@ declare class Editor {
|
|
|
1774
1897
|
private getShapeScreenBounds;
|
|
1775
1898
|
getShapeAtScreenPoint(screenPoint: Vec2): Shape | null;
|
|
1776
1899
|
getShapeAtPoint(point: Vec2, excludeId?: string): Shape | null;
|
|
1900
|
+
/** 点是否落在连线的**实际走线**上(与画面一致:含出/入桩、绕行、手工折点) */
|
|
1901
|
+
private isPointOnConnector;
|
|
1777
1902
|
/** 橡皮擦:返回与圆形笔刷相交的所有图形(不含线条的命中由其线段距离判定) */
|
|
1778
1903
|
getShapesInBrushRadius(point: Vec2, radius: number): Shape[];
|
|
1779
1904
|
private shapeIntersectsBrush;
|
|
@@ -1877,6 +2002,19 @@ interface SnapGuide {
|
|
|
1877
2002
|
start: number;
|
|
1878
2003
|
end: number;
|
|
1879
2004
|
}
|
|
2005
|
+
/** 一枚锁徽标(世界坐标矩形 + 点击它要解锁的目标)—— 绘制与命中共用 */
|
|
2006
|
+
interface LockBadgeTarget {
|
|
2007
|
+
x: number;
|
|
2008
|
+
y: number;
|
|
2009
|
+
/** 边长(屏幕 20px 换算到世界单位) */
|
|
2010
|
+
size: number;
|
|
2011
|
+
/** 单图形锁定:解锁它本身 */
|
|
2012
|
+
shapeId?: string;
|
|
2013
|
+
/** 组锁定:解锁整组 */
|
|
2014
|
+
groupId?: string;
|
|
2015
|
+
/** 组锁的所有成员 id(用于判断"悬停/选中是否在这个组上") */
|
|
2016
|
+
memberIds: string[];
|
|
2017
|
+
}
|
|
1880
2018
|
declare class Renderer {
|
|
1881
2019
|
private ctx;
|
|
1882
2020
|
private width;
|
|
@@ -1901,6 +2039,11 @@ declare class Renderer {
|
|
|
1901
2039
|
} | null): void;
|
|
1902
2040
|
/** 当前悬停的图形 id(由每帧 render 写入),仅用于表格拖动把手等提示性绘制 */
|
|
1903
2041
|
private hoverShapeId;
|
|
2042
|
+
/**
|
|
2043
|
+
* 本帧是否是「多选」(选中集 > 1)。多选时每个图形只描发丝轮廓、不再画手柄,
|
|
2044
|
+
* 手柄收敛到整体范围框上(见 drawMultiSelectionBounds)。
|
|
2045
|
+
*/
|
|
2046
|
+
private multiSelection;
|
|
1904
2047
|
private static readonly TEXT_CACHE_LIMIT;
|
|
1905
2048
|
constructor(canvas: HTMLCanvasElement, dpr?: number);
|
|
1906
2049
|
resize(width: number, height: number): void;
|
|
@@ -1930,7 +2073,9 @@ declare class Renderer {
|
|
|
1930
2073
|
/** 悬停的图形 id:为其绘制四边连接锚点(飞书式悬浮提示),已选中图形由选择手柄负责 */
|
|
1931
2074
|
hoverAnchorShapeId?: string | null,
|
|
1932
2075
|
/** 悬停的连线 id:整条线描一层浅蓝高亮(提示「这条线可点、点开能调线段」) */
|
|
1933
|
-
hoverConnectorId?: string | null
|
|
2076
|
+
hoverConnectorId?: string | null,
|
|
2077
|
+
/** 橡皮擦渐隐:图形 id → 不透明度(0~1)。缺省时不改任何图形的透明度 */
|
|
2078
|
+
eraseFade?: Map<string, number> | null): void;
|
|
1934
2079
|
/** 橡皮擦:半透明主色圆 + 主色描边,半径与笔刷命中范围一致(屏幕像素恒定) */
|
|
1935
2080
|
private drawEraserBrush;
|
|
1936
2081
|
/** 连接进行中,高亮目标图形四边中点的可连锚点 */
|
|
@@ -2052,6 +2197,14 @@ declare class Renderer {
|
|
|
2052
2197
|
getConnectorRoute(shape: Shape, shapeMap: Map<string, Shape>, options?: {
|
|
2053
2198
|
ignoreUserPoints?: boolean;
|
|
2054
2199
|
}): Vec2[];
|
|
2200
|
+
/**
|
|
2201
|
+
* 连线最终走线(世界坐标)+ 生效的连线类型 —— **绘制、命中、导出判定都走这里**。
|
|
2202
|
+
*
|
|
2203
|
+
* 手工折点会先过一道「过期检查」(connectorEdit.userPointsAreStale):
|
|
2204
|
+
* 走线压到自己连的图形、或者布局已经变到自动走线的形状都不一样了,就丢弃手工折点。
|
|
2205
|
+
* 这样「旧布局下绕出来的大回环」不会跟着图形被带进新布局,默认永远是最少突兀的那条线。
|
|
2206
|
+
*/
|
|
2207
|
+
private connectorWorldPath;
|
|
2055
2208
|
/**
|
|
2056
2209
|
* 选中连线时:在每段(够长的)线段中点画一个可拖动的小手柄(飞书式「拖线段调位置」)。
|
|
2057
2210
|
* 拖动交互在 SelectTool 的 'dragging-segment' 状态里。
|
|
@@ -2194,16 +2347,22 @@ declare class Renderer {
|
|
|
2194
2347
|
private drawText;
|
|
2195
2348
|
private drawFreehand;
|
|
2196
2349
|
/**
|
|
2197
|
-
*
|
|
2198
|
-
*
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
*
|
|
2203
|
-
*
|
|
2204
|
-
*
|
|
2205
|
-
*/
|
|
2206
|
-
|
|
2350
|
+
* 当前**可见**的锁标记(世界坐标矩形 + 解锁目标)。
|
|
2351
|
+
*
|
|
2352
|
+
* 绘制与「点锁解锁」的命中共用这一份 —— 看到哪就能点到哪,不会出现"看不见却能点"。
|
|
2353
|
+
*
|
|
2354
|
+
* 为什么不再给每个锁定图形常驻画一把锁:一条流程图里锁三个图形就冒出三把锁,
|
|
2355
|
+
* 满屏徽标比锁本身更干扰。现在只在**需要解释的时候**出现:
|
|
2356
|
+
* 指针悬停在这个锁定图形上,或它刚被右键选中(右键是选中锁定图形的入口)。
|
|
2357
|
+
* 组锁仍然整组一把(挂在组包围盒顶部居中),条件同上:悬停/选中任一成员。
|
|
2358
|
+
*/
|
|
2359
|
+
visibleLockBadges(shapes: Shape[], selectedIds: Set<string>, zoom: number): LockBadgeTarget[];
|
|
2360
|
+
/** 所有「锁定图形」的徽标位置(不考虑是否显示)—— 命中测试与悬停判定用 */
|
|
2361
|
+
lockBadgeTargets(shapes: Shape[], zoom: number): LockBadgeTarget[];
|
|
2362
|
+
private allLockBadges;
|
|
2363
|
+
/** 悬停的锁定图形 id(由 Editor 在指针移动时写入):只有它才会亮出锁徽标 */
|
|
2364
|
+
private lockHoverId;
|
|
2365
|
+
setLockHover(id: string | null): void;
|
|
2207
2366
|
/** 在指定位置(徽标左上角,世界坐标)画一枚挂锁徽标 */
|
|
2208
2367
|
private drawLockBadgeAt;
|
|
2209
2368
|
/**
|
|
@@ -2211,6 +2370,13 @@ declare class Renderer {
|
|
|
2211
2370
|
* 提示「这些图形是绑在一起的」。整组锁定的成员画不到(成员不可选),不需要外框。
|
|
2212
2371
|
*/
|
|
2213
2372
|
private drawGroupFrames;
|
|
2373
|
+
/**
|
|
2374
|
+
* 多选时每个图形的「发丝轮廓」:1px、不填充、不画任何手柄。
|
|
2375
|
+
* 目的是告诉用户「这个也在选区里」,而不是喧宾夺主。
|
|
2376
|
+
*/
|
|
2377
|
+
private drawMultiSelectOutline;
|
|
2378
|
+
/** 多选的整体范围框:一个蓝框圈住全部选中图形(不带手柄) */
|
|
2379
|
+
private drawMultiSelectionBounds;
|
|
2214
2380
|
private drawSelectionOutline;
|
|
2215
2381
|
private drawSelectionHandles;
|
|
2216
2382
|
/**
|
|
@@ -2286,7 +2452,7 @@ declare const ICON_CATEGORIES: {
|
|
|
2286
2452
|
id: IconCategoryId;
|
|
2287
2453
|
labelKey: MessageKey;
|
|
2288
2454
|
}[];
|
|
2289
|
-
type IconCategoryId = 'status' | 'number' | 'emoji' | 'device' | 'tech' | 'chart' | 'office' | 'media' | 'arrow' | 'misc' | 'weather' | 'transport' | 'nature' | 'building' | 'medical' | 'shopping' | 'science' | 'animal' | 'time' | 'edit' | 'food' | 'communication';
|
|
2455
|
+
type IconCategoryId = 'status' | 'number' | 'emoji' | 'sticker' | 'device' | 'tech' | 'chart' | 'office' | 'media' | 'arrow' | 'misc' | 'weather' | 'transport' | 'nature' | 'building' | 'medical' | 'shopping' | 'science' | 'animal' | 'time' | 'edit' | 'food' | 'communication';
|
|
2290
2456
|
interface IconLayer {
|
|
2291
2457
|
/** 24×24 网格内的路径(语法同 SVG path,统一大写指令) */
|
|
2292
2458
|
d: string;
|
|
@@ -2323,6 +2489,20 @@ interface IconDef {
|
|
|
2323
2489
|
};
|
|
2324
2490
|
}
|
|
2325
2491
|
declare const ICONS: IconDef[];
|
|
2492
|
+
/** 大目录是否已并入(同步查询) */
|
|
2493
|
+
declare function isIconCatalogLoaded(): boolean;
|
|
2494
|
+
/**
|
|
2495
|
+
* 加载大目录。可重复调用(共享同一个 Promise);失败会重置状态,允许下次重试。
|
|
2496
|
+
* 宿主一般不用直接调 —— 图标面板与 `Editor` 会自动触发。
|
|
2497
|
+
*/
|
|
2498
|
+
declare function loadIconCatalog(): Promise<void>;
|
|
2499
|
+
/**
|
|
2500
|
+
* 预取一批图标(通常是文档里出现过的 iconId)。
|
|
2501
|
+
*
|
|
2502
|
+
* 全部已在首包里时**不会触发任何加载**,所以「没有表情/贴纸」的文档完全不受影响;
|
|
2503
|
+
* 只要有一个不认识,就说明文档用了大目录里的图标,此时整份目录拉一次(浏览器会缓存)。
|
|
2504
|
+
*/
|
|
2505
|
+
declare function ensureIcons(ids: Iterable<string>): Promise<void>;
|
|
2326
2506
|
declare function getIcon(id: string): IconDef | undefined;
|
|
2327
2507
|
/** 存在该 id 的图标(写入图形/读文档时校验,避免引用到不存在的图标) */
|
|
2328
2508
|
declare function hasIcon(id: string): boolean;
|
|
@@ -2349,6 +2529,39 @@ declare const ICON_CATEGORY_INK: Record<IconCategoryId, string>;
|
|
|
2349
2529
|
/** 取某个图标的默认墨色:图标自带 ink 优先(全彩贴纸),否则用分类主色,最后退回全局默认 */
|
|
2350
2530
|
declare function iconInk(icon: IconDef): string;
|
|
2351
2531
|
|
|
2532
|
+
/**
|
|
2533
|
+
* 内置模板库(数据层,不含 UI)。
|
|
2534
|
+
*
|
|
2535
|
+
* 设计约定(每一条都踩过坑):
|
|
2536
|
+
* - `build()` **现场生成**图形,不共享可变数组 —— 否则插两次会复用同一批 id。
|
|
2537
|
+
* - 坐标是**相对模板中心**的,插入时整体平移到视口中心;`x/y` 是**图形中心**。
|
|
2538
|
+
* - **连线段必须绑定到图形**(`startBinding`/`endBinding`)。不绑的话拖动盒子线不动,
|
|
2539
|
+
* 整个模板当场散架。走线交给路由算法(同一侧引出的多条线会自动共用主干)。
|
|
2540
|
+
* - 一个视觉整体由多个图形拼成时(表头+字段行、卡片+按钮),用 `groupId` 绑成组,
|
|
2541
|
+
* 拖动才会整块走。
|
|
2542
|
+
* - 想要「只有字、没有框」必须用 `type: 'text'`:`strokeWidth: 0` 并不会去掉矩形边框。
|
|
2543
|
+
* - 想加模板:往 `TEMPLATES` 里加一项,UI 与搜索会自动带上。
|
|
2544
|
+
*/
|
|
2545
|
+
type TemplateCategoryId = 'flow' | 'org' | 'analysis' | 'plan' | 'uml' | 'tech';
|
|
2546
|
+
declare const TEMPLATE_CATEGORIES: {
|
|
2547
|
+
id: TemplateCategoryId;
|
|
2548
|
+
zh: string;
|
|
2549
|
+
en: string;
|
|
2550
|
+
}[];
|
|
2551
|
+
interface TemplateDef {
|
|
2552
|
+
id: string;
|
|
2553
|
+
cat: TemplateCategoryId;
|
|
2554
|
+
zh: string;
|
|
2555
|
+
en: string;
|
|
2556
|
+
/** 搜索关键词(中英混排,空格分词) */
|
|
2557
|
+
kw: string;
|
|
2558
|
+
build: () => Shape[];
|
|
2559
|
+
}
|
|
2560
|
+
declare const TEMPLATES: TemplateDef[];
|
|
2561
|
+
declare function templateById(id: string): TemplateDef | undefined;
|
|
2562
|
+
/** 搜索模板:中/英文名 + 关键词,空格分词全部命中 */
|
|
2563
|
+
declare function searchTemplates(query: string): TemplateDef[];
|
|
2564
|
+
|
|
2352
2565
|
/**
|
|
2353
2566
|
* 画板范围(Board Extent)—— 宿主用来决定「画板这块 DOM / 可滚区域该多大」。
|
|
2354
2567
|
*
|
|
@@ -2423,8 +2636,16 @@ interface ToolContext {
|
|
|
2423
2636
|
addShape(shape: Shape): void;
|
|
2424
2637
|
updateShape(id: string, updates: Partial<Shape>): void;
|
|
2425
2638
|
deleteShape(id: string): void;
|
|
2639
|
+
/** 橡皮擦专用:先渐隐再删除(普通删除请用 deleteShape) */
|
|
2640
|
+
eraseShape(id: string): void;
|
|
2426
2641
|
selectShape(id: string, additive: boolean): void;
|
|
2427
2642
|
selectShapes(ids: string[]): void;
|
|
2643
|
+
/**
|
|
2644
|
+
* 绕过「组扩张」直接只选这一个图形。
|
|
2645
|
+
* 用于「点第二次进入组」:组已经被整组选中时,再点某个成员就把它单独选出来
|
|
2646
|
+
* (否则组内成员永远只能整组操作,改一个标签得先解组)。
|
|
2647
|
+
*/
|
|
2648
|
+
selectShapeRaw(id: string): void;
|
|
2428
2649
|
getShapes(): Shape[];
|
|
2429
2650
|
getSelectedIds(): string[];
|
|
2430
2651
|
setActiveTool(tool: ToolType): void;
|
|
@@ -2560,6 +2781,11 @@ declare class SelectTool extends Tool {
|
|
|
2560
2781
|
/** 把生成点位打包成创建上下文(from 为源点,to 为目标落点) */
|
|
2561
2782
|
private genContext;
|
|
2562
2783
|
onPointerDown(point: Vec2, event: PointerEvent): void;
|
|
2784
|
+
/**
|
|
2785
|
+
* 是否已经「进入」了 shape 所在的组:当前选区非空,且是这一组**严格子集**的成员。
|
|
2786
|
+
* 用于「组内逐成员切换」—— 进了组以后点同组其他成员不再整组扩张。
|
|
2787
|
+
*/
|
|
2788
|
+
private isInsideGroup;
|
|
2563
2789
|
/**
|
|
2564
2790
|
* 命中「表格左上角拖动把手」的表格。把手画在表格包围盒之外、普通 hitTest 命中不到,
|
|
2565
2791
|
* 所以这里单独判定;落点上若有别的图形则不抢(避免盖住别人的点击)。
|
|
@@ -2607,6 +2833,10 @@ declare class SelectTool extends Tool {
|
|
|
2607
2833
|
*
|
|
2608
2834
|
* 另外还要丢掉「其实属于自动走线的折点」(两端出/入桩的拐角,见 pruneStubBends):
|
|
2609
2835
|
* 它们是自动生成的,冻进 userPoints 后会让之后移动图形时端点旁长出小钩子。
|
|
2836
|
+
*
|
|
2837
|
+
* 同时记下 `userPointsBase`(这一刻的自动走线):之后布局一变(自动走线的形状签名变了),
|
|
2838
|
+
* 这些折点就按「过期」处理,连线自动回到当前布局下最简单的走线 —— 否则旧布局下
|
|
2839
|
+
* 绕出来的大回环会被一路带到新布局里,看着就像凭空多出一圈。
|
|
2610
2840
|
*/
|
|
2611
2841
|
private writeConnectorRoute;
|
|
2612
2842
|
/**
|
|
@@ -2659,6 +2889,11 @@ declare class SelectTool extends Tool {
|
|
|
2659
2889
|
/** 生成点位命中阈值 / 单击 vs 拖动判定阈值 */
|
|
2660
2890
|
private static readonly GEN_HIT_THRESHOLD;
|
|
2661
2891
|
private static readonly CLICK_MOVE_THRESHOLD;
|
|
2892
|
+
/**
|
|
2893
|
+
* 拖动起始阈值:小于这个距离的移动不生效。
|
|
2894
|
+
* 点击时鼠标/触控板的抖动(1~2px)以前会把图形真的挪动一点 —— 看着像"点一下就偏了"。
|
|
2895
|
+
*/
|
|
2896
|
+
private static readonly DRAG_START_THRESHOLD;
|
|
2662
2897
|
/**
|
|
2663
2898
|
* 「点击锚点生成图形」时源图形与新图形之间的默认间距(页面单位,**边到边**)。
|
|
2664
2899
|
* 旧实现是「中心沿法线外移 96」:对默认矩形(120×60)实际边距只有 36,看着太挤;
|
|
@@ -3098,4 +3333,4 @@ declare function imageDataUrl(src: string): string | null;
|
|
|
3098
3333
|
/** 清空缓存(测试/卸载时用;会释放自己创建的 blob 地址) */
|
|
3099
3334
|
declare function clearImageCache(): void;
|
|
3100
3335
|
|
|
3101
|
-
export { type ArrowBinding, type ArrowHeadType, type ArrowShape, type ArrowStyle, ArrowTool, BoardExtentKeeper, type BoardExtentResult, type BoardExtentUpdate, Camera, type CameraState, type CircleShape, type ConnectionType, DEFAULT_HIGHLIGHTER_COLOR, DEFAULT_IMAGE_MAX_SIZE_BYTES, DEFAULT_PAGE_THEME, type DiamondShape, type DrawShape, type DrawuiTheme, type DrawuiThemeSelection, Editor, type EditorData, type EditorOptions, type EditorState, type EllipseShape, type ExportFormat, type ExportOptions, type FreehandMode, FreehandTool, type GenerationContext, HandTool, type HexagonShape, ICONS, ICON_CATEGORIES, ICON_CATEGORY_INK, ICON_DEFAULT_INK, ICON_DEFAULT_SIZE, ICON_GRID, type IconCategoryId, type IconDef, type IconLayer, type IconShape, type ImageShape, type ImageUploadConfig, type ImageUploadOption, type ImageUploader, LANGUAGES, type Language, type LineShape, LineTool, MINDMAP_COLORS, MINDMAP_DIRECTIONS, MINDMAP_FONT_SIZE, MINDMAP_HANDLE_HIT_RADIUS, MINDMAP_HANDLE_RADIUS, MINDMAP_MAX_WIDTH, MINDMAP_MIN_WIDTH, MINDMAP_NODE_HEIGHT, MIN_HANDLE_SEGMENT, MIN_JOG, Mat2d, type MessageKey, type MindMapDirection, type MindMapHandleKind, type MindMapHandlePos, type MindMapLayoutResult, type MindMapNode, type MindMapNodePos, type MindMapShape, type OctagonShape, PAGE_THEMES, type PageTheme, type PageThemePreset, type ParallelogramShape, type PentagonShape, type Rect, type RectangleShape, Renderer, type RoundedRectangleShape, STICKY_FOLD_RATIO, STICKY_NOTE_COLORS, STICKY_NOTE_DEFAULT_COLOR, STICKY_TEXT_SCALE, type SegmentHandle, SelectTool, type Shape, type ShapeStyle, ShapeTool, type ShapeType, type SnapGuide, type StarShape, type StickyNoteShape, TABLE_CELL_PADDING_X, TABLE_CELL_PADDING_Y, TABLE_DEFAULT_COL_WIDTH, TABLE_DEFAULT_ROW_HEIGHT, TABLE_FONT_SIZE, TABLE_HEADER_FILL, TABLE_LINE_HEIGHT_RATIO, TABLE_MAX_AUTO_LINES, TABLE_MIN_COL_WIDTH, TABLE_MIN_ROW_HEIGHT, TABLE_MOVE_HANDLE_GAP, TABLE_MOVE_HANDLE_HEIGHT, TABLE_MOVE_HANDLE_WIDTH, THEME, type TableCell, type TableShape, type TextShape, type ToolType, type TrapezoidShape, type TriangleShape, UML_FONT_SIZE, UML_HEADER_HEIGHT, UML_LINE_HEIGHT, UML_MIN_WIDTH, UML_PADDING_X, UML_PADDING_Y, type UiEvent, type UmlAttribute, type UmlClassShape, type UmlInterfaceShape, type UmlMethod, type UmlVisibility, Vec, type Vec2 as Vec2Type, addImageReadyListener, calcUmlClassSize, clearImageCache, cloneMindMapNode, cloneTable, cloneTableCells, collapseRoute, collectTemporaryImageSrcs, connectorSegmentHandles, countMindMapNodes, createTableCells, downloadBlob, effectiveDirection, ensureImagesLoaded, exportToBlob, findMindMapNode, getContentBounds, getIcon, getLanguage, getMindMapNodeDepth, getMindMapNodeSiblings, getMindMapParent, getTheme, hasIcon, hexToRgba, hitTableBody, hitTableMoveHandle, iconInk, iconsByCategory, imageDataUrl, isEmptyRect, isFlippableShapeType, isHorizontalDirection, isImageFailed, isImageLoading, isStubCorner, isUploaderFunction, layoutMindMap, loadImage, mindMapHandleAtLocalPoint, mindMapNodeColor, mindMapNodeHandles, mindMapNodeSize, moveMindMapNodeInTree, offsetConnectorSegment, parseUploadResponse, peekImage, pickSegmentHandle, pointToSegmentDistance, promoteMindMapNodeInTree, pruneStubBends, rectsIntersect, renderSVGString, renderToCanvas, reorderMindMapNodeInTree, routeToUserPoints, sameRoute, searchIcons, setImageCrossOrigin, setLanguage, setTheme, shadeColor, subscribeLanguage, subscribeTheme, subtractUnion, t, tableAnchorAt, tableCellAtLocalClamped, tableCellLineCount, tableCellLocalRect, tableCellTextStartOffset, tableCoveredMap, tableDeleteColumn, tableDeleteRow, tableExpandRangeToMerges, tableGrowRowHeights, tableInsertColumn, tableInsertRow, tableLocalPoint, tableMerge, tableMoveHandleLocalRect, tablePagePoint, tableRangeHasMerge, tableRangeLocalRect, tableRowAtPoint, tableSplit, tableSplitRange, tableTotalHeight, tableTotalWidth, umlAttrRowText, umlMethodRowText, unionRect, uploadImageViaConfig };
|
|
3336
|
+
export { type ArrowBinding, type ArrowHeadType, type ArrowShape, type ArrowStyle, ArrowTool, BoardExtentKeeper, type BoardExtentResult, type BoardExtentUpdate, Camera, type CameraState, type CircleShape, type ConnectionType, DEFAULT_HIGHLIGHTER_COLOR, DEFAULT_IMAGE_MAX_SIZE_BYTES, DEFAULT_PAGE_THEME, type DiamondShape, type DrawShape, type DrawuiTheme, type DrawuiThemeSelection, Editor, type EditorData, type EditorOptions, type EditorState, type EllipseShape, type ExportFormat, type ExportOptions, type FreehandMode, FreehandTool, type GenerationContext, HandTool, type HexagonShape, ICONS, ICON_CATEGORIES, ICON_CATEGORY_INK, ICON_DEFAULT_INK, ICON_DEFAULT_SIZE, ICON_GRID, type IconCategoryId, type IconDef, type IconLayer, type IconShape, type ImageShape, type ImageUploadConfig, type ImageUploadOption, type ImageUploader, LANGUAGES, type Language, type LineShape, LineTool, MINDMAP_COLORS, MINDMAP_DIRECTIONS, MINDMAP_FONT_SIZE, MINDMAP_HANDLE_HIT_RADIUS, MINDMAP_HANDLE_RADIUS, MINDMAP_MAX_WIDTH, MINDMAP_MIN_WIDTH, MINDMAP_NODE_HEIGHT, MIN_HANDLE_SEGMENT, MIN_JOG, Mat2d, type MessageKey, type MindMapDirection, type MindMapHandleKind, type MindMapHandlePos, type MindMapLayoutResult, type MindMapNode, type MindMapNodePos, type MindMapShape, type OctagonShape, PAGE_THEMES, type PageTheme, type PageThemePreset, type ParallelogramShape, type PentagonShape, type Rect, type RectangleShape, Renderer, type RoundedRectangleShape, STICKY_FOLD_RATIO, STICKY_NOTE_COLORS, STICKY_NOTE_DEFAULT_COLOR, STICKY_TEXT_SCALE, type SegmentHandle, SelectTool, type Shape, type ShapeStyle, ShapeTool, type ShapeType, type SnapGuide, type StarShape, type StickyNoteShape, TABLE_CELL_PADDING_X, TABLE_CELL_PADDING_Y, TABLE_DEFAULT_COL_WIDTH, TABLE_DEFAULT_ROW_HEIGHT, TABLE_FONT_SIZE, TABLE_HEADER_FILL, TABLE_LINE_HEIGHT_RATIO, TABLE_MAX_AUTO_LINES, TABLE_MIN_COL_WIDTH, TABLE_MIN_ROW_HEIGHT, TABLE_MOVE_HANDLE_GAP, TABLE_MOVE_HANDLE_HEIGHT, TABLE_MOVE_HANDLE_WIDTH, TEMPLATES, TEMPLATE_CATEGORIES, THEME, type TableCell, type TableShape, type TemplateCategoryId, type TemplateDef, type TextShape, type ToolType, type TrapezoidShape, type TriangleShape, UML_FONT_SIZE, UML_HEADER_HEIGHT, UML_LINE_HEIGHT, UML_MIN_WIDTH, UML_PADDING_X, UML_PADDING_Y, type UiEvent, type UmlAttribute, type UmlClassShape, type UmlInterfaceShape, type UmlMethod, type UmlVisibility, Vec, type Vec2 as Vec2Type, addImageReadyListener, calcUmlClassSize, clearImageCache, cloneMindMapNode, cloneTable, cloneTableCells, collapseRoute, collectTemporaryImageSrcs, connectorSegmentHandles, countMindMapNodes, createTableCells, downloadBlob, effectiveDirection, ensureIcons, ensureImagesLoaded, exportToBlob, findMindMapNode, getContentBounds, getIcon, getLanguage, getMindMapNodeDepth, getMindMapNodeSiblings, getMindMapParent, getTheme, hasIcon, hexToRgba, hitTableBody, hitTableMoveHandle, iconInk, iconsByCategory, imageDataUrl, isEmptyRect, isFlippableShapeType, isHorizontalDirection, isIconCatalogLoaded, isImageFailed, isImageLoading, isStubCorner, isUploaderFunction, layoutMindMap, loadIconCatalog, loadImage, mindMapHandleAtLocalPoint, mindMapNodeColor, mindMapNodeHandles, mindMapNodeSize, moveMindMapNodeInTree, offsetConnectorSegment, parseUploadResponse, peekImage, pickSegmentHandle, pointToSegmentDistance, promoteMindMapNodeInTree, pruneStubBends, rectsIntersect, renderSVGString, renderToCanvas, reorderMindMapNodeInTree, routeToUserPoints, sameRoute, searchIcons, searchTemplates, setImageCrossOrigin, setLanguage, setTheme, shadeColor, subscribeLanguage, subscribeTheme, subtractUnion, t, tableAnchorAt, tableCellAtLocalClamped, tableCellLineCount, tableCellLocalRect, tableCellTextStartOffset, tableCoveredMap, tableDeleteColumn, tableDeleteRow, tableExpandRangeToMerges, tableGrowRowHeights, tableInsertColumn, tableInsertRow, tableLocalPoint, tableMerge, tableMoveHandleLocalRect, tablePagePoint, tableRangeHasMerge, tableRangeLocalRect, tableRowAtPoint, tableSplit, tableSplitRange, tableTotalHeight, tableTotalWidth, templateById, umlAttrRowText, umlMethodRowText, unionRect, uploadImageViaConfig };
|