drawui-core 0.3.3 → 0.3.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/dist/index.cjs +17 -17
- package/dist/index.d.cts +142 -15
- package/dist/index.d.ts +142 -15
- package/dist/index.js +17 -17
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -185,12 +185,24 @@ interface GenerationContext {
|
|
|
185
185
|
sourceShapeId?: string;
|
|
186
186
|
edge?: 'n' | 'e' | 's' | 'w';
|
|
187
187
|
}
|
|
188
|
-
/**
|
|
188
|
+
/** 生成点位预览:与最终创建结果完全一致的连线预览(+ 待放置图形轮廓) */
|
|
189
189
|
interface GenerationPreview {
|
|
190
190
|
from: Vec2;
|
|
191
191
|
to: Vec2;
|
|
192
192
|
/** 待放置图形的类型;不提供(指向已有图形)时只画线条 */
|
|
193
193
|
type?: ShapeType;
|
|
194
|
+
/** 源图形 id 与出线边:预览走与最终创建相同的「出线边同轴接入」路由 */
|
|
195
|
+
sourceShapeId?: string;
|
|
196
|
+
sourceEdge?: 'n' | 'e' | 's' | 'w';
|
|
197
|
+
/** 指向已有图形时的目标与绑定(预览即最终落点) */
|
|
198
|
+
targetShapeId?: string;
|
|
199
|
+
targetBinding?: ArrowBinding;
|
|
200
|
+
/** true = 拖拽中(按真实样式预览);false/缺省 = 悬停(浅色虚线提示) */
|
|
201
|
+
dragging?: boolean;
|
|
202
|
+
/** 新建连线的默认样式,与最终创建保持一致 */
|
|
203
|
+
arrowStyle?: ArrowStyle;
|
|
204
|
+
/** 连线本身的颜色/粗细,与最终创建保持一致 */
|
|
205
|
+
lineStyle?: ShapeStyle;
|
|
194
206
|
}
|
|
195
207
|
/** 生成点位 → UI 菜单载荷:拖动到空白处后触发的"选择新图形"菜单 */
|
|
196
208
|
interface GenerationMenuPayload {
|
|
@@ -803,6 +815,7 @@ declare class Editor {
|
|
|
803
815
|
private snapGuides;
|
|
804
816
|
private connectingTargetId;
|
|
805
817
|
private genPreview;
|
|
818
|
+
private hoverAnchorShapeId;
|
|
806
819
|
private eraserPoint;
|
|
807
820
|
private mindMapEditingShapeId;
|
|
808
821
|
private mindMapSelectedNode;
|
|
@@ -819,6 +832,23 @@ declare class Editor {
|
|
|
819
832
|
private arrowStyle;
|
|
820
833
|
constructor(canvas: HTMLCanvasElement, options?: EditorOptions);
|
|
821
834
|
private setupEventListeners;
|
|
835
|
+
/** 窗口失焦(切页签/alt-tab):按下状态与一切瞬态预览都作废,避免"卡住" */
|
|
836
|
+
private handleWindowBlur;
|
|
837
|
+
/**
|
|
838
|
+
* 在画布之外按下指针(工具栏、面板、页面空白)→ 立刻收尾残留交互。
|
|
839
|
+
* 用户预期是「点哪儿都能把残留的虚线清掉」,这里就是那根兜底绳。
|
|
840
|
+
* 若此时 pointerIsDown 仍是 true,说明上一轮的 pointerup 丢了(在窗口外松手),
|
|
841
|
+
* 一并把按下状态复位。
|
|
842
|
+
*/
|
|
843
|
+
private handleGlobalPointerDown;
|
|
844
|
+
/**
|
|
845
|
+
* 当前是否存在「本该结束、却还留着」的瞬态交互。
|
|
846
|
+
* 注意:只认拖拽态(工具非空闲 / 目标高亮 / 对齐线 / 框选)——
|
|
847
|
+
* 悬停产生的锚点与悬停预览是常驻的合法状态,不能算残留,否则每次移动都会被打断。
|
|
848
|
+
*/
|
|
849
|
+
private shouldRecoverTransient;
|
|
850
|
+
/** 收尾:让工具回到空闲态,并清空画布上的瞬态可视化 */
|
|
851
|
+
private cancelTransientInteraction;
|
|
822
852
|
private handlePointerDown;
|
|
823
853
|
private handlePointerMove;
|
|
824
854
|
private handlePointerUp;
|
|
@@ -844,8 +874,16 @@ declare class Editor {
|
|
|
844
874
|
/** 设置对齐参考线(由工具在拖拽过程中调用) */
|
|
845
875
|
private setSnapGuides;
|
|
846
876
|
private setConnectingTarget;
|
|
847
|
-
/**
|
|
877
|
+
/** 设置生成点位预览(拖动/悬浮中显示的连线 + 待放置图形虚框) */
|
|
848
878
|
private setGenerationPreview;
|
|
879
|
+
/** 设置悬停图形(画布为其绘制四边连接锚点) */
|
|
880
|
+
private setHoverAnchorShape;
|
|
881
|
+
/**
|
|
882
|
+
* 清掉所有「瞬态」的交互可视化状态:连线预览、目标高亮、对齐参考线、框选、悬停锚点。
|
|
883
|
+
* 这些状态只在一次交互过程中有效 —— 只要交互结束(或事件丢失)就必须清空,
|
|
884
|
+
* 否则会残留虚线/虚框且越点越多。返回是否确有清理(供调用方决定是否重绘)。
|
|
885
|
+
*/
|
|
886
|
+
private clearTransientPreview;
|
|
849
887
|
/** 拖动到空白处松开 → 弹出"选择新图形"菜单(转发给 React UI) */
|
|
850
888
|
private openGenerationMenu;
|
|
851
889
|
private lineStyle;
|
|
@@ -853,10 +891,7 @@ declare class Editor {
|
|
|
853
891
|
private computeSourceBinding;
|
|
854
892
|
/**
|
|
855
893
|
* 连线到达目标图形时,应吸附到目标面向来线的那个边。
|
|
856
|
-
*
|
|
857
|
-
* 左/右边(面向来线的一侧);从上下边出线,就优先接目标的上/下边。
|
|
858
|
-
* 这样多条分支连线才能共用同一条正交主干总线(飞书式分叉),而不是各自
|
|
859
|
-
* 横着拐进目标的顶边、沿边缘爬进去。
|
|
894
|
+
* 规则唯一来源:`docking.ts` 的 pickDockSide(与出线边同轴,详见该文件注释)。
|
|
860
895
|
*/
|
|
861
896
|
private connectHandle;
|
|
862
897
|
/** 仅创建一条从源点引出、末端悬空的线条并选中它 */
|
|
@@ -1126,7 +1161,9 @@ declare class Renderer {
|
|
|
1126
1161
|
nodeId: string;
|
|
1127
1162
|
} | null,
|
|
1128
1163
|
/** 导出用:非 null 时先以该颜色铺满整块画布(白底等),默认不铺(透明) */
|
|
1129
|
-
background?: string | null
|
|
1164
|
+
background?: string | null,
|
|
1165
|
+
/** 悬停的图形 id:为其绘制四边连接锚点(飞书式悬浮提示),已选中图形由选择手柄负责 */
|
|
1166
|
+
hoverAnchorShapeId?: string | null): void;
|
|
1130
1167
|
/** 橡皮擦:半透明主色圆 + 主色描边,半径与笔刷命中范围一致(屏幕像素恒定) */
|
|
1131
1168
|
private drawEraserBrush;
|
|
1132
1169
|
/** 连接进行中,高亮目标图形四边中点的可连锚点 */
|
|
@@ -1188,11 +1225,23 @@ declare class Renderer {
|
|
|
1188
1225
|
private drawArrow;
|
|
1189
1226
|
/** 选中连线 → 在线条上叠加一条高亮辅助线 */
|
|
1190
1227
|
private drawLinearHighlight;
|
|
1191
|
-
/**
|
|
1228
|
+
/**
|
|
1229
|
+
* 生成点位预览:源点圆点 + 连线预览 + 待放置图形虚框。
|
|
1230
|
+
*
|
|
1231
|
+
* 关键:预览不再是「直线虚线」——它把待创建的连线合成为一条临时箭头,
|
|
1232
|
+
* 直接走 drawArrow 的真实渲染路径(正交路由 / 垂直出入桩 / 出线边同轴接入 /
|
|
1233
|
+
* 箭头头部 / 虚线样式全一致),因此拖拽时看到的就是松手后得到的样子。
|
|
1234
|
+
* 拖拽中按真实样式绘制;悬停时降为半透明,保持「尚未确定」的观感。
|
|
1235
|
+
*/
|
|
1192
1236
|
private drawGenerationPreview;
|
|
1193
|
-
/**
|
|
1237
|
+
/** 待放置图形的虚线轮廓(按该类型的真实默认尺寸绘制) */
|
|
1194
1238
|
private drawPreviewShapeOutline;
|
|
1195
1239
|
private static readonly ALIGN_TOLERANCE;
|
|
1240
|
+
/** 生成预览用的临时 id / 样式(不写入文档,仅本次绘制使用) */
|
|
1241
|
+
private static readonly GEN_PREVIEW_ID;
|
|
1242
|
+
private static readonly GEN_GHOST_ID;
|
|
1243
|
+
/** 与 Editor.lineStyle() 一致:预览线用最终连线的真实颜色/粗细 */
|
|
1244
|
+
private static readonly PREVIEW_LINE_STYLE;
|
|
1196
1245
|
/**
|
|
1197
1246
|
* 判断连线两端是否水平或垂直对齐(在容差内)。
|
|
1198
1247
|
* 若在容差内,强制将坐标对齐(避免 grid snapping 导致无法形成直线)。
|
|
@@ -1214,10 +1263,25 @@ declare class Renderer {
|
|
|
1214
1263
|
private generatePolylinePoints;
|
|
1215
1264
|
/** 直角折线:与 polyline 使用相同的 H-V-H 正交路由,仅渲染方式(sharp)不同。 */
|
|
1216
1265
|
private generateOrthogonalPoints;
|
|
1266
|
+
/**
|
|
1267
|
+
* 把折线末段掰到期望轴向('H' 水平收尾 / 'V' 垂直收尾)。
|
|
1268
|
+
* 绕行分支(A 星网格 / 退避)给出的路径末段方向不受控,这里在末点前补一个拐点,
|
|
1269
|
+
* 保证箭头始终沿接入边法向插入(或沿出线方向收尾)。
|
|
1270
|
+
*/
|
|
1271
|
+
private ensureFinalAxis;
|
|
1217
1272
|
/** 去除连续重合点与共线点,精简冗余拐点 */
|
|
1218
1273
|
private collapseLinePoints;
|
|
1219
1274
|
/** 计算单段直角路由:优先无碰撞、且符合总线轴方向的 H-V-H / V-H-V 折线,必要时绕开障碍 */
|
|
1220
1275
|
private computeOrthogonalRoute;
|
|
1276
|
+
/**
|
|
1277
|
+
* 剔除「把某个端点压在身下」的障碍。
|
|
1278
|
+
*
|
|
1279
|
+
* 这类障碍(典型:用户把图形拖到与另一张图形重叠)无法绕开 —— 端点的落点就在它里面,
|
|
1280
|
+
* 与其避让只会让布线变成「绕着端点打转」的怪线,还会把 A* 的终点节点封死。
|
|
1281
|
+
* 剔除后连线可以直穿重叠图形,观测上就是「叠在一起就随他叠」,
|
|
1282
|
+
* 同时保证端点(点位)不会被自动挪走。
|
|
1283
|
+
*/
|
|
1284
|
+
private dropObstaclesAtEndpoints;
|
|
1221
1285
|
/**
|
|
1222
1286
|
* 在停靠偏好对应的总线轴上,从源侧向外逐点平移总线位置,返回第一条「垂直方向和
|
|
1223
1287
|
* 末段水平分支都避开所有中间障碍」的总线折线;找不到则返回 null。
|
|
@@ -1254,20 +1318,27 @@ declare class Renderer {
|
|
|
1254
1318
|
private getTextBounds;
|
|
1255
1319
|
private wrapLine;
|
|
1256
1320
|
private truncateLine;
|
|
1257
|
-
/** 连接点句柄 →
|
|
1321
|
+
/** 连接点句柄 → 外法向(页面坐标单位向量;规则见 docking.ts) */
|
|
1258
1322
|
private static readonly HANDLE_NORMALS;
|
|
1259
1323
|
/**
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1324
|
+
* 自动接入边选择:与出线边「同轴」优先(规则唯一来源见 docking.ts)——
|
|
1325
|
+
* 从源图形左右边出线就接目标的左/右边(面向来线一侧),从上下边出线就接上/下边;
|
|
1326
|
+
* 这样分支连线才能共用同一条正交主干总线,而不是横着拐进目标顶边。
|
|
1263
1327
|
*/
|
|
1264
1328
|
private pickAutoHandle;
|
|
1265
1329
|
/** auto 绑定 → 按当前几何重选接入边;显式绑定原样返回 */
|
|
1266
1330
|
private resolveAutoEndBinding;
|
|
1267
1331
|
private getBindingPoint;
|
|
1332
|
+
/**
|
|
1333
|
+
* 求某一端的停靠法向。**优先用绑定信息**:绑定已经明确告诉我们是哪个图形的哪条边,
|
|
1334
|
+
* 比几何猜测可靠得多 —— 当有图形与端点所在图形重叠时(典型:新建图形虚框压在源图形上),
|
|
1335
|
+
* 纯几何的 getDockNormal 会挑到「离端点更近的另一张图形」,把出线/接入方向判反。
|
|
1336
|
+
*/
|
|
1337
|
+
private resolveDockNormal;
|
|
1268
1338
|
/**
|
|
1269
1339
|
* 计算端点所在图形的外法向(垂直于该侧边缘,页面坐标单位向量)。
|
|
1270
1340
|
* 用于连线垂直脱离/接入图形边缘,端点不在任何图形上时返回 undefined。
|
|
1341
|
+
* preferShapeId:优先认这个图形(端点正好被多张图形覆盖时用它消歧)。
|
|
1271
1342
|
*/
|
|
1272
1343
|
private getDockNormal;
|
|
1273
1344
|
/**
|
|
@@ -1303,6 +1374,12 @@ declare class Renderer {
|
|
|
1303
1374
|
private drawFreehand;
|
|
1304
1375
|
private drawSelectionOutline;
|
|
1305
1376
|
private drawSelectionHandles;
|
|
1377
|
+
/**
|
|
1378
|
+
* 四边中点的连接锚点(外圈 + 内点)。
|
|
1379
|
+
* bounds 使用调用方的坐标系:选中手柄路径传入「本地包围盒」(画布已 translate 到图形中心),
|
|
1380
|
+
* 悬停提示路径传入「世界包围盒」(画布未平移)。alpha 用于弱化悬停态。
|
|
1381
|
+
*/
|
|
1382
|
+
private drawConnectionDots;
|
|
1306
1383
|
/** 画旋转图标:顺时针短弧 + 箭头 */
|
|
1307
1384
|
private drawRotateIcon;
|
|
1308
1385
|
private getShapeBounds;
|
|
@@ -1354,6 +1431,10 @@ interface ToolContext {
|
|
|
1354
1431
|
setSnapGuides(guides: SnapGuide[]): void;
|
|
1355
1432
|
setConnectingTarget(id: string | null): void;
|
|
1356
1433
|
setGenerationPreview(preview: GenerationPreview | null): void;
|
|
1434
|
+
/** 悬停图形 → 画布为其绘制四边连接锚点(null 清除) */
|
|
1435
|
+
setHoverAnchorShape(id: string | null): void;
|
|
1436
|
+
/** 新建连线的线条样式(颜色/粗细),与最终创建的连线保持一致 */
|
|
1437
|
+
getLineStyle(): ShapeStyle;
|
|
1357
1438
|
/** 拖动到空白处:创建一条浮动线条并弹出"选择新图形"菜单 */
|
|
1358
1439
|
openGenerationMenu(payload: GenerationMenuPayload): void;
|
|
1359
1440
|
/** 创建"新图形 + 连线";existingArrowId 存在时把线条末端接到新图形 */
|
|
@@ -1392,6 +1473,17 @@ declare abstract class Tool {
|
|
|
1392
1473
|
abstract onKeyUp(event: KeyboardEvent): void;
|
|
1393
1474
|
/** 返回当前指针位置应显示的鼠标样式,null 表示使用默认 */
|
|
1394
1475
|
getCursor(_point: Vec2): string | null;
|
|
1476
|
+
/**
|
|
1477
|
+
* 是否正处于一次未结束的交互中(拖拽/生成/框选…)。
|
|
1478
|
+
* 编辑器据此判断「指针没按下却仍有工具状态」= 丢事件,需要自愈。
|
|
1479
|
+
*/
|
|
1480
|
+
hasTransientState(): boolean;
|
|
1481
|
+
/**
|
|
1482
|
+
* 取消一切「瞬态」交互状态(正在拖拽/生成/框选/旋转…),回到干净的空闲态。
|
|
1483
|
+
* 用于指针事件丢失(在窗口外松手、失焦)、点击画布外、切换工具时的自愈。
|
|
1484
|
+
* @returns 是否确实清理了状态(false = 本来就是空闲态,调用方可跳过重绘)
|
|
1485
|
+
*/
|
|
1486
|
+
cancelTransient(): boolean;
|
|
1395
1487
|
dispose(): void;
|
|
1396
1488
|
}
|
|
1397
1489
|
|
|
@@ -1402,6 +1494,8 @@ declare class SelectTool extends Tool {
|
|
|
1402
1494
|
private resizingState;
|
|
1403
1495
|
private generatingState;
|
|
1404
1496
|
private hoverGenPoint;
|
|
1497
|
+
/** 悬停(未按下)的图形 id:为其显示四边连接锚点,可直接从这里拖出连线 */
|
|
1498
|
+
private hoverShapeId;
|
|
1405
1499
|
private rotatingState;
|
|
1406
1500
|
private draggingArrowId;
|
|
1407
1501
|
private draggingTerminal;
|
|
@@ -1410,12 +1504,23 @@ declare class SelectTool extends Tool {
|
|
|
1410
1504
|
private brushShiftKey;
|
|
1411
1505
|
/** 生成点位默认创建的图形类型:源图形若为可创建类型则同型,否则用矩形 */
|
|
1412
1506
|
private defaultGenType;
|
|
1507
|
+
/**
|
|
1508
|
+
* 生成点位预览:带上源图形/出线边/目标绑定/线条样式,画布据此走「与最终创建完全一致」
|
|
1509
|
+
* 的真实渲染路径(正交路由 + 出入桩 + 同轴接入边 + 箭头样式),做到拖拽即所见即所得。
|
|
1510
|
+
*/
|
|
1413
1511
|
private genPreviewOf;
|
|
1414
1512
|
/** 把生成点位打包成创建上下文(from 为源点,to 为目标落点) */
|
|
1415
1513
|
private genContext;
|
|
1416
1514
|
onPointerDown(point: Vec2, event: PointerEvent): void;
|
|
1417
1515
|
onPointerMove(point: Vec2, event: PointerEvent): void;
|
|
1418
1516
|
onPointerUp(point: Vec2, _event: PointerEvent): void;
|
|
1517
|
+
hasTransientState(): boolean;
|
|
1518
|
+
/**
|
|
1519
|
+
* 取消一切瞬态交互(拖拽/生成/框选/旋转/连线端点拖拽)并清掉画布上的瞬态预览。
|
|
1520
|
+
* 触发场景:指针在窗口外松手丢失 pointerup、窗口失焦、点击画布外、无按压的移动、
|
|
1521
|
+
* 切换工具、Esc。返回值用于让调用方决定是否需要重绘。
|
|
1522
|
+
*/
|
|
1523
|
+
cancelTransient(): boolean;
|
|
1419
1524
|
onKeyDown(event: KeyboardEvent): void;
|
|
1420
1525
|
onKeyUp(_event: KeyboardEvent): void;
|
|
1421
1526
|
/** 鼠标样式:伸缩手柄 → 对应方向的双向箭头;拖拽中 → 抓取 */
|
|
@@ -1448,13 +1553,20 @@ declare class SelectTool extends Tool {
|
|
|
1448
1553
|
/** 生成点位命中阈值 / 单击 vs 拖动判定阈值 */
|
|
1449
1554
|
private static readonly GEN_HIT_THRESHOLD;
|
|
1450
1555
|
private static readonly CLICK_MOVE_THRESHOLD;
|
|
1451
|
-
/**
|
|
1556
|
+
/** 支持四边连接锚点的图形类型(矩形类、流程图形、UML 等) */
|
|
1557
|
+
private static readonly GEN_SUPPORTED_TYPES;
|
|
1558
|
+
/**
|
|
1559
|
+
* 收集图形上的全部生成点位(四边中点/快捷连线按钮)。
|
|
1560
|
+
* extraShapeId:额外把某个图形(当前悬停的图形)纳入 —— 未选中图形也能直接连出连线。
|
|
1561
|
+
*/
|
|
1452
1562
|
private computeGenPoints;
|
|
1453
1563
|
/** 命中检测:指针是否落在某个生成点位附近(取最近的) */
|
|
1454
1564
|
private hitGenPoint;
|
|
1565
|
+
/** 悬停(未按下)时指针所在的、支持连线锚点的图形 id(已选中的交给选择手柄,返回 null) */
|
|
1566
|
+
private findHoverAnchorShape;
|
|
1455
1567
|
/** 生成点位预览的落点:拖动时跟随光标;静止/悬浮时向外延伸一个默认位置的框 */
|
|
1456
1568
|
private genPreviewTarget;
|
|
1457
|
-
/**
|
|
1569
|
+
/** 生成拖动:更新预览(真实样式的连线 + 待放置图形虚框)与目标高亮 */
|
|
1458
1570
|
private handleGenerating;
|
|
1459
1571
|
private handleRotating;
|
|
1460
1572
|
/** 根据绑定信息返回目标图形的实际吸附点 */
|
|
@@ -1462,6 +1574,21 @@ declare class SelectTool extends Tool {
|
|
|
1462
1574
|
private isPointInShape;
|
|
1463
1575
|
private isPointInHexagon;
|
|
1464
1576
|
private pointToLineDistance;
|
|
1577
|
+
/**
|
|
1578
|
+
* 待新建图形与源图形重叠时,把它沿「源→目标」方向推到不重叠(留一个引线距离)。
|
|
1579
|
+
*
|
|
1580
|
+
* 为什么必须做:图形重叠时,连线要接入的那条边会落在源图形内部/后方,
|
|
1581
|
+
* 路由只能往回折(实测出现「往右拖一点点 → 一条往回折的钩子甚至横穿的怪线」),
|
|
1582
|
+
* 而且新图形压着源图形本身就不好看。推开后接入边始终在出线方向的前方,
|
|
1583
|
+
* 引线距离取 CONNECTION_LEAD(24),正好让「出线桩 → 接入点」是一条直线。
|
|
1584
|
+
*/
|
|
1585
|
+
private avoidSourceOverlap;
|
|
1586
|
+
/**
|
|
1587
|
+
* 预判「将要新建的图形」面向来线的那个接入点:
|
|
1588
|
+
* 用该类型的真实默认尺寸 + 与 Editor.connectHandle 完全相同的 docking 规则算落点,
|
|
1589
|
+
* 让「拖拽预览 → 松手后的浮动线条 → 插入后的真实连线」位置一致、不跳变。
|
|
1590
|
+
*/
|
|
1591
|
+
private futureDockPoint;
|
|
1465
1592
|
private getShapeBounds;
|
|
1466
1593
|
private hitTestArrowTerminal;
|
|
1467
1594
|
private findShapeNearPoint;
|
package/dist/index.d.ts
CHANGED
|
@@ -185,12 +185,24 @@ interface GenerationContext {
|
|
|
185
185
|
sourceShapeId?: string;
|
|
186
186
|
edge?: 'n' | 'e' | 's' | 'w';
|
|
187
187
|
}
|
|
188
|
-
/**
|
|
188
|
+
/** 生成点位预览:与最终创建结果完全一致的连线预览(+ 待放置图形轮廓) */
|
|
189
189
|
interface GenerationPreview {
|
|
190
190
|
from: Vec2;
|
|
191
191
|
to: Vec2;
|
|
192
192
|
/** 待放置图形的类型;不提供(指向已有图形)时只画线条 */
|
|
193
193
|
type?: ShapeType;
|
|
194
|
+
/** 源图形 id 与出线边:预览走与最终创建相同的「出线边同轴接入」路由 */
|
|
195
|
+
sourceShapeId?: string;
|
|
196
|
+
sourceEdge?: 'n' | 'e' | 's' | 'w';
|
|
197
|
+
/** 指向已有图形时的目标与绑定(预览即最终落点) */
|
|
198
|
+
targetShapeId?: string;
|
|
199
|
+
targetBinding?: ArrowBinding;
|
|
200
|
+
/** true = 拖拽中(按真实样式预览);false/缺省 = 悬停(浅色虚线提示) */
|
|
201
|
+
dragging?: boolean;
|
|
202
|
+
/** 新建连线的默认样式,与最终创建保持一致 */
|
|
203
|
+
arrowStyle?: ArrowStyle;
|
|
204
|
+
/** 连线本身的颜色/粗细,与最终创建保持一致 */
|
|
205
|
+
lineStyle?: ShapeStyle;
|
|
194
206
|
}
|
|
195
207
|
/** 生成点位 → UI 菜单载荷:拖动到空白处后触发的"选择新图形"菜单 */
|
|
196
208
|
interface GenerationMenuPayload {
|
|
@@ -803,6 +815,7 @@ declare class Editor {
|
|
|
803
815
|
private snapGuides;
|
|
804
816
|
private connectingTargetId;
|
|
805
817
|
private genPreview;
|
|
818
|
+
private hoverAnchorShapeId;
|
|
806
819
|
private eraserPoint;
|
|
807
820
|
private mindMapEditingShapeId;
|
|
808
821
|
private mindMapSelectedNode;
|
|
@@ -819,6 +832,23 @@ declare class Editor {
|
|
|
819
832
|
private arrowStyle;
|
|
820
833
|
constructor(canvas: HTMLCanvasElement, options?: EditorOptions);
|
|
821
834
|
private setupEventListeners;
|
|
835
|
+
/** 窗口失焦(切页签/alt-tab):按下状态与一切瞬态预览都作废,避免"卡住" */
|
|
836
|
+
private handleWindowBlur;
|
|
837
|
+
/**
|
|
838
|
+
* 在画布之外按下指针(工具栏、面板、页面空白)→ 立刻收尾残留交互。
|
|
839
|
+
* 用户预期是「点哪儿都能把残留的虚线清掉」,这里就是那根兜底绳。
|
|
840
|
+
* 若此时 pointerIsDown 仍是 true,说明上一轮的 pointerup 丢了(在窗口外松手),
|
|
841
|
+
* 一并把按下状态复位。
|
|
842
|
+
*/
|
|
843
|
+
private handleGlobalPointerDown;
|
|
844
|
+
/**
|
|
845
|
+
* 当前是否存在「本该结束、却还留着」的瞬态交互。
|
|
846
|
+
* 注意:只认拖拽态(工具非空闲 / 目标高亮 / 对齐线 / 框选)——
|
|
847
|
+
* 悬停产生的锚点与悬停预览是常驻的合法状态,不能算残留,否则每次移动都会被打断。
|
|
848
|
+
*/
|
|
849
|
+
private shouldRecoverTransient;
|
|
850
|
+
/** 收尾:让工具回到空闲态,并清空画布上的瞬态可视化 */
|
|
851
|
+
private cancelTransientInteraction;
|
|
822
852
|
private handlePointerDown;
|
|
823
853
|
private handlePointerMove;
|
|
824
854
|
private handlePointerUp;
|
|
@@ -844,8 +874,16 @@ declare class Editor {
|
|
|
844
874
|
/** 设置对齐参考线(由工具在拖拽过程中调用) */
|
|
845
875
|
private setSnapGuides;
|
|
846
876
|
private setConnectingTarget;
|
|
847
|
-
/**
|
|
877
|
+
/** 设置生成点位预览(拖动/悬浮中显示的连线 + 待放置图形虚框) */
|
|
848
878
|
private setGenerationPreview;
|
|
879
|
+
/** 设置悬停图形(画布为其绘制四边连接锚点) */
|
|
880
|
+
private setHoverAnchorShape;
|
|
881
|
+
/**
|
|
882
|
+
* 清掉所有「瞬态」的交互可视化状态:连线预览、目标高亮、对齐参考线、框选、悬停锚点。
|
|
883
|
+
* 这些状态只在一次交互过程中有效 —— 只要交互结束(或事件丢失)就必须清空,
|
|
884
|
+
* 否则会残留虚线/虚框且越点越多。返回是否确有清理(供调用方决定是否重绘)。
|
|
885
|
+
*/
|
|
886
|
+
private clearTransientPreview;
|
|
849
887
|
/** 拖动到空白处松开 → 弹出"选择新图形"菜单(转发给 React UI) */
|
|
850
888
|
private openGenerationMenu;
|
|
851
889
|
private lineStyle;
|
|
@@ -853,10 +891,7 @@ declare class Editor {
|
|
|
853
891
|
private computeSourceBinding;
|
|
854
892
|
/**
|
|
855
893
|
* 连线到达目标图形时,应吸附到目标面向来线的那个边。
|
|
856
|
-
*
|
|
857
|
-
* 左/右边(面向来线的一侧);从上下边出线,就优先接目标的上/下边。
|
|
858
|
-
* 这样多条分支连线才能共用同一条正交主干总线(飞书式分叉),而不是各自
|
|
859
|
-
* 横着拐进目标的顶边、沿边缘爬进去。
|
|
894
|
+
* 规则唯一来源:`docking.ts` 的 pickDockSide(与出线边同轴,详见该文件注释)。
|
|
860
895
|
*/
|
|
861
896
|
private connectHandle;
|
|
862
897
|
/** 仅创建一条从源点引出、末端悬空的线条并选中它 */
|
|
@@ -1126,7 +1161,9 @@ declare class Renderer {
|
|
|
1126
1161
|
nodeId: string;
|
|
1127
1162
|
} | null,
|
|
1128
1163
|
/** 导出用:非 null 时先以该颜色铺满整块画布(白底等),默认不铺(透明) */
|
|
1129
|
-
background?: string | null
|
|
1164
|
+
background?: string | null,
|
|
1165
|
+
/** 悬停的图形 id:为其绘制四边连接锚点(飞书式悬浮提示),已选中图形由选择手柄负责 */
|
|
1166
|
+
hoverAnchorShapeId?: string | null): void;
|
|
1130
1167
|
/** 橡皮擦:半透明主色圆 + 主色描边,半径与笔刷命中范围一致(屏幕像素恒定) */
|
|
1131
1168
|
private drawEraserBrush;
|
|
1132
1169
|
/** 连接进行中,高亮目标图形四边中点的可连锚点 */
|
|
@@ -1188,11 +1225,23 @@ declare class Renderer {
|
|
|
1188
1225
|
private drawArrow;
|
|
1189
1226
|
/** 选中连线 → 在线条上叠加一条高亮辅助线 */
|
|
1190
1227
|
private drawLinearHighlight;
|
|
1191
|
-
/**
|
|
1228
|
+
/**
|
|
1229
|
+
* 生成点位预览:源点圆点 + 连线预览 + 待放置图形虚框。
|
|
1230
|
+
*
|
|
1231
|
+
* 关键:预览不再是「直线虚线」——它把待创建的连线合成为一条临时箭头,
|
|
1232
|
+
* 直接走 drawArrow 的真实渲染路径(正交路由 / 垂直出入桩 / 出线边同轴接入 /
|
|
1233
|
+
* 箭头头部 / 虚线样式全一致),因此拖拽时看到的就是松手后得到的样子。
|
|
1234
|
+
* 拖拽中按真实样式绘制;悬停时降为半透明,保持「尚未确定」的观感。
|
|
1235
|
+
*/
|
|
1192
1236
|
private drawGenerationPreview;
|
|
1193
|
-
/**
|
|
1237
|
+
/** 待放置图形的虚线轮廓(按该类型的真实默认尺寸绘制) */
|
|
1194
1238
|
private drawPreviewShapeOutline;
|
|
1195
1239
|
private static readonly ALIGN_TOLERANCE;
|
|
1240
|
+
/** 生成预览用的临时 id / 样式(不写入文档,仅本次绘制使用) */
|
|
1241
|
+
private static readonly GEN_PREVIEW_ID;
|
|
1242
|
+
private static readonly GEN_GHOST_ID;
|
|
1243
|
+
/** 与 Editor.lineStyle() 一致:预览线用最终连线的真实颜色/粗细 */
|
|
1244
|
+
private static readonly PREVIEW_LINE_STYLE;
|
|
1196
1245
|
/**
|
|
1197
1246
|
* 判断连线两端是否水平或垂直对齐(在容差内)。
|
|
1198
1247
|
* 若在容差内,强制将坐标对齐(避免 grid snapping 导致无法形成直线)。
|
|
@@ -1214,10 +1263,25 @@ declare class Renderer {
|
|
|
1214
1263
|
private generatePolylinePoints;
|
|
1215
1264
|
/** 直角折线:与 polyline 使用相同的 H-V-H 正交路由,仅渲染方式(sharp)不同。 */
|
|
1216
1265
|
private generateOrthogonalPoints;
|
|
1266
|
+
/**
|
|
1267
|
+
* 把折线末段掰到期望轴向('H' 水平收尾 / 'V' 垂直收尾)。
|
|
1268
|
+
* 绕行分支(A 星网格 / 退避)给出的路径末段方向不受控,这里在末点前补一个拐点,
|
|
1269
|
+
* 保证箭头始终沿接入边法向插入(或沿出线方向收尾)。
|
|
1270
|
+
*/
|
|
1271
|
+
private ensureFinalAxis;
|
|
1217
1272
|
/** 去除连续重合点与共线点,精简冗余拐点 */
|
|
1218
1273
|
private collapseLinePoints;
|
|
1219
1274
|
/** 计算单段直角路由:优先无碰撞、且符合总线轴方向的 H-V-H / V-H-V 折线,必要时绕开障碍 */
|
|
1220
1275
|
private computeOrthogonalRoute;
|
|
1276
|
+
/**
|
|
1277
|
+
* 剔除「把某个端点压在身下」的障碍。
|
|
1278
|
+
*
|
|
1279
|
+
* 这类障碍(典型:用户把图形拖到与另一张图形重叠)无法绕开 —— 端点的落点就在它里面,
|
|
1280
|
+
* 与其避让只会让布线变成「绕着端点打转」的怪线,还会把 A* 的终点节点封死。
|
|
1281
|
+
* 剔除后连线可以直穿重叠图形,观测上就是「叠在一起就随他叠」,
|
|
1282
|
+
* 同时保证端点(点位)不会被自动挪走。
|
|
1283
|
+
*/
|
|
1284
|
+
private dropObstaclesAtEndpoints;
|
|
1221
1285
|
/**
|
|
1222
1286
|
* 在停靠偏好对应的总线轴上,从源侧向外逐点平移总线位置,返回第一条「垂直方向和
|
|
1223
1287
|
* 末段水平分支都避开所有中间障碍」的总线折线;找不到则返回 null。
|
|
@@ -1254,20 +1318,27 @@ declare class Renderer {
|
|
|
1254
1318
|
private getTextBounds;
|
|
1255
1319
|
private wrapLine;
|
|
1256
1320
|
private truncateLine;
|
|
1257
|
-
/** 连接点句柄 →
|
|
1321
|
+
/** 连接点句柄 → 外法向(页面坐标单位向量;规则见 docking.ts) */
|
|
1258
1322
|
private static readonly HANDLE_NORMALS;
|
|
1259
1323
|
/**
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1324
|
+
* 自动接入边选择:与出线边「同轴」优先(规则唯一来源见 docking.ts)——
|
|
1325
|
+
* 从源图形左右边出线就接目标的左/右边(面向来线一侧),从上下边出线就接上/下边;
|
|
1326
|
+
* 这样分支连线才能共用同一条正交主干总线,而不是横着拐进目标顶边。
|
|
1263
1327
|
*/
|
|
1264
1328
|
private pickAutoHandle;
|
|
1265
1329
|
/** auto 绑定 → 按当前几何重选接入边;显式绑定原样返回 */
|
|
1266
1330
|
private resolveAutoEndBinding;
|
|
1267
1331
|
private getBindingPoint;
|
|
1332
|
+
/**
|
|
1333
|
+
* 求某一端的停靠法向。**优先用绑定信息**:绑定已经明确告诉我们是哪个图形的哪条边,
|
|
1334
|
+
* 比几何猜测可靠得多 —— 当有图形与端点所在图形重叠时(典型:新建图形虚框压在源图形上),
|
|
1335
|
+
* 纯几何的 getDockNormal 会挑到「离端点更近的另一张图形」,把出线/接入方向判反。
|
|
1336
|
+
*/
|
|
1337
|
+
private resolveDockNormal;
|
|
1268
1338
|
/**
|
|
1269
1339
|
* 计算端点所在图形的外法向(垂直于该侧边缘,页面坐标单位向量)。
|
|
1270
1340
|
* 用于连线垂直脱离/接入图形边缘,端点不在任何图形上时返回 undefined。
|
|
1341
|
+
* preferShapeId:优先认这个图形(端点正好被多张图形覆盖时用它消歧)。
|
|
1271
1342
|
*/
|
|
1272
1343
|
private getDockNormal;
|
|
1273
1344
|
/**
|
|
@@ -1303,6 +1374,12 @@ declare class Renderer {
|
|
|
1303
1374
|
private drawFreehand;
|
|
1304
1375
|
private drawSelectionOutline;
|
|
1305
1376
|
private drawSelectionHandles;
|
|
1377
|
+
/**
|
|
1378
|
+
* 四边中点的连接锚点(外圈 + 内点)。
|
|
1379
|
+
* bounds 使用调用方的坐标系:选中手柄路径传入「本地包围盒」(画布已 translate 到图形中心),
|
|
1380
|
+
* 悬停提示路径传入「世界包围盒」(画布未平移)。alpha 用于弱化悬停态。
|
|
1381
|
+
*/
|
|
1382
|
+
private drawConnectionDots;
|
|
1306
1383
|
/** 画旋转图标:顺时针短弧 + 箭头 */
|
|
1307
1384
|
private drawRotateIcon;
|
|
1308
1385
|
private getShapeBounds;
|
|
@@ -1354,6 +1431,10 @@ interface ToolContext {
|
|
|
1354
1431
|
setSnapGuides(guides: SnapGuide[]): void;
|
|
1355
1432
|
setConnectingTarget(id: string | null): void;
|
|
1356
1433
|
setGenerationPreview(preview: GenerationPreview | null): void;
|
|
1434
|
+
/** 悬停图形 → 画布为其绘制四边连接锚点(null 清除) */
|
|
1435
|
+
setHoverAnchorShape(id: string | null): void;
|
|
1436
|
+
/** 新建连线的线条样式(颜色/粗细),与最终创建的连线保持一致 */
|
|
1437
|
+
getLineStyle(): ShapeStyle;
|
|
1357
1438
|
/** 拖动到空白处:创建一条浮动线条并弹出"选择新图形"菜单 */
|
|
1358
1439
|
openGenerationMenu(payload: GenerationMenuPayload): void;
|
|
1359
1440
|
/** 创建"新图形 + 连线";existingArrowId 存在时把线条末端接到新图形 */
|
|
@@ -1392,6 +1473,17 @@ declare abstract class Tool {
|
|
|
1392
1473
|
abstract onKeyUp(event: KeyboardEvent): void;
|
|
1393
1474
|
/** 返回当前指针位置应显示的鼠标样式,null 表示使用默认 */
|
|
1394
1475
|
getCursor(_point: Vec2): string | null;
|
|
1476
|
+
/**
|
|
1477
|
+
* 是否正处于一次未结束的交互中(拖拽/生成/框选…)。
|
|
1478
|
+
* 编辑器据此判断「指针没按下却仍有工具状态」= 丢事件,需要自愈。
|
|
1479
|
+
*/
|
|
1480
|
+
hasTransientState(): boolean;
|
|
1481
|
+
/**
|
|
1482
|
+
* 取消一切「瞬态」交互状态(正在拖拽/生成/框选/旋转…),回到干净的空闲态。
|
|
1483
|
+
* 用于指针事件丢失(在窗口外松手、失焦)、点击画布外、切换工具时的自愈。
|
|
1484
|
+
* @returns 是否确实清理了状态(false = 本来就是空闲态,调用方可跳过重绘)
|
|
1485
|
+
*/
|
|
1486
|
+
cancelTransient(): boolean;
|
|
1395
1487
|
dispose(): void;
|
|
1396
1488
|
}
|
|
1397
1489
|
|
|
@@ -1402,6 +1494,8 @@ declare class SelectTool extends Tool {
|
|
|
1402
1494
|
private resizingState;
|
|
1403
1495
|
private generatingState;
|
|
1404
1496
|
private hoverGenPoint;
|
|
1497
|
+
/** 悬停(未按下)的图形 id:为其显示四边连接锚点,可直接从这里拖出连线 */
|
|
1498
|
+
private hoverShapeId;
|
|
1405
1499
|
private rotatingState;
|
|
1406
1500
|
private draggingArrowId;
|
|
1407
1501
|
private draggingTerminal;
|
|
@@ -1410,12 +1504,23 @@ declare class SelectTool extends Tool {
|
|
|
1410
1504
|
private brushShiftKey;
|
|
1411
1505
|
/** 生成点位默认创建的图形类型:源图形若为可创建类型则同型,否则用矩形 */
|
|
1412
1506
|
private defaultGenType;
|
|
1507
|
+
/**
|
|
1508
|
+
* 生成点位预览:带上源图形/出线边/目标绑定/线条样式,画布据此走「与最终创建完全一致」
|
|
1509
|
+
* 的真实渲染路径(正交路由 + 出入桩 + 同轴接入边 + 箭头样式),做到拖拽即所见即所得。
|
|
1510
|
+
*/
|
|
1413
1511
|
private genPreviewOf;
|
|
1414
1512
|
/** 把生成点位打包成创建上下文(from 为源点,to 为目标落点) */
|
|
1415
1513
|
private genContext;
|
|
1416
1514
|
onPointerDown(point: Vec2, event: PointerEvent): void;
|
|
1417
1515
|
onPointerMove(point: Vec2, event: PointerEvent): void;
|
|
1418
1516
|
onPointerUp(point: Vec2, _event: PointerEvent): void;
|
|
1517
|
+
hasTransientState(): boolean;
|
|
1518
|
+
/**
|
|
1519
|
+
* 取消一切瞬态交互(拖拽/生成/框选/旋转/连线端点拖拽)并清掉画布上的瞬态预览。
|
|
1520
|
+
* 触发场景:指针在窗口外松手丢失 pointerup、窗口失焦、点击画布外、无按压的移动、
|
|
1521
|
+
* 切换工具、Esc。返回值用于让调用方决定是否需要重绘。
|
|
1522
|
+
*/
|
|
1523
|
+
cancelTransient(): boolean;
|
|
1419
1524
|
onKeyDown(event: KeyboardEvent): void;
|
|
1420
1525
|
onKeyUp(_event: KeyboardEvent): void;
|
|
1421
1526
|
/** 鼠标样式:伸缩手柄 → 对应方向的双向箭头;拖拽中 → 抓取 */
|
|
@@ -1448,13 +1553,20 @@ declare class SelectTool extends Tool {
|
|
|
1448
1553
|
/** 生成点位命中阈值 / 单击 vs 拖动判定阈值 */
|
|
1449
1554
|
private static readonly GEN_HIT_THRESHOLD;
|
|
1450
1555
|
private static readonly CLICK_MOVE_THRESHOLD;
|
|
1451
|
-
/**
|
|
1556
|
+
/** 支持四边连接锚点的图形类型(矩形类、流程图形、UML 等) */
|
|
1557
|
+
private static readonly GEN_SUPPORTED_TYPES;
|
|
1558
|
+
/**
|
|
1559
|
+
* 收集图形上的全部生成点位(四边中点/快捷连线按钮)。
|
|
1560
|
+
* extraShapeId:额外把某个图形(当前悬停的图形)纳入 —— 未选中图形也能直接连出连线。
|
|
1561
|
+
*/
|
|
1452
1562
|
private computeGenPoints;
|
|
1453
1563
|
/** 命中检测:指针是否落在某个生成点位附近(取最近的) */
|
|
1454
1564
|
private hitGenPoint;
|
|
1565
|
+
/** 悬停(未按下)时指针所在的、支持连线锚点的图形 id(已选中的交给选择手柄,返回 null) */
|
|
1566
|
+
private findHoverAnchorShape;
|
|
1455
1567
|
/** 生成点位预览的落点:拖动时跟随光标;静止/悬浮时向外延伸一个默认位置的框 */
|
|
1456
1568
|
private genPreviewTarget;
|
|
1457
|
-
/**
|
|
1569
|
+
/** 生成拖动:更新预览(真实样式的连线 + 待放置图形虚框)与目标高亮 */
|
|
1458
1570
|
private handleGenerating;
|
|
1459
1571
|
private handleRotating;
|
|
1460
1572
|
/** 根据绑定信息返回目标图形的实际吸附点 */
|
|
@@ -1462,6 +1574,21 @@ declare class SelectTool extends Tool {
|
|
|
1462
1574
|
private isPointInShape;
|
|
1463
1575
|
private isPointInHexagon;
|
|
1464
1576
|
private pointToLineDistance;
|
|
1577
|
+
/**
|
|
1578
|
+
* 待新建图形与源图形重叠时,把它沿「源→目标」方向推到不重叠(留一个引线距离)。
|
|
1579
|
+
*
|
|
1580
|
+
* 为什么必须做:图形重叠时,连线要接入的那条边会落在源图形内部/后方,
|
|
1581
|
+
* 路由只能往回折(实测出现「往右拖一点点 → 一条往回折的钩子甚至横穿的怪线」),
|
|
1582
|
+
* 而且新图形压着源图形本身就不好看。推开后接入边始终在出线方向的前方,
|
|
1583
|
+
* 引线距离取 CONNECTION_LEAD(24),正好让「出线桩 → 接入点」是一条直线。
|
|
1584
|
+
*/
|
|
1585
|
+
private avoidSourceOverlap;
|
|
1586
|
+
/**
|
|
1587
|
+
* 预判「将要新建的图形」面向来线的那个接入点:
|
|
1588
|
+
* 用该类型的真实默认尺寸 + 与 Editor.connectHandle 完全相同的 docking 规则算落点,
|
|
1589
|
+
* 让「拖拽预览 → 松手后的浮动线条 → 插入后的真实连线」位置一致、不跳变。
|
|
1590
|
+
*/
|
|
1591
|
+
private futureDockPoint;
|
|
1465
1592
|
private getShapeBounds;
|
|
1466
1593
|
private hitTestArrowTerminal;
|
|
1467
1594
|
private findShapeNearPoint;
|