@logicflow/extension 2.0.0-beta.9 → 2.0.1
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 +387 -754
- package/CHANGELOG.md +812 -1253
- package/dist/index.css +0 -63
- package/dist/index.min.js +16 -16
- package/es/bpmn-adapter/index.js +1 -1
- package/es/bpmn-adapter/index.js.map +1 -1
- package/es/bpmn-elements-adapter/index.js +1 -1
- package/es/bpmn-elements-adapter/index.js.map +1 -1
- package/es/components/highlight/index.d.ts +6 -4
- package/es/components/highlight/index.js +36 -5
- package/es/components/highlight/index.js.map +1 -1
- package/es/components/mini-map/index.d.ts +1 -1
- package/es/components/mini-map/index.js +1 -1
- package/es/components/selection-select/index.js +14 -6
- package/es/components/selection-select/index.js.map +1 -1
- package/es/dynamic-group/index.js +3 -4
- package/es/dynamic-group/index.js.map +1 -1
- package/es/dynamic-group/model.d.ts +3 -3
- package/es/dynamic-group/model.js +12 -9
- package/es/dynamic-group/model.js.map +1 -1
- package/es/dynamic-group/node.js +19 -0
- package/es/dynamic-group/node.js.map +1 -1
- package/es/dynamic-group/utils.d.ts +5 -3
- package/es/dynamic-group/utils.js +14 -7
- package/es/dynamic-group/utils.js.map +1 -1
- package/es/index.css +0 -63
- package/es/index.d.ts +2 -0
- package/es/index.js +3 -0
- package/es/index.js.map +1 -1
- package/es/style/index.css +0 -63
- package/es/style/index.less +0 -73
- package/es/style/raw.d.ts +1 -1
- package/es/style/raw.js +1 -1
- package/es/style/raw.js.map +1 -1
- package/es/tools/label/LabelOverlay.js.map +1 -1
- package/es/tools/label/index.d.ts +1 -0
- package/es/tools/label/index.js +13 -3
- package/es/tools/label/index.js.map +1 -1
- package/es/tools/label/mediumEditor.d.ts +1 -0
- package/es/tools/label/mediumEditor.js +1 -0
- package/es/tools/label/mediumEditor.js.map +1 -1
- package/es/tools/label/style.css +63 -0
- package/es/tools/label/style.less +71 -0
- package/es/tools/snapshot/index.d.ts +9 -9
- package/es/tools/snapshot/index.js +15 -15
- package/es/tools/snapshot/index.js.map +1 -1
- package/lib/bpmn-adapter/index.js +1 -1
- package/lib/bpmn-adapter/index.js.map +1 -1
- package/lib/bpmn-elements-adapter/index.js +1 -1
- package/lib/bpmn-elements-adapter/index.js.map +1 -1
- package/lib/components/highlight/index.d.ts +6 -4
- package/lib/components/highlight/index.js +36 -5
- package/lib/components/highlight/index.js.map +1 -1
- package/lib/components/mini-map/index.d.ts +1 -1
- package/lib/components/mini-map/index.js +1 -1
- package/lib/components/selection-select/index.js +14 -6
- package/lib/components/selection-select/index.js.map +1 -1
- package/lib/dynamic-group/index.js +3 -4
- package/lib/dynamic-group/index.js.map +1 -1
- package/lib/dynamic-group/model.d.ts +3 -3
- package/lib/dynamic-group/model.js +12 -9
- package/lib/dynamic-group/model.js.map +1 -1
- package/lib/dynamic-group/node.js +19 -0
- package/lib/dynamic-group/node.js.map +1 -1
- package/lib/dynamic-group/utils.d.ts +5 -3
- package/lib/dynamic-group/utils.js +14 -7
- package/lib/dynamic-group/utils.js.map +1 -1
- package/lib/index.css +0 -63
- package/lib/index.d.ts +2 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/style/index.css +0 -63
- package/lib/style/index.less +0 -73
- package/lib/style/raw.d.ts +1 -1
- package/lib/style/raw.js +1 -1
- package/lib/style/raw.js.map +1 -1
- package/lib/tools/label/LabelOverlay.js.map +1 -1
- package/lib/tools/label/index.d.ts +1 -0
- package/lib/tools/label/index.js +13 -3
- package/lib/tools/label/index.js.map +1 -1
- package/lib/tools/label/mediumEditor.d.ts +1 -0
- package/lib/tools/label/mediumEditor.js +1 -0
- package/lib/tools/label/mediumEditor.js.map +1 -1
- package/lib/tools/label/style.css +63 -0
- package/lib/tools/label/style.less +71 -0
- package/lib/tools/snapshot/index.d.ts +9 -9
- package/lib/tools/snapshot/index.js +15 -15
- package/lib/tools/snapshot/index.js.map +1 -1
- package/package.json +10 -4
- package/rollup.config.js +17 -1
- package/src/bpmn-adapter/index.ts +1 -1
- package/src/bpmn-elements-adapter/README.md +1 -3
- package/src/bpmn-elements-adapter/index.ts +1 -1
- package/src/components/highlight/index.ts +35 -6
- package/src/components/mini-map/index.ts +6 -6
- package/src/components/selection-select/index.ts +14 -6
- package/src/dynamic-group/index.ts +3 -4
- package/src/dynamic-group/model.ts +17 -11
- package/src/dynamic-group/node.ts +25 -1
- package/src/dynamic-group/utils.ts +20 -7
- package/src/index.ts +5 -0
- package/src/style/index.less +0 -73
- package/src/style/raw.ts +1 -64
- package/src/tools/label/LabelOverlay.tsx +0 -1
- package/src/tools/label/index.ts +16 -7
- package/src/tools/label/mediumEditor.ts +1 -0
- package/src/tools/label/style.less +71 -0
- package/src/tools/snapshot/index.ts +19 -15
|
@@ -19,15 +19,28 @@ export function isBoundsInGroup(bounds: BoxBoundsPoint, group: BaseNodeModel) {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* 判断 bounds 是否可以移动到下一个范围
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
22
|
+
* @param groupBounds
|
|
23
|
+
* @param node
|
|
24
|
+
* @param deltaX
|
|
25
|
+
* @param deltaY
|
|
24
26
|
*/
|
|
25
|
-
export function isAllowMoveTo(
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
export function isAllowMoveTo(
|
|
28
|
+
groupBounds: BoxBoundsPoint,
|
|
29
|
+
node: BaseNodeModel,
|
|
30
|
+
deltaX: number,
|
|
31
|
+
deltaY: number,
|
|
32
|
+
) {
|
|
33
|
+
const { minX, minY, maxX, maxY } = groupBounds
|
|
34
|
+
const { x, y, width, height } = node
|
|
35
|
+
|
|
36
|
+
// DONE: 计算节点坐标 (x, y) 可移动的范围,并判断 x + deltaX, y + deltaY 是否在范围内
|
|
37
|
+
const allowMoveMinX = minX + width / 2
|
|
38
|
+
const allowMoveMinY = minY + height / 2
|
|
39
|
+
const allowMoveMaxX = maxX - width / 2
|
|
40
|
+
const allowMoveMaxY = maxY - height / 2
|
|
28
41
|
|
|
29
42
|
return {
|
|
30
|
-
x:
|
|
31
|
-
y:
|
|
43
|
+
x: x + deltaX >= allowMoveMinX && x + deltaX <= allowMoveMaxX,
|
|
44
|
+
y: y + deltaY >= allowMoveMinY && y + deltaY <= allowMoveMaxY,
|
|
32
45
|
}
|
|
33
46
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import './index.less'
|
|
2
|
+
|
|
1
3
|
// BPMN 相关
|
|
2
4
|
export * from './bpmn'
|
|
3
5
|
export * from './bpmn-adapter'
|
|
@@ -39,3 +41,6 @@ export * from './materials/node-selection'
|
|
|
39
41
|
*/
|
|
40
42
|
export * from './NodeResize'
|
|
41
43
|
export * from './materials/group'
|
|
44
|
+
|
|
45
|
+
// 迷之插件
|
|
46
|
+
export * from './rect-label-node'
|
package/src/style/index.less
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
@import url('medium-editor/dist/css/medium-editor.min.css');
|
|
2
|
-
//@import url('medium-editor/dist/css/themes/bootstrap.min.css');
|
|
3
|
-
@import url('medium-editor/dist/css/themes/beagle.min.css');
|
|
4
|
-
@import url('vanilla-picker/dist/vanilla-picker.csp.css');
|
|
5
|
-
|
|
6
1
|
.lf-control {
|
|
7
2
|
position: absolute;
|
|
8
3
|
top: 0;
|
|
@@ -258,71 +253,3 @@
|
|
|
258
253
|
.lf-mindmap_addIcon {
|
|
259
254
|
margin-top: 10px;
|
|
260
255
|
}
|
|
261
|
-
|
|
262
|
-
/* label */
|
|
263
|
-
.lf-label-overlay {
|
|
264
|
-
width: 0;
|
|
265
|
-
height: 0;
|
|
266
|
-
overflow: visible;
|
|
267
|
-
|
|
268
|
-
.lf-label-editor {
|
|
269
|
-
//box-sizing: content-box;
|
|
270
|
-
padding: 4px;
|
|
271
|
-
background: #fff;
|
|
272
|
-
border-radius: 5px;
|
|
273
|
-
|
|
274
|
-
&-container {
|
|
275
|
-
position: absolute;
|
|
276
|
-
display: flex;
|
|
277
|
-
align-items: center;
|
|
278
|
-
justify-content: center;
|
|
279
|
-
overflow: visible;
|
|
280
|
-
text-align: center;
|
|
281
|
-
|
|
282
|
-
p {
|
|
283
|
-
margin: 0;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
&-dragging {
|
|
288
|
-
cursor: move;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
&-editing {
|
|
292
|
-
border: 2px solid #275dc5;
|
|
293
|
-
outline: none;
|
|
294
|
-
cursor: text;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
&-hover {
|
|
298
|
-
border: 2px dashed #acacac;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// textOverflowMode
|
|
302
|
-
&-clip {
|
|
303
|
-
width: 100px; /* 根据需要调整宽度 */
|
|
304
|
-
overflow: hidden;
|
|
305
|
-
white-space: nowrap;
|
|
306
|
-
text-overflow: clip;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
&-ellipsis {
|
|
310
|
-
width: 100px; /* 根据需要调整宽度 */
|
|
311
|
-
overflow: hidden;
|
|
312
|
-
white-space: nowrap;
|
|
313
|
-
text-overflow: ellipsis;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
&-wrap {
|
|
317
|
-
width: 100px; /* 根据需要调整宽度 */
|
|
318
|
-
white-space: normal;
|
|
319
|
-
overflow-wrap: break-word; /* 允许单词内换行 */
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
&-nowrap {
|
|
323
|
-
width: 100px; /* 根据需要调整宽度 */
|
|
324
|
-
overflow: visible;
|
|
325
|
-
white-space: nowrap;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
}
|
package/src/style/raw.ts
CHANGED
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* Auto generated file, do not modify it!
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export const content =
|
|
8
|
-
@import url('medium-editor/dist/css/themes/beagle.min.css');
|
|
9
|
-
@import url('vanilla-picker/dist/vanilla-picker.csp.css');
|
|
10
|
-
.lf-control {
|
|
7
|
+
export const content = `.lf-control {
|
|
11
8
|
position: absolute;
|
|
12
9
|
top: 0;
|
|
13
10
|
right: 10px;
|
|
@@ -222,64 +219,4 @@ export const content = `@import url('medium-editor/dist/css/medium-editor.min.cs
|
|
|
222
219
|
.lf-mindmap_addIcon {
|
|
223
220
|
margin-top: 10px;
|
|
224
221
|
}
|
|
225
|
-
/* label */
|
|
226
|
-
.lf-label-overlay {
|
|
227
|
-
width: 0;
|
|
228
|
-
height: 0;
|
|
229
|
-
overflow: visible;
|
|
230
|
-
}
|
|
231
|
-
.lf-label-overlay .lf-label-editor {
|
|
232
|
-
padding: 4px;
|
|
233
|
-
background: #fff;
|
|
234
|
-
border-radius: 5px;
|
|
235
|
-
}
|
|
236
|
-
.lf-label-overlay .lf-label-editor-container {
|
|
237
|
-
position: absolute;
|
|
238
|
-
display: flex;
|
|
239
|
-
align-items: center;
|
|
240
|
-
justify-content: center;
|
|
241
|
-
overflow: visible;
|
|
242
|
-
text-align: center;
|
|
243
|
-
}
|
|
244
|
-
.lf-label-overlay .lf-label-editor-container p {
|
|
245
|
-
margin: 0;
|
|
246
|
-
}
|
|
247
|
-
.lf-label-overlay .lf-label-editor-dragging {
|
|
248
|
-
cursor: move;
|
|
249
|
-
}
|
|
250
|
-
.lf-label-overlay .lf-label-editor-editing {
|
|
251
|
-
border: 2px solid #275dc5;
|
|
252
|
-
outline: none;
|
|
253
|
-
cursor: text;
|
|
254
|
-
}
|
|
255
|
-
.lf-label-overlay .lf-label-editor-hover {
|
|
256
|
-
border: 2px dashed #acacac;
|
|
257
|
-
}
|
|
258
|
-
.lf-label-overlay .lf-label-editor-clip {
|
|
259
|
-
width: 100px;
|
|
260
|
-
/* 根据需要调整宽度 */
|
|
261
|
-
overflow: hidden;
|
|
262
|
-
white-space: nowrap;
|
|
263
|
-
text-overflow: clip;
|
|
264
|
-
}
|
|
265
|
-
.lf-label-overlay .lf-label-editor-ellipsis {
|
|
266
|
-
width: 100px;
|
|
267
|
-
/* 根据需要调整宽度 */
|
|
268
|
-
overflow: hidden;
|
|
269
|
-
white-space: nowrap;
|
|
270
|
-
text-overflow: ellipsis;
|
|
271
|
-
}
|
|
272
|
-
.lf-label-overlay .lf-label-editor-wrap {
|
|
273
|
-
width: 100px;
|
|
274
|
-
/* 根据需要调整宽度 */
|
|
275
|
-
white-space: normal;
|
|
276
|
-
overflow-wrap: break-word;
|
|
277
|
-
/* 允许单词内换行 */
|
|
278
|
-
}
|
|
279
|
-
.lf-label-overlay .lf-label-editor-nowrap {
|
|
280
|
-
width: 100px;
|
|
281
|
-
/* 根据需要调整宽度 */
|
|
282
|
-
overflow: visible;
|
|
283
|
-
white-space: nowrap;
|
|
284
|
-
}
|
|
285
222
|
`
|
package/src/tools/label/index.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import LogicFlow, { createUuid, GraphModel, TextMode } from '@logicflow/core'
|
|
2
2
|
import { cloneDeep, forEach, isArray, isObject, map } from 'lodash-es'
|
|
3
3
|
import LabelOverlay, { LabelConfigType } from './LabelOverlay'
|
|
4
|
+
import {
|
|
5
|
+
BBoxInfo,
|
|
6
|
+
calcPointAfterResize,
|
|
7
|
+
rotatePointAroundCenter,
|
|
8
|
+
} from './utils'
|
|
9
|
+
import './style.less'
|
|
4
10
|
|
|
5
11
|
import Position = LogicFlow.Position
|
|
6
12
|
import NodeData = LogicFlow.NodeData
|
|
@@ -8,11 +14,6 @@ import EdgeData = LogicFlow.EdgeData
|
|
|
8
14
|
import Extension = LogicFlow.Extension
|
|
9
15
|
import LabelConfig = LogicFlow.LabelConfig
|
|
10
16
|
import GraphElement = LogicFlow.GraphElement
|
|
11
|
-
import {
|
|
12
|
-
BBoxInfo,
|
|
13
|
-
calcPointAfterResize,
|
|
14
|
-
rotatePointAroundCenter,
|
|
15
|
-
} from './utils'
|
|
16
17
|
|
|
17
18
|
// 类型定义,如果 isMultiple 为 true 的话,maxCount 为数值且大于 1
|
|
18
19
|
export type ILabelOptions = {
|
|
@@ -197,7 +198,7 @@ export class Label implements Extension {
|
|
|
197
198
|
* @param position
|
|
198
199
|
*/
|
|
199
200
|
private addLabel(element: GraphElement, position: Position) {
|
|
200
|
-
const { maxCount } = this
|
|
201
|
+
const { isMultiple, maxCount } = this
|
|
201
202
|
const {
|
|
202
203
|
properties: { _label, _labelOption },
|
|
203
204
|
} = element
|
|
@@ -217,7 +218,7 @@ export class Label implements Extension {
|
|
|
217
218
|
vertical: false,
|
|
218
219
|
}
|
|
219
220
|
|
|
220
|
-
if (len >= (curLabelOption?.maxCount ?? maxCount)) {
|
|
221
|
+
if (!isMultiple || len >= (curLabelOption?.maxCount ?? maxCount)) {
|
|
221
222
|
return
|
|
222
223
|
}
|
|
223
224
|
|
|
@@ -333,6 +334,14 @@ export class Label implements Extension {
|
|
|
333
334
|
|
|
334
335
|
model.setProperty('_label', newLabelConfig)
|
|
335
336
|
})
|
|
337
|
+
// 监听元素新增事件,元素label格式化
|
|
338
|
+
eventCenter.on('node:add,edge:add', ({ data }) => {
|
|
339
|
+
const element = graphModel.getElement(data.id)
|
|
340
|
+
if (element) {
|
|
341
|
+
const formatedLabel = this.formatConfig(graphModel, data)
|
|
342
|
+
element.setProperty('_label', formatedLabel)
|
|
343
|
+
}
|
|
344
|
+
})
|
|
336
345
|
}
|
|
337
346
|
|
|
338
347
|
/**
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
@import url('medium-editor/dist/css/medium-editor.min.css');
|
|
2
|
+
@import url('medium-editor/dist/css/themes/beagle.min.css');
|
|
3
|
+
@import url('vanilla-picker/dist/vanilla-picker.csp.css');
|
|
4
|
+
|
|
5
|
+
/* label */
|
|
6
|
+
.lf-label-overlay {
|
|
7
|
+
width: 0;
|
|
8
|
+
height: 0;
|
|
9
|
+
overflow: visible;
|
|
10
|
+
|
|
11
|
+
.lf-label-editor {
|
|
12
|
+
//box-sizing: content-box;
|
|
13
|
+
padding: 4px;
|
|
14
|
+
background: #fff;
|
|
15
|
+
border-radius: 5px;
|
|
16
|
+
|
|
17
|
+
&-container {
|
|
18
|
+
position: absolute;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
overflow: visible;
|
|
23
|
+
text-align: center;
|
|
24
|
+
|
|
25
|
+
p {
|
|
26
|
+
margin: 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&-dragging {
|
|
31
|
+
cursor: move;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&-editing {
|
|
35
|
+
border: 2px solid #275dc5;
|
|
36
|
+
outline: none;
|
|
37
|
+
cursor: text;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&-hover {
|
|
41
|
+
border: 2px dashed #acacac;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// textOverflowMode
|
|
45
|
+
&-clip {
|
|
46
|
+
width: 100px; /* 根据需要调整宽度 */
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
text-overflow: clip;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&-ellipsis {
|
|
53
|
+
width: 100px; /* 根据需要调整宽度 */
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
white-space: nowrap;
|
|
56
|
+
text-overflow: ellipsis;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&-wrap {
|
|
60
|
+
width: 100px; /* 根据需要调整宽度 */
|
|
61
|
+
white-space: normal;
|
|
62
|
+
overflow-wrap: break-word; /* 允许单词内换行 */
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
&-nowrap {
|
|
66
|
+
width: 100px; /* 根据需要调整宽度 */
|
|
67
|
+
overflow: visible;
|
|
68
|
+
white-space: nowrap;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -4,7 +4,7 @@ import { updateImageSource, copyCanvas } from './utils'
|
|
|
4
4
|
// 导出图片
|
|
5
5
|
export type ToImageOptions = {
|
|
6
6
|
/**
|
|
7
|
-
* 导出图片的格式,可选值为:`png`、`webp`、`
|
|
7
|
+
* 导出图片的格式,可选值为:`png`、`webp`、`jpeg`、`svg`,默认值为 `png`
|
|
8
8
|
*/
|
|
9
9
|
fileType?: string
|
|
10
10
|
/**
|
|
@@ -63,17 +63,17 @@ export class Snapshot {
|
|
|
63
63
|
|
|
64
64
|
// TODO: 设置fileType为gif但是下载下来的还是png
|
|
65
65
|
// TODO: 完善静默模式不允许添加、操作元素能力
|
|
66
|
-
/*
|
|
66
|
+
/* 导出画布快照 */
|
|
67
67
|
lf.getSnapshot = async (
|
|
68
68
|
fileName?: string,
|
|
69
69
|
toImageOptions?: ToImageOptions,
|
|
70
70
|
) => await this.getSnapshot(fileName, toImageOptions)
|
|
71
71
|
|
|
72
|
-
/* 获取Blob
|
|
72
|
+
/* 获取Blob对象 */
|
|
73
73
|
lf.getSnapshotBlob = async (backgroundColor?: string, fileType?: string) =>
|
|
74
74
|
await this.getSnapshotBlob(backgroundColor, fileType)
|
|
75
75
|
|
|
76
|
-
/* 获取Base64
|
|
76
|
+
/* 获取Base64对象 */
|
|
77
77
|
lf.getSnapshotBase64 = async (
|
|
78
78
|
backgroundColor?: string,
|
|
79
79
|
fileType?: string,
|
|
@@ -144,7 +144,7 @@ export class Snapshot {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
/**
|
|
147
|
-
*
|
|
147
|
+
* 导出画布:导出前的处理画布工作,局部渲染模式处理、静默模式处理
|
|
148
148
|
* @param fileName
|
|
149
149
|
* @param toImageOptions
|
|
150
150
|
*/
|
|
@@ -195,7 +195,7 @@ export class Snapshot {
|
|
|
195
195
|
} else {
|
|
196
196
|
this.getCanvasData(svg, toImageOptions ?? {}).then(
|
|
197
197
|
(canvas: HTMLCanvasElement) => {
|
|
198
|
-
// canvas元素 => url image/octet-stream: 确保所有浏览器都能正常下载
|
|
198
|
+
// canvas元素 => base64 url image/octet-stream: 确保所有浏览器都能正常下载
|
|
199
199
|
const imgUrl = canvas
|
|
200
200
|
.toDataURL(`image/${fileType}`, quality)
|
|
201
201
|
.replace(`image/${fileType}`, 'image/octet-stream')
|
|
@@ -211,7 +211,7 @@ export class Snapshot {
|
|
|
211
211
|
* @param fileType
|
|
212
212
|
* @returns
|
|
213
213
|
*/
|
|
214
|
-
|
|
214
|
+
async getSnapshotBase64(
|
|
215
215
|
backgroundColor?: string,
|
|
216
216
|
fileType?: string,
|
|
217
217
|
): Promise<SnapshotResponse> {
|
|
@@ -238,7 +238,7 @@ export class Snapshot {
|
|
|
238
238
|
* @param fileType
|
|
239
239
|
* @returns
|
|
240
240
|
*/
|
|
241
|
-
|
|
241
|
+
async getSnapshotBlob(
|
|
242
242
|
backgroundColor?: string,
|
|
243
243
|
fileType?: string,
|
|
244
244
|
): Promise<SnapshotResponse> {
|
|
@@ -264,7 +264,7 @@ export class Snapshot {
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
/**
|
|
267
|
-
* 获取脚本css样式
|
|
267
|
+
* 获取脚本 css 样式
|
|
268
268
|
* @returns
|
|
269
269
|
*/
|
|
270
270
|
private getClassRules(): string {
|
|
@@ -273,7 +273,7 @@ export class Snapshot {
|
|
|
273
273
|
const { styleSheets } = document
|
|
274
274
|
for (let i = 0; i < styleSheets.length; i++) {
|
|
275
275
|
const sheet = styleSheets[i]
|
|
276
|
-
// 这里是为了过滤掉不同源css
|
|
276
|
+
// 这里是为了过滤掉不同源 css 脚本,防止报错终止导出
|
|
277
277
|
try {
|
|
278
278
|
for (let j = 0; j < sheet.cssRules.length; j++) {
|
|
279
279
|
rules += sheet.cssRules[j].cssText
|
|
@@ -292,10 +292,10 @@ export class Snapshot {
|
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
/**
|
|
295
|
-
*
|
|
296
|
-
* @param svg
|
|
297
|
-
* @param toImageOptions
|
|
298
|
-
* @returns
|
|
295
|
+
* 将 svg 转化为 canvas
|
|
296
|
+
* @param svg - svg 元素
|
|
297
|
+
* @param toImageOptions - 图像选项
|
|
298
|
+
* @returns Promise<canvas> - 返回 canvas 对象
|
|
299
299
|
*/
|
|
300
300
|
private async getCanvasData(
|
|
301
301
|
svg: Element,
|
|
@@ -334,15 +334,19 @@ export class Snapshot {
|
|
|
334
334
|
const { graphModel } = this.lf
|
|
335
335
|
const { transformModel } = graphModel
|
|
336
336
|
const { SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y } = transformModel
|
|
337
|
+
|
|
338
|
+
// 将导出区域移动到左上角,canvas 绘制的时候是从左上角开始绘制的
|
|
337
339
|
;(copy.lastChild as SVGElement).style.transform = `matrix(1, 0, 0, 1, ${
|
|
338
340
|
(-offsetX + TRANSLATE_X) * (1 / SCALE_X)
|
|
339
341
|
}, ${(-offsetY + TRANSLATE_Y) * (1 / SCALE_Y)})`
|
|
342
|
+
|
|
340
343
|
// 包含所有元素的最小宽高
|
|
341
344
|
const bboxWidth = Math.ceil(bbox.width / SCALE_X)
|
|
342
345
|
const bboxHeight = Math.ceil(bbox.height / SCALE_Y)
|
|
343
346
|
const canvas = document.createElement('canvas')
|
|
344
347
|
canvas.style.width = `${bboxWidth}px`
|
|
345
348
|
canvas.style.height = `${bboxHeight}px`
|
|
349
|
+
|
|
346
350
|
// 宽高值 默认加padding 40,保证图形不会紧贴着下载图片
|
|
347
351
|
canvas.width = bboxWidth * dpr + padding * 2
|
|
348
352
|
canvas.height = bboxHeight * dpr + padding * 2
|
|
@@ -362,7 +366,7 @@ export class Snapshot {
|
|
|
362
366
|
|
|
363
367
|
const img = new Image()
|
|
364
368
|
|
|
365
|
-
//
|
|
369
|
+
// 注入 css 样式
|
|
366
370
|
const style = document.createElement('style')
|
|
367
371
|
style.innerHTML = this.getClassRules()
|
|
368
372
|
const foreignObject = document.createElement('foreignObject')
|