@logicflow/extension 2.2.0-alpha.4 → 2.2.0-alpha.6
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +21 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/components/control/index.js +3 -3
- package/es/materials/curved-edge/index.js +49 -21
- package/es/tools/snapshot/index.d.ts +7 -3
- package/es/tools/snapshot/index.js +46 -64
- package/lib/components/control/index.js +3 -3
- package/lib/materials/curved-edge/index.js +49 -21
- package/lib/tools/snapshot/index.d.ts +7 -3
- package/lib/tools/snapshot/index.js +46 -64
- package/package.json +5 -5
- package/src/components/control/index.ts +3 -3
- package/src/materials/curved-edge/index.ts +57 -25
- package/src/tools/snapshot/index.ts +47 -76
- package/stats.html +1 -1
|
@@ -132,14 +132,14 @@ var Control = /** @class */ (function () {
|
|
|
132
132
|
else {
|
|
133
133
|
itemContainer.append(icon);
|
|
134
134
|
}
|
|
135
|
-
switch (item.
|
|
136
|
-
case '
|
|
135
|
+
switch (item.key) {
|
|
136
|
+
case 'undo':
|
|
137
137
|
_this.lf.on('history:change', function (_a) {
|
|
138
138
|
var undoAble = _a.data.undoAble;
|
|
139
139
|
itemContainer.className = undoAble ? NORMAL : DISABLED;
|
|
140
140
|
});
|
|
141
141
|
break;
|
|
142
|
-
case '
|
|
142
|
+
case 'redo':
|
|
143
143
|
_this.lf.on('history:change', function (_a) {
|
|
144
144
|
var redoAble = _a.data.redoAble;
|
|
145
145
|
itemContainer.className = redoAble ? NORMAL : DISABLED;
|
|
@@ -41,6 +41,9 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
41
41
|
return ar;
|
|
42
42
|
};
|
|
43
43
|
import { PolylineEdge, PolylineEdgeModel, h } from '@logicflow/core';
|
|
44
|
+
// 方向组合到圆弧象限的映射。
|
|
45
|
+
// key 由进入方向(dir1)和离开方向(dir2)拼接,例如 'tr' 表示从上(t)到右(r)的拐角。
|
|
46
|
+
// 通过该映射确定在拐点处应该绘制的圆弧象限,用于计算中间控制点。
|
|
44
47
|
var directionMap = {
|
|
45
48
|
tr: 'tl',
|
|
46
49
|
lb: 'tl',
|
|
@@ -51,13 +54,17 @@ var directionMap = {
|
|
|
51
54
|
bl: 'br',
|
|
52
55
|
rt: 'br',
|
|
53
56
|
};
|
|
57
|
+
// 过滤折线中的共线中间点,减少不必要的顶点
|
|
54
58
|
function pointFilter(points) {
|
|
59
|
+
// 原地修改传入的数组
|
|
55
60
|
var all = points;
|
|
61
|
+
// 从第二个点开始,检查三点是否共线
|
|
56
62
|
var i = 1;
|
|
57
63
|
while (i < all.length - 1) {
|
|
58
64
|
var _a = __read(all[i - 1], 2), x = _a[0], y = _a[1];
|
|
59
65
|
var _b = __read(all[i], 2), x1 = _b[0], y1 = _b[1];
|
|
60
66
|
var _c = __read(all[i + 1], 2), x2 = _c[0], y2 = _c[1];
|
|
67
|
+
// 如果三点在同一条水平或垂直直线上,删除中间点
|
|
61
68
|
if ((x === x1 && x1 === x2) || (y === y1 && y1 === y2)) {
|
|
62
69
|
all.splice(i, 1);
|
|
63
70
|
}
|
|
@@ -65,6 +72,7 @@ function pointFilter(points) {
|
|
|
65
72
|
i++;
|
|
66
73
|
}
|
|
67
74
|
}
|
|
75
|
+
// 返回精简后的点集
|
|
68
76
|
return all;
|
|
69
77
|
}
|
|
70
78
|
function getMidPoints(cur, key, orientation, radius) {
|
|
@@ -119,34 +127,54 @@ function getMidPoints(cur, key, orientation, radius) {
|
|
|
119
127
|
return [];
|
|
120
128
|
}
|
|
121
129
|
}
|
|
122
|
-
|
|
130
|
+
/**
|
|
131
|
+
* 生成局部路径片段(包含圆角)
|
|
132
|
+
* - 输入为上一个顶点、当前拐点、下一个顶点,计算方向组合并选择圆弧象限
|
|
133
|
+
* - 将圆角半径限制在相邻两段长度的一半以内,避免过度弯曲
|
|
134
|
+
* @param prevPoint 上一个顶点
|
|
135
|
+
* @param cornerPoint 当前拐点(圆角所在拐点)
|
|
136
|
+
* @param nextPoint 下一个顶点
|
|
137
|
+
* @param cornerRadius 圆角半径上限
|
|
138
|
+
* @returns 局部 path 字符串(包含 L/Q 操作)
|
|
139
|
+
*/
|
|
140
|
+
function getPartialPath(prevPoint, cornerPoint, nextPoint, cornerRadius) {
|
|
123
141
|
var _a;
|
|
124
|
-
|
|
125
|
-
var
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
// 轴对齐容差(像素),用于消除微小误差
|
|
143
|
+
var epsilon = 1;
|
|
144
|
+
var resolveDir = function (a, b) {
|
|
145
|
+
var dx = b[0] - a[0];
|
|
146
|
+
var dy = b[1] - a[1];
|
|
147
|
+
var adx = Math.abs(dx);
|
|
148
|
+
var ady = Math.abs(dy);
|
|
149
|
+
if (ady <= epsilon && adx > epsilon) {
|
|
150
|
+
return dx < 0 ? 'l' : 'r';
|
|
151
|
+
}
|
|
152
|
+
if (adx <= epsilon && ady > epsilon) {
|
|
153
|
+
return dy < 0 ? 't' : 'b';
|
|
154
|
+
}
|
|
155
|
+
if (adx <= epsilon && ady <= epsilon) {
|
|
156
|
+
return '';
|
|
157
|
+
}
|
|
158
|
+
// 非严格对齐时,选择更接近的轴
|
|
159
|
+
return adx < ady ? (dx < 0 ? 'l' : 'r') : dy < 0 ? 't' : 'b';
|
|
160
|
+
};
|
|
161
|
+
var dir1 = resolveDir(prevPoint, cornerPoint);
|
|
162
|
+
var dir2 = resolveDir(cornerPoint, nextPoint);
|
|
163
|
+
var r = Math.min(Math.hypot(cornerPoint[0] - prevPoint[0], cornerPoint[1] - prevPoint[1]) /
|
|
164
|
+
2, Math.hypot(nextPoint[0] - cornerPoint[0], nextPoint[1] - cornerPoint[1]) /
|
|
165
|
+
2, cornerRadius) || (1 / 5) * cornerRadius;
|
|
139
166
|
var key = "".concat(dir1).concat(dir2);
|
|
140
167
|
var orientation = directionMap[key] || '-';
|
|
141
|
-
var path =
|
|
168
|
+
var path = '';
|
|
142
169
|
if (orientation === '-') {
|
|
143
|
-
|
|
170
|
+
// 仅移动到当前拐点,由下一次迭代决定如何从拐点继续(直线或圆角)
|
|
171
|
+
path += "L ".concat(cornerPoint[0], " ").concat(cornerPoint[1]);
|
|
144
172
|
}
|
|
145
173
|
else {
|
|
146
|
-
var _b = __read(getMidPoints(
|
|
174
|
+
var _b = __read(getMidPoints(cornerPoint, key, orientation, r), 2), mid1 = _b[0], mid2 = _b[1];
|
|
147
175
|
if (mid1 && mid2) {
|
|
148
|
-
path += "L ".concat(mid1[0], " ").concat(mid1[1], " Q ").concat(
|
|
149
|
-
_a = __read(mid2, 2),
|
|
176
|
+
path += "L ".concat(mid1[0], " ").concat(mid1[1], " Q ").concat(cornerPoint[0], " ").concat(cornerPoint[1], " ").concat(mid2[0], " ").concat(mid2[1]);
|
|
177
|
+
_a = __read(mid2, 2), cornerPoint[0] = _a[0], cornerPoint[1] = _a[1];
|
|
150
178
|
}
|
|
151
179
|
}
|
|
152
180
|
return path;
|
|
@@ -110,10 +110,14 @@ export declare class Snapshot {
|
|
|
110
110
|
*/
|
|
111
111
|
private getClassRules;
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
113
|
+
* 根据浏览器对 canvas 的大小限制,计算等比缩放比例
|
|
114
|
+
* - 参考 MDN 最大的画布尺寸:
|
|
115
|
+
* https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements/canvas#最大的画布尺寸
|
|
116
|
+
*
|
|
117
|
+
* @param width
|
|
118
|
+
* @param height
|
|
115
119
|
*/
|
|
116
|
-
private
|
|
120
|
+
private getCanvasScaleRatio;
|
|
117
121
|
/**
|
|
118
122
|
* 将 svg 转化为 canvas
|
|
119
123
|
* @param svg - svg 元素
|
|
@@ -345,24 +345,28 @@ var Snapshot = /** @class */ (function () {
|
|
|
345
345
|
return rules;
|
|
346
346
|
};
|
|
347
347
|
/**
|
|
348
|
-
*
|
|
349
|
-
*
|
|
348
|
+
* 根据浏览器对 canvas 的大小限制,计算等比缩放比例
|
|
349
|
+
* - 参考 MDN 最大的画布尺寸:
|
|
350
|
+
* https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements/canvas#最大的画布尺寸
|
|
351
|
+
*
|
|
352
|
+
* @param width
|
|
353
|
+
* @param height
|
|
350
354
|
*/
|
|
351
|
-
Snapshot.prototype.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
var
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
355
|
+
Snapshot.prototype.getCanvasScaleRatio = function (width, height) {
|
|
356
|
+
/* 单边最大像素 */
|
|
357
|
+
var maxCanvasSide = 32767;
|
|
358
|
+
/* 最大像素面积 */
|
|
359
|
+
var maxCanvasArea = 268435456;
|
|
360
|
+
var area = width * height;
|
|
361
|
+
if (width <= maxCanvasSide &&
|
|
362
|
+
height <= maxCanvasSide &&
|
|
363
|
+
area <= maxCanvasArea) {
|
|
364
|
+
return 1;
|
|
360
365
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
return { maxCanvasDimension: maxCanvasDimension, otherMaxCanvasDimension: otherMaxCanvasDimension };
|
|
366
|
+
var widthScale = maxCanvasSide / width;
|
|
367
|
+
var heightScale = maxCanvasSide / height;
|
|
368
|
+
var areaScale = maxCanvasArea / area;
|
|
369
|
+
return Math.min(widthScale, heightScale, areaScale);
|
|
366
370
|
};
|
|
367
371
|
/**
|
|
368
372
|
* 将 svg 转化为 canvas
|
|
@@ -372,14 +376,14 @@ var Snapshot = /** @class */ (function () {
|
|
|
372
376
|
*/
|
|
373
377
|
Snapshot.prototype.getCanvasData = function (svg, toImageOptions) {
|
|
374
378
|
return __awaiter(this, void 0, void 0, function () {
|
|
375
|
-
var width, height, backgroundColor, _a, padding, copy, dpr, base, bbox, layoutCanvas, layout, offsetX, offsetY, graphModel, transformModel, SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y, safetyFactor, actualWidth, actualHeight, bboxWidth, bboxHeight, canvas, safetyMargin,
|
|
376
|
-
return __generator(this, function (
|
|
377
|
-
switch (
|
|
379
|
+
var width, height, backgroundColor, _a, padding, copy, dpr, base, bbox, layoutCanvas, layout, offsetX, offsetY, graphModel, transformModel, SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y, safetyFactor, actualWidth, actualHeight, factorWidth, factorHeight, bboxWidth, bboxHeight, canvas, safetyMargin, targetWidth, targetHeight, scaleRatio, ctx, img, style, foreignObject;
|
|
380
|
+
return __generator(this, function (_b) {
|
|
381
|
+
switch (_b.label) {
|
|
378
382
|
case 0:
|
|
379
383
|
width = toImageOptions.width, height = toImageOptions.height, backgroundColor = toImageOptions.backgroundColor, _a = toImageOptions.padding, padding = _a === void 0 ? 40 : _a;
|
|
380
384
|
return [4 /*yield*/, this.cloneSvg(svg, false)];
|
|
381
385
|
case 1:
|
|
382
|
-
copy =
|
|
386
|
+
copy = _b.sent();
|
|
383
387
|
dpr = window.devicePixelRatio || 1;
|
|
384
388
|
if (dpr < 1) {
|
|
385
389
|
// https://github.com/didi/LogicFlow/issues/1222
|
|
@@ -404,62 +408,42 @@ var Snapshot = /** @class */ (function () {
|
|
|
404
408
|
graphModel = this.lf.graphModel;
|
|
405
409
|
transformModel = graphModel.transformModel;
|
|
406
410
|
SCALE_X = transformModel.SCALE_X, SCALE_Y = transformModel.SCALE_Y, TRANSLATE_X = transformModel.TRANSLATE_X, TRANSLATE_Y = transformModel.TRANSLATE_Y;
|
|
407
|
-
safetyFactor = toImageOptions.safetyFactor || 1
|
|
411
|
+
safetyFactor = toImageOptions.safetyFactor || 1 // 安全系数,增加10%的空间
|
|
408
412
|
;
|
|
409
|
-
actualWidth =
|
|
410
|
-
actualHeight =
|
|
411
|
-
|
|
412
|
-
|
|
413
|
+
actualWidth = bbox.width / SCALE_X;
|
|
414
|
+
actualHeight = bbox.height / SCALE_Y;
|
|
415
|
+
factorWidth = actualWidth * (safetyFactor - 1);
|
|
416
|
+
factorHeight = actualHeight * (safetyFactor - 1);
|
|
417
|
+
bboxWidth = Math.ceil(actualWidth + factorWidth);
|
|
418
|
+
bboxHeight = Math.ceil(actualHeight + factorHeight);
|
|
413
419
|
canvas = document.createElement('canvas');
|
|
414
420
|
canvas.style.width = "".concat(bboxWidth, "px");
|
|
415
421
|
canvas.style.height = "".concat(bboxHeight, "px");
|
|
416
|
-
safetyMargin = toImageOptions.safetyMargin ||
|
|
422
|
+
safetyMargin = toImageOptions.safetyMargin || 0 // 额外的安全边距
|
|
417
423
|
;
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
;
|
|
425
|
-
scaleHeight = 1 //高 缩放
|
|
426
|
-
;
|
|
427
|
-
// 对宽和高分别进行缩放,如chrome,矩形单边最大宽度不超过65535,如宽超过65535,那么高不能超过4096,否则像素会超,也会显示不出。
|
|
428
|
-
if (targetWidth > MAX_CANVAS_DIMENSION &&
|
|
429
|
-
targetHeight > OTHER_MAX_CANVAS_DIMENSION) {
|
|
430
|
-
scaleWidth = MAX_CANVAS_DIMENSION / targetWidth;
|
|
431
|
-
scaleHeight = OTHER_MAX_CANVAS_DIMENSION / targetHeight;
|
|
432
|
-
}
|
|
433
|
-
else if (targetWidth > OTHER_MAX_CANVAS_DIMENSION &&
|
|
434
|
-
targetHeight > MAX_CANVAS_DIMENSION) {
|
|
435
|
-
scaleWidth = OTHER_MAX_CANVAS_DIMENSION / targetWidth;
|
|
436
|
-
scaleHeight = MAX_CANVAS_DIMENSION / targetHeight;
|
|
437
|
-
}
|
|
438
|
-
else if (targetWidth > MAX_CANVAS_DIMENSION &&
|
|
439
|
-
targetHeight < OTHER_MAX_CANVAS_DIMENSION) {
|
|
440
|
-
scaleHeight = scaleWidth = MAX_CANVAS_DIMENSION / targetWidth;
|
|
441
|
-
}
|
|
442
|
-
else if (targetWidth < OTHER_MAX_CANVAS_DIMENSION &&
|
|
443
|
-
targetHeight > MAX_CANVAS_DIMENSION) {
|
|
444
|
-
scaleHeight = scaleWidth = MAX_CANVAS_DIMENSION / targetHeight;
|
|
445
|
-
}
|
|
446
|
-
if (scaleWidth < 1 || scaleHeight < 1) {
|
|
447
|
-
targetWidth = Math.floor(targetWidth * scaleWidth);
|
|
448
|
-
targetHeight = Math.floor(targetHeight * scaleHeight);
|
|
424
|
+
targetWidth = bboxWidth * dpr;
|
|
425
|
+
targetHeight = bboxHeight * dpr;
|
|
426
|
+
scaleRatio = this.getCanvasScaleRatio(targetWidth, targetHeight);
|
|
427
|
+
if (scaleRatio < 1) {
|
|
428
|
+
targetWidth = Math.floor(targetWidth * scaleRatio);
|
|
429
|
+
targetHeight = Math.floor(targetHeight * scaleRatio);
|
|
449
430
|
}
|
|
450
431
|
// 将导出区域移动到左上角,canvas 绘制的时候是从左上角开始绘制的
|
|
451
432
|
// 在transform矩阵中加入padding值,确保左侧元素不会被截断
|
|
452
433
|
// 对这个矩阵进行缩放,否则会导致截断
|
|
453
434
|
;
|
|
454
435
|
copy.lastChild.style.transform =
|
|
455
|
-
"matrix(".concat(
|
|
456
|
-
|
|
457
|
-
|
|
436
|
+
"matrix(".concat(scaleRatio, ", 0, 0, ").concat(scaleRatio, ", ").concat((-offsetX + TRANSLATE_X) * (1 / SCALE_X) * scaleRatio +
|
|
437
|
+
padding +
|
|
438
|
+
factorWidth / 2 +
|
|
439
|
+
safetyMargin, ", ").concat((-offsetY + TRANSLATE_Y) * (1 / SCALE_Y) * scaleRatio + padding + factorHeight / 2 + safetyMargin, ")");
|
|
440
|
+
canvas.width = targetWidth + (padding + safetyMargin) * 2 * dpr;
|
|
441
|
+
canvas.height = targetHeight + (padding + safetyMargin) * 2 * dpr;
|
|
458
442
|
ctx = canvas.getContext('2d');
|
|
459
443
|
if (ctx) {
|
|
460
444
|
// 清空canvas
|
|
461
445
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
462
|
-
ctx.scale(dpr
|
|
446
|
+
ctx.scale(dpr, dpr);
|
|
463
447
|
// 如果有背景色,设置流程图导出的背景色
|
|
464
448
|
if (backgroundColor) {
|
|
465
449
|
ctx.fillStyle = backgroundColor;
|
|
@@ -717,9 +701,7 @@ var Snapshot = /** @class */ (function () {
|
|
|
717
701
|
var _this = this;
|
|
718
702
|
return __generator(this, function (_a) {
|
|
719
703
|
switch (_a.label) {
|
|
720
|
-
case 0:
|
|
721
|
-
console.log('getSnapshotBase64---------------', backgroundColor, fileType, toImageOptions);
|
|
722
|
-
return [4 /*yield*/, this.withExportPreparation(function () { return _this._getSnapshotBase64(backgroundColor, fileType, toImageOptions); }, toImageOptions)];
|
|
704
|
+
case 0: return [4 /*yield*/, this.withExportPreparation(function () { return _this._getSnapshotBase64(backgroundColor, fileType, toImageOptions); }, toImageOptions)];
|
|
723
705
|
case 1: return [2 /*return*/, _a.sent()];
|
|
724
706
|
}
|
|
725
707
|
});
|
|
@@ -135,14 +135,14 @@ var Control = /** @class */ (function () {
|
|
|
135
135
|
else {
|
|
136
136
|
itemContainer.append(icon);
|
|
137
137
|
}
|
|
138
|
-
switch (item.
|
|
139
|
-
case '
|
|
138
|
+
switch (item.key) {
|
|
139
|
+
case 'undo':
|
|
140
140
|
_this.lf.on('history:change', function (_a) {
|
|
141
141
|
var undoAble = _a.data.undoAble;
|
|
142
142
|
itemContainer.className = undoAble ? NORMAL : DISABLED;
|
|
143
143
|
});
|
|
144
144
|
break;
|
|
145
|
-
case '
|
|
145
|
+
case 'redo':
|
|
146
146
|
_this.lf.on('history:change', function (_a) {
|
|
147
147
|
var redoAble = _a.data.redoAble;
|
|
148
148
|
itemContainer.className = redoAble ? NORMAL : DISABLED;
|
|
@@ -44,6 +44,9 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
45
|
exports.getCurvedEdgePath = exports.CurvedEdgeModel = exports.CurvedEdge = void 0;
|
|
46
46
|
var core_1 = require("@logicflow/core");
|
|
47
|
+
// 方向组合到圆弧象限的映射。
|
|
48
|
+
// key 由进入方向(dir1)和离开方向(dir2)拼接,例如 'tr' 表示从上(t)到右(r)的拐角。
|
|
49
|
+
// 通过该映射确定在拐点处应该绘制的圆弧象限,用于计算中间控制点。
|
|
47
50
|
var directionMap = {
|
|
48
51
|
tr: 'tl',
|
|
49
52
|
lb: 'tl',
|
|
@@ -54,13 +57,17 @@ var directionMap = {
|
|
|
54
57
|
bl: 'br',
|
|
55
58
|
rt: 'br',
|
|
56
59
|
};
|
|
60
|
+
// 过滤折线中的共线中间点,减少不必要的顶点
|
|
57
61
|
function pointFilter(points) {
|
|
62
|
+
// 原地修改传入的数组
|
|
58
63
|
var all = points;
|
|
64
|
+
// 从第二个点开始,检查三点是否共线
|
|
59
65
|
var i = 1;
|
|
60
66
|
while (i < all.length - 1) {
|
|
61
67
|
var _a = __read(all[i - 1], 2), x = _a[0], y = _a[1];
|
|
62
68
|
var _b = __read(all[i], 2), x1 = _b[0], y1 = _b[1];
|
|
63
69
|
var _c = __read(all[i + 1], 2), x2 = _c[0], y2 = _c[1];
|
|
70
|
+
// 如果三点在同一条水平或垂直直线上,删除中间点
|
|
64
71
|
if ((x === x1 && x1 === x2) || (y === y1 && y1 === y2)) {
|
|
65
72
|
all.splice(i, 1);
|
|
66
73
|
}
|
|
@@ -68,6 +75,7 @@ function pointFilter(points) {
|
|
|
68
75
|
i++;
|
|
69
76
|
}
|
|
70
77
|
}
|
|
78
|
+
// 返回精简后的点集
|
|
71
79
|
return all;
|
|
72
80
|
}
|
|
73
81
|
function getMidPoints(cur, key, orientation, radius) {
|
|
@@ -122,34 +130,54 @@ function getMidPoints(cur, key, orientation, radius) {
|
|
|
122
130
|
return [];
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
|
-
|
|
133
|
+
/**
|
|
134
|
+
* 生成局部路径片段(包含圆角)
|
|
135
|
+
* - 输入为上一个顶点、当前拐点、下一个顶点,计算方向组合并选择圆弧象限
|
|
136
|
+
* - 将圆角半径限制在相邻两段长度的一半以内,避免过度弯曲
|
|
137
|
+
* @param prevPoint 上一个顶点
|
|
138
|
+
* @param cornerPoint 当前拐点(圆角所在拐点)
|
|
139
|
+
* @param nextPoint 下一个顶点
|
|
140
|
+
* @param cornerRadius 圆角半径上限
|
|
141
|
+
* @returns 局部 path 字符串(包含 L/Q 操作)
|
|
142
|
+
*/
|
|
143
|
+
function getPartialPath(prevPoint, cornerPoint, nextPoint, cornerRadius) {
|
|
126
144
|
var _a;
|
|
127
|
-
|
|
128
|
-
var
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
145
|
+
// 轴对齐容差(像素),用于消除微小误差
|
|
146
|
+
var epsilon = 1;
|
|
147
|
+
var resolveDir = function (a, b) {
|
|
148
|
+
var dx = b[0] - a[0];
|
|
149
|
+
var dy = b[1] - a[1];
|
|
150
|
+
var adx = Math.abs(dx);
|
|
151
|
+
var ady = Math.abs(dy);
|
|
152
|
+
if (ady <= epsilon && adx > epsilon) {
|
|
153
|
+
return dx < 0 ? 'l' : 'r';
|
|
154
|
+
}
|
|
155
|
+
if (adx <= epsilon && ady > epsilon) {
|
|
156
|
+
return dy < 0 ? 't' : 'b';
|
|
157
|
+
}
|
|
158
|
+
if (adx <= epsilon && ady <= epsilon) {
|
|
159
|
+
return '';
|
|
160
|
+
}
|
|
161
|
+
// 非严格对齐时,选择更接近的轴
|
|
162
|
+
return adx < ady ? (dx < 0 ? 'l' : 'r') : dy < 0 ? 't' : 'b';
|
|
163
|
+
};
|
|
164
|
+
var dir1 = resolveDir(prevPoint, cornerPoint);
|
|
165
|
+
var dir2 = resolveDir(cornerPoint, nextPoint);
|
|
166
|
+
var r = Math.min(Math.hypot(cornerPoint[0] - prevPoint[0], cornerPoint[1] - prevPoint[1]) /
|
|
167
|
+
2, Math.hypot(nextPoint[0] - cornerPoint[0], nextPoint[1] - cornerPoint[1]) /
|
|
168
|
+
2, cornerRadius) || (1 / 5) * cornerRadius;
|
|
142
169
|
var key = "".concat(dir1).concat(dir2);
|
|
143
170
|
var orientation = directionMap[key] || '-';
|
|
144
|
-
var path =
|
|
171
|
+
var path = '';
|
|
145
172
|
if (orientation === '-') {
|
|
146
|
-
|
|
173
|
+
// 仅移动到当前拐点,由下一次迭代决定如何从拐点继续(直线或圆角)
|
|
174
|
+
path += "L ".concat(cornerPoint[0], " ").concat(cornerPoint[1]);
|
|
147
175
|
}
|
|
148
176
|
else {
|
|
149
|
-
var _b = __read(getMidPoints(
|
|
177
|
+
var _b = __read(getMidPoints(cornerPoint, key, orientation, r), 2), mid1 = _b[0], mid2 = _b[1];
|
|
150
178
|
if (mid1 && mid2) {
|
|
151
|
-
path += "L ".concat(mid1[0], " ").concat(mid1[1], " Q ").concat(
|
|
152
|
-
_a = __read(mid2, 2),
|
|
179
|
+
path += "L ".concat(mid1[0], " ").concat(mid1[1], " Q ").concat(cornerPoint[0], " ").concat(cornerPoint[1], " ").concat(mid2[0], " ").concat(mid2[1]);
|
|
180
|
+
_a = __read(mid2, 2), cornerPoint[0] = _a[0], cornerPoint[1] = _a[1];
|
|
153
181
|
}
|
|
154
182
|
}
|
|
155
183
|
return path;
|
|
@@ -110,10 +110,14 @@ export declare class Snapshot {
|
|
|
110
110
|
*/
|
|
111
111
|
private getClassRules;
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
113
|
+
* 根据浏览器对 canvas 的大小限制,计算等比缩放比例
|
|
114
|
+
* - 参考 MDN 最大的画布尺寸:
|
|
115
|
+
* https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements/canvas#最大的画布尺寸
|
|
116
|
+
*
|
|
117
|
+
* @param width
|
|
118
|
+
* @param height
|
|
115
119
|
*/
|
|
116
|
-
private
|
|
120
|
+
private getCanvasScaleRatio;
|
|
117
121
|
/**
|
|
118
122
|
* 将 svg 转化为 canvas
|
|
119
123
|
* @param svg - svg 元素
|
|
@@ -348,24 +348,28 @@ var Snapshot = /** @class */ (function () {
|
|
|
348
348
|
return rules;
|
|
349
349
|
};
|
|
350
350
|
/**
|
|
351
|
-
*
|
|
352
|
-
*
|
|
351
|
+
* 根据浏览器对 canvas 的大小限制,计算等比缩放比例
|
|
352
|
+
* - 参考 MDN 最大的画布尺寸:
|
|
353
|
+
* https://developer.mozilla.org/zh-CN/docs/Web/HTML/Reference/Elements/canvas#最大的画布尺寸
|
|
354
|
+
*
|
|
355
|
+
* @param width
|
|
356
|
+
* @param height
|
|
353
357
|
*/
|
|
354
|
-
Snapshot.prototype.
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
var
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
358
|
+
Snapshot.prototype.getCanvasScaleRatio = function (width, height) {
|
|
359
|
+
/* 单边最大像素 */
|
|
360
|
+
var maxCanvasSide = 32767;
|
|
361
|
+
/* 最大像素面积 */
|
|
362
|
+
var maxCanvasArea = 268435456;
|
|
363
|
+
var area = width * height;
|
|
364
|
+
if (width <= maxCanvasSide &&
|
|
365
|
+
height <= maxCanvasSide &&
|
|
366
|
+
area <= maxCanvasArea) {
|
|
367
|
+
return 1;
|
|
363
368
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
return { maxCanvasDimension: maxCanvasDimension, otherMaxCanvasDimension: otherMaxCanvasDimension };
|
|
369
|
+
var widthScale = maxCanvasSide / width;
|
|
370
|
+
var heightScale = maxCanvasSide / height;
|
|
371
|
+
var areaScale = maxCanvasArea / area;
|
|
372
|
+
return Math.min(widthScale, heightScale, areaScale);
|
|
369
373
|
};
|
|
370
374
|
/**
|
|
371
375
|
* 将 svg 转化为 canvas
|
|
@@ -375,14 +379,14 @@ var Snapshot = /** @class */ (function () {
|
|
|
375
379
|
*/
|
|
376
380
|
Snapshot.prototype.getCanvasData = function (svg, toImageOptions) {
|
|
377
381
|
return __awaiter(this, void 0, void 0, function () {
|
|
378
|
-
var width, height, backgroundColor, _a, padding, copy, dpr, base, bbox, layoutCanvas, layout, offsetX, offsetY, graphModel, transformModel, SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y, safetyFactor, actualWidth, actualHeight, bboxWidth, bboxHeight, canvas, safetyMargin,
|
|
379
|
-
return __generator(this, function (
|
|
380
|
-
switch (
|
|
382
|
+
var width, height, backgroundColor, _a, padding, copy, dpr, base, bbox, layoutCanvas, layout, offsetX, offsetY, graphModel, transformModel, SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y, safetyFactor, actualWidth, actualHeight, factorWidth, factorHeight, bboxWidth, bboxHeight, canvas, safetyMargin, targetWidth, targetHeight, scaleRatio, ctx, img, style, foreignObject;
|
|
383
|
+
return __generator(this, function (_b) {
|
|
384
|
+
switch (_b.label) {
|
|
381
385
|
case 0:
|
|
382
386
|
width = toImageOptions.width, height = toImageOptions.height, backgroundColor = toImageOptions.backgroundColor, _a = toImageOptions.padding, padding = _a === void 0 ? 40 : _a;
|
|
383
387
|
return [4 /*yield*/, this.cloneSvg(svg, false)];
|
|
384
388
|
case 1:
|
|
385
|
-
copy =
|
|
389
|
+
copy = _b.sent();
|
|
386
390
|
dpr = window.devicePixelRatio || 1;
|
|
387
391
|
if (dpr < 1) {
|
|
388
392
|
// https://github.com/didi/LogicFlow/issues/1222
|
|
@@ -407,62 +411,42 @@ var Snapshot = /** @class */ (function () {
|
|
|
407
411
|
graphModel = this.lf.graphModel;
|
|
408
412
|
transformModel = graphModel.transformModel;
|
|
409
413
|
SCALE_X = transformModel.SCALE_X, SCALE_Y = transformModel.SCALE_Y, TRANSLATE_X = transformModel.TRANSLATE_X, TRANSLATE_Y = transformModel.TRANSLATE_Y;
|
|
410
|
-
safetyFactor = toImageOptions.safetyFactor || 1
|
|
414
|
+
safetyFactor = toImageOptions.safetyFactor || 1 // 安全系数,增加10%的空间
|
|
411
415
|
;
|
|
412
|
-
actualWidth =
|
|
413
|
-
actualHeight =
|
|
414
|
-
|
|
415
|
-
|
|
416
|
+
actualWidth = bbox.width / SCALE_X;
|
|
417
|
+
actualHeight = bbox.height / SCALE_Y;
|
|
418
|
+
factorWidth = actualWidth * (safetyFactor - 1);
|
|
419
|
+
factorHeight = actualHeight * (safetyFactor - 1);
|
|
420
|
+
bboxWidth = Math.ceil(actualWidth + factorWidth);
|
|
421
|
+
bboxHeight = Math.ceil(actualHeight + factorHeight);
|
|
416
422
|
canvas = document.createElement('canvas');
|
|
417
423
|
canvas.style.width = "".concat(bboxWidth, "px");
|
|
418
424
|
canvas.style.height = "".concat(bboxHeight, "px");
|
|
419
|
-
safetyMargin = toImageOptions.safetyMargin ||
|
|
425
|
+
safetyMargin = toImageOptions.safetyMargin || 0 // 额外的安全边距
|
|
420
426
|
;
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
;
|
|
428
|
-
scaleHeight = 1 //高 缩放
|
|
429
|
-
;
|
|
430
|
-
// 对宽和高分别进行缩放,如chrome,矩形单边最大宽度不超过65535,如宽超过65535,那么高不能超过4096,否则像素会超,也会显示不出。
|
|
431
|
-
if (targetWidth > MAX_CANVAS_DIMENSION &&
|
|
432
|
-
targetHeight > OTHER_MAX_CANVAS_DIMENSION) {
|
|
433
|
-
scaleWidth = MAX_CANVAS_DIMENSION / targetWidth;
|
|
434
|
-
scaleHeight = OTHER_MAX_CANVAS_DIMENSION / targetHeight;
|
|
435
|
-
}
|
|
436
|
-
else if (targetWidth > OTHER_MAX_CANVAS_DIMENSION &&
|
|
437
|
-
targetHeight > MAX_CANVAS_DIMENSION) {
|
|
438
|
-
scaleWidth = OTHER_MAX_CANVAS_DIMENSION / targetWidth;
|
|
439
|
-
scaleHeight = MAX_CANVAS_DIMENSION / targetHeight;
|
|
440
|
-
}
|
|
441
|
-
else if (targetWidth > MAX_CANVAS_DIMENSION &&
|
|
442
|
-
targetHeight < OTHER_MAX_CANVAS_DIMENSION) {
|
|
443
|
-
scaleHeight = scaleWidth = MAX_CANVAS_DIMENSION / targetWidth;
|
|
444
|
-
}
|
|
445
|
-
else if (targetWidth < OTHER_MAX_CANVAS_DIMENSION &&
|
|
446
|
-
targetHeight > MAX_CANVAS_DIMENSION) {
|
|
447
|
-
scaleHeight = scaleWidth = MAX_CANVAS_DIMENSION / targetHeight;
|
|
448
|
-
}
|
|
449
|
-
if (scaleWidth < 1 || scaleHeight < 1) {
|
|
450
|
-
targetWidth = Math.floor(targetWidth * scaleWidth);
|
|
451
|
-
targetHeight = Math.floor(targetHeight * scaleHeight);
|
|
427
|
+
targetWidth = bboxWidth * dpr;
|
|
428
|
+
targetHeight = bboxHeight * dpr;
|
|
429
|
+
scaleRatio = this.getCanvasScaleRatio(targetWidth, targetHeight);
|
|
430
|
+
if (scaleRatio < 1) {
|
|
431
|
+
targetWidth = Math.floor(targetWidth * scaleRatio);
|
|
432
|
+
targetHeight = Math.floor(targetHeight * scaleRatio);
|
|
452
433
|
}
|
|
453
434
|
// 将导出区域移动到左上角,canvas 绘制的时候是从左上角开始绘制的
|
|
454
435
|
// 在transform矩阵中加入padding值,确保左侧元素不会被截断
|
|
455
436
|
// 对这个矩阵进行缩放,否则会导致截断
|
|
456
437
|
;
|
|
457
438
|
copy.lastChild.style.transform =
|
|
458
|
-
"matrix(".concat(
|
|
459
|
-
|
|
460
|
-
|
|
439
|
+
"matrix(".concat(scaleRatio, ", 0, 0, ").concat(scaleRatio, ", ").concat((-offsetX + TRANSLATE_X) * (1 / SCALE_X) * scaleRatio +
|
|
440
|
+
padding +
|
|
441
|
+
factorWidth / 2 +
|
|
442
|
+
safetyMargin, ", ").concat((-offsetY + TRANSLATE_Y) * (1 / SCALE_Y) * scaleRatio + padding + factorHeight / 2 + safetyMargin, ")");
|
|
443
|
+
canvas.width = targetWidth + (padding + safetyMargin) * 2 * dpr;
|
|
444
|
+
canvas.height = targetHeight + (padding + safetyMargin) * 2 * dpr;
|
|
461
445
|
ctx = canvas.getContext('2d');
|
|
462
446
|
if (ctx) {
|
|
463
447
|
// 清空canvas
|
|
464
448
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
465
|
-
ctx.scale(dpr
|
|
449
|
+
ctx.scale(dpr, dpr);
|
|
466
450
|
// 如果有背景色,设置流程图导出的背景色
|
|
467
451
|
if (backgroundColor) {
|
|
468
452
|
ctx.fillStyle = backgroundColor;
|
|
@@ -720,9 +704,7 @@ var Snapshot = /** @class */ (function () {
|
|
|
720
704
|
var _this = this;
|
|
721
705
|
return __generator(this, function (_a) {
|
|
722
706
|
switch (_a.label) {
|
|
723
|
-
case 0:
|
|
724
|
-
console.log('getSnapshotBase64---------------', backgroundColor, fileType, toImageOptions);
|
|
725
|
-
return [4 /*yield*/, this.withExportPreparation(function () { return _this._getSnapshotBase64(backgroundColor, fileType, toImageOptions); }, toImageOptions)];
|
|
707
|
+
case 0: return [4 /*yield*/, this.withExportPreparation(function () { return _this._getSnapshotBase64(backgroundColor, fileType, toImageOptions); }, toImageOptions)];
|
|
726
708
|
case 1: return [2 /*return*/, _a.sent()];
|
|
727
709
|
}
|
|
728
710
|
});
|