@logicflow/core 2.2.1 → 2.2.2
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/docs/api/logicflow-constructor/index.en.md +106 -0
- package/dist/docs/api/logicflow-constructor/index.zh.md +106 -0
- package/dist/docs/api/logicflow-constructor/use.en.md +61 -0
- package/dist/docs/api/logicflow-constructor/use.zh.md +61 -0
- package/dist/docs/api/logicflow-instance/canvas.en.md +197 -0
- package/dist/docs/api/logicflow-instance/canvas.zh.md +199 -0
- package/dist/docs/api/logicflow-instance/edge.en.md +273 -0
- package/dist/docs/api/logicflow-instance/edge.zh.md +273 -0
- package/dist/docs/api/logicflow-instance/edit-config.en.md +59 -0
- package/dist/docs/api/logicflow-instance/edit-config.zh.md +59 -0
- package/dist/docs/api/logicflow-instance/element.en.md +375 -0
- package/dist/docs/api/logicflow-instance/element.zh.md +379 -0
- package/dist/docs/api/logicflow-instance/event.en.md +326 -0
- package/dist/docs/api/logicflow-instance/event.zh.md +406 -0
- package/dist/docs/api/logicflow-instance/history.en.md +38 -0
- package/dist/docs/api/logicflow-instance/history.zh.md +38 -0
- package/dist/docs/api/logicflow-instance/index.en.md +41 -0
- package/dist/docs/api/logicflow-instance/index.zh.md +41 -0
- package/dist/docs/api/logicflow-instance/node.en.md +308 -0
- package/dist/docs/api/logicflow-instance/node.zh.md +308 -0
- package/dist/docs/api/logicflow-instance/register.en.md +76 -0
- package/dist/docs/api/logicflow-instance/register.zh.md +76 -0
- package/dist/docs/api/logicflow-instance/render-and-data.en.md +179 -0
- package/dist/docs/api/logicflow-instance/render-and-data.zh.md +181 -0
- package/dist/docs/api/logicflow-instance/text.en.md +60 -0
- package/dist/docs/api/logicflow-instance/text.zh.md +60 -0
- package/dist/docs/api/logicflow-instance/theme.en.md +179 -0
- package/dist/docs/api/logicflow-instance/theme.zh.md +179 -0
- package/dist/docs/api/runtime-model/edgeModel.en.md +29 -0
- package/dist/docs/api/runtime-model/edgeModel.zh.md +325 -0
- package/dist/docs/api/runtime-model/graphModel.en.md +275 -0
- package/dist/docs/api/runtime-model/graphModel.zh.md +1153 -0
- package/dist/docs/api/runtime-model/nodeModel.en.md +37 -0
- package/dist/docs/api/runtime-model/nodeModel.zh.md +644 -0
- package/dist/docs/api/type/MainTypes.en.md +598 -0
- package/dist/docs/api/type/MainTypes.zh.md +867 -0
- package/dist/docs/api/type/Theme.en.md +187 -0
- package/dist/docs/api/type/Theme.zh.md +187 -0
- package/dist/docs/api/type/canvas-types.en.md +25 -0
- package/dist/docs/api/type/canvas-types.zh.md +25 -0
- package/dist/docs/api/type/index.en.md +96 -0
- package/dist/docs/api/type/index.zh.md +99 -0
- package/dist/docs/api/type/node-types.en.md +21 -0
- package/dist/docs/api/type/node-types.zh.md +21 -0
- package/dist/docs/api/type/plugin-types.en.md +24 -0
- package/dist/docs/api/type/plugin-types.zh.md +24 -0
- package/dist/docs/index.md +11 -0
- package/dist/docs/tutorial/about.en.md +38 -0
- package/dist/docs/tutorial/about.zh.md +65 -0
- package/dist/docs/tutorial/advanced/dnd.en.md +62 -0
- package/dist/docs/tutorial/advanced/dnd.zh.md +52 -0
- package/dist/docs/tutorial/advanced/edge.en.md +64 -0
- package/dist/docs/tutorial/advanced/edge.zh.md +66 -0
- package/dist/docs/tutorial/advanced/keyboard.en.md +70 -0
- package/dist/docs/tutorial/advanced/keyboard.zh.md +67 -0
- package/dist/docs/tutorial/advanced/node.en.md +338 -0
- package/dist/docs/tutorial/advanced/node.zh.md +338 -0
- package/dist/docs/tutorial/advanced/react.en.md +106 -0
- package/dist/docs/tutorial/advanced/react.zh.md +114 -0
- package/dist/docs/tutorial/advanced/silent-mode.en.md +75 -0
- package/dist/docs/tutorial/advanced/silent-mode.zh.md +71 -0
- package/dist/docs/tutorial/advanced/snapline.en.md +54 -0
- package/dist/docs/tutorial/advanced/vue.en.md +249 -0
- package/dist/docs/tutorial/advanced/vue.zh.md +248 -0
- package/dist/docs/tutorial/ai.en.md +64 -0
- package/dist/docs/tutorial/ai.zh.md +64 -0
- package/dist/docs/tutorial/basic/background.en.md +50 -0
- package/dist/docs/tutorial/basic/canvas.en.md +164 -0
- package/dist/docs/tutorial/basic/canvas.zh.md +183 -0
- package/dist/docs/tutorial/basic/class.en.md +106 -0
- package/dist/docs/tutorial/basic/class.zh.md +103 -0
- package/dist/docs/tutorial/basic/edge.en.md +151 -0
- package/dist/docs/tutorial/basic/edge.zh.md +152 -0
- package/dist/docs/tutorial/basic/event.en.md +70 -0
- package/dist/docs/tutorial/basic/event.zh.md +66 -0
- package/dist/docs/tutorial/basic/grid.en.md +77 -0
- package/dist/docs/tutorial/basic/node.en.md +358 -0
- package/dist/docs/tutorial/basic/node.zh.md +318 -0
- package/dist/docs/tutorial/basic/theme.en.md +154 -0
- package/dist/docs/tutorial/basic/theme.zh.md +157 -0
- package/dist/docs/tutorial/extension/adapter.en.md +446 -0
- package/dist/docs/tutorial/extension/adapter.zh.md +429 -0
- package/dist/docs/tutorial/extension/bpmn-element.en.md +1427 -0
- package/dist/docs/tutorial/extension/bpmn-element.zh.md +1472 -0
- package/dist/docs/tutorial/extension/control.en.md +117 -0
- package/dist/docs/tutorial/extension/control.zh.md +118 -0
- package/dist/docs/tutorial/extension/curved-edge.en.md +46 -0
- package/dist/docs/tutorial/extension/curved-edge.zh.md +46 -0
- package/dist/docs/tutorial/extension/custom.en.md +142 -0
- package/dist/docs/tutorial/extension/custom.zh.md +138 -0
- package/dist/docs/tutorial/extension/dnd-panel.en.md +109 -0
- package/dist/docs/tutorial/extension/dnd-panel.zh.md +109 -0
- package/dist/docs/tutorial/extension/dynamic-group.en.md +606 -0
- package/dist/docs/tutorial/extension/dynamic-group.zh.md +606 -0
- package/dist/docs/tutorial/extension/group.en.md +217 -0
- package/dist/docs/tutorial/extension/group.zh.md +209 -0
- package/dist/docs/tutorial/extension/highlight.en.md +50 -0
- package/dist/docs/tutorial/extension/highlight.zh.md +50 -0
- package/dist/docs/tutorial/extension/insert-node-in-polyline.en.md +52 -0
- package/dist/docs/tutorial/extension/insert-node-in-polyline.zh.md +47 -0
- package/dist/docs/tutorial/extension/intro.en.md +72 -0
- package/dist/docs/tutorial/extension/intro.zh.md +95 -0
- package/dist/docs/tutorial/extension/label.en.md +136 -0
- package/dist/docs/tutorial/extension/label.zh.md +135 -0
- package/dist/docs/tutorial/extension/layout.en.md +156 -0
- package/dist/docs/tutorial/extension/layout.zh.md +156 -0
- package/dist/docs/tutorial/extension/menu.en.md +319 -0
- package/dist/docs/tutorial/extension/menu.zh.md +377 -0
- package/dist/docs/tutorial/extension/minimap.en.md +164 -0
- package/dist/docs/tutorial/extension/minimap.zh.md +180 -0
- package/dist/docs/tutorial/extension/node-resize.en.md +199 -0
- package/dist/docs/tutorial/extension/node-resize.zh.md +221 -0
- package/dist/docs/tutorial/extension/pool.en.md +227 -0
- package/dist/docs/tutorial/extension/pool.zh.md +227 -0
- package/dist/docs/tutorial/extension/proximity-connect.en.md +104 -0
- package/dist/docs/tutorial/extension/proximity-connect.zh.md +107 -0
- package/dist/docs/tutorial/extension/selection.en.md +166 -0
- package/dist/docs/tutorial/extension/selection.zh.md +150 -0
- package/dist/docs/tutorial/extension/snapshot.en.md +276 -0
- package/dist/docs/tutorial/extension/snapshot.zh.md +276 -0
- package/dist/docs/tutorial/get-started.en.md +501 -0
- package/dist/docs/tutorial/get-started.zh.md +139 -0
- package/dist/docs/tutorial/update.en.md +213 -0
- package/dist/docs/tutorial/update.zh.md +212 -0
- package/package.json +5 -3
- package/scripts/postinstall-ai-prompt.js +67 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: Guide
|
|
3
|
+
group:
|
|
4
|
+
title: Plug-in functionality
|
|
5
|
+
order: 3
|
|
6
|
+
title: Snapshot
|
|
7
|
+
order: 6
|
|
8
|
+
toc: content
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
We often need to export the canvas content as an image. LogicFlow provides an independent plug-in package `Snapshot` to support exporting the canvas as an image.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Registration
|
|
16
|
+
|
|
17
|
+
Like other LogicFlow plugins, Snapshot supports both global and local registration:
|
|
18
|
+
|
|
19
|
+
```tsx | pure
|
|
20
|
+
import LogicFlow from "@logicflow/core";
|
|
21
|
+
import { Snapshot } from "@logicflow/extension";
|
|
22
|
+
|
|
23
|
+
// Global Registration: Available for all LogicFlow instances
|
|
24
|
+
LogicFlow.use(Snapshot);
|
|
25
|
+
|
|
26
|
+
// Local Registration: Only available for the current instance
|
|
27
|
+
const lf = new LogicFlow({
|
|
28
|
+
...config,
|
|
29
|
+
plugins: [Snapshot]
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Basic Usage
|
|
34
|
+
|
|
35
|
+
After registering the plugin, you can directly call the export method through the LogicFlow instance:
|
|
36
|
+
|
|
37
|
+
```tsx | pure
|
|
38
|
+
// Export as PNG image and download
|
|
39
|
+
lf.getSnapshot('Flowchart');
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
In version 2.0, we have comprehensively upgraded the export functionality:
|
|
45
|
+
|
|
46
|
+
- **Multiple Format Support**: PNG, JPEG, SVG, and other formats
|
|
47
|
+
- **Custom Background and Padding**: Adjust image effects according to requirements
|
|
48
|
+
- **Partial Rendering**: Option to export only the visible area, improving efficiency
|
|
49
|
+
- **Custom Styles**: Support for adding CSS styles to ensure consistent export image style
|
|
50
|
+
|
|
51
|
+
### Configuration Options
|
|
52
|
+
|
|
53
|
+
The export method supports the `toImageOptions` parameter with the following configuration options:
|
|
54
|
+
|
|
55
|
+
| Property Name | Type | Default Value | Description |
|
|
56
|
+
| --------------- | ------- | ------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| fileType | string | png | Export format: `png`, `webp`, `jpeg`, `svg` |
|
|
58
|
+
| width | number | - | Image width (may cause image stretching) |
|
|
59
|
+
| height | number | - | Image height (may cause image stretching) |
|
|
60
|
+
| backgroundColor | string | - | Background color, transparent by default |
|
|
61
|
+
| quality | number | 0.92 | Image quality, only effective for `jpeg` and `webp`, value range 0-1 |
|
|
62
|
+
| padding | number | 40 | Inner margin, in pixels |
|
|
63
|
+
| partial | boolean | false | Whether to export only the visible area |
|
|
64
|
+
| safetyFactor | number | 1.1 | Safety factor: for wide canvas scenarios, enlarges the export bounds proportionally to ensure all elements are included |
|
|
65
|
+
| safetyMargin | number | 40 | Safety margin: extra margin for wide canvas scenarios to avoid cropping |
|
|
66
|
+
|
|
67
|
+
:::warning{title=Notes}
|
|
68
|
+
- SVG format does not support `width`, `height`, `backgroundColor`, `padding` attributes
|
|
69
|
+
- Custom width and height may cause image stretching, also affecting padding
|
|
70
|
+
- During export, the canvas will automatically handle wide canvas situations, adding safety factors and extra margins
|
|
71
|
+
- During export, silent mode will be automatically enabled, disabling canvas interaction
|
|
72
|
+
- Automatically converts relative path images in SVG to Base64 encoding <Badge type="warning">2.0.14 New</Badge>
|
|
73
|
+
- When the image exceeds the browser's canvas limit, it will automatically scale the image size proportionally to ensure successful export, but it will affect image clarity
|
|
74
|
+
- You can fine-tune wide canvas behavior via `safetyFactor` and `safetyMargin` to avoid element cropping
|
|
75
|
+
- If `partial` is not explicitly provided, it defaults to the current canvas partial rendering state; during export, the rendering mode may be temporarily switched and will be restored afterward
|
|
76
|
+
- Anchors and rotate controls are automatically removed during export to prevent auxiliary elements from appearing in the image
|
|
77
|
+
:::
|
|
78
|
+
|
|
79
|
+
### Custom CSS Styles
|
|
80
|
+
|
|
81
|
+
To keep the exported image consistent with the canvas effect, the plugin loads all CSS rules of the page by default. If you encounter cross-domain issues, you can:
|
|
82
|
+
|
|
83
|
+
```tsx | pure
|
|
84
|
+
// Disable global CSS rules
|
|
85
|
+
lf.extension.snapshot.useGlobalRules = false;
|
|
86
|
+
// Add custom styles (higher priority)
|
|
87
|
+
lf.extension.snapshot.customCssRules = `
|
|
88
|
+
.uml-wrapper {
|
|
89
|
+
line-height: 1.2;
|
|
90
|
+
text-align: center;
|
|
91
|
+
color: blue;
|
|
92
|
+
}
|
|
93
|
+
`
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## API Reference
|
|
97
|
+
|
|
98
|
+
### getSnapshot
|
|
99
|
+
Export image and download
|
|
100
|
+
```tsx | pure
|
|
101
|
+
lf.getSnapshot(name: string, toImageOptions?: ToImageOptions)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### getSnapshotBlob
|
|
105
|
+
Get Blob object
|
|
106
|
+
```tsx | pure
|
|
107
|
+
lf.getSnapshotBlob(backgroundColor?: string, fileType?: string): Promise<{ data: Blob; width: number; height: number }>
|
|
108
|
+
// Supported syntax after version 2.0.14👇🏻
|
|
109
|
+
lf.getSnapshotBlob(
|
|
110
|
+
backgroundColor?: string, // Compatible with old syntax, will be used as fallback for toImageOptions.backgroundColor
|
|
111
|
+
fileType?: string, // Compatible with old syntax, will be used as fallback for toImageOptions.fileType
|
|
112
|
+
toImageOptions?: ToImageOptions // New parameter
|
|
113
|
+
)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### getSnapshotBase64
|
|
117
|
+
Get Base64 string
|
|
118
|
+
```tsx | pure
|
|
119
|
+
lf.getSnapshotBase64(backgroundColor?: string, fileType?: string): Promise<{ data: string; width: number; height: number }>
|
|
120
|
+
// Supported syntax after version 2.0.14👇🏻
|
|
121
|
+
lf.getSnapshotBase64(
|
|
122
|
+
backgroundColor?: string, // Compatible with old syntax, will be used as fallback for toImageOptions.backgroundColor
|
|
123
|
+
fileType?: string, // Compatible with old syntax, will be used as fallback for toImageOptions.fileType
|
|
124
|
+
toImageOptions?: ToImageOptions // New parameter
|
|
125
|
+
)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Usage Examples
|
|
129
|
+
|
|
130
|
+
### Demonstration
|
|
131
|
+
|
|
132
|
+
<code id="react-portal" src="@/src/tutorial/extension/snapshot"></code>
|
|
133
|
+
|
|
134
|
+
### Code Examples
|
|
135
|
+
|
|
136
|
+
**Basic Usage: Export as PNG image and download**
|
|
137
|
+
```tsx | pure
|
|
138
|
+
lf.getSnapshot('Flowchart');
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Advanced Usage: Specify format, background color, and other options**
|
|
142
|
+
```tsx | pure
|
|
143
|
+
lf.getSnapshot('Flowchart', {
|
|
144
|
+
fileType: 'png', // Options: 'png', 'webp', 'jpeg', 'svg'
|
|
145
|
+
backgroundColor: '#f5f5f5',
|
|
146
|
+
padding: 30, // Inner margin, in pixels
|
|
147
|
+
partial: false, // false: export all elements, true: only export visible area
|
|
148
|
+
quality: 0.92 // Effective for jpeg and webp formats, value range 0-1
|
|
149
|
+
})
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Export as SVG format**
|
|
153
|
+
```tsx | pure
|
|
154
|
+
lf.getSnapshot('Flowchart', {
|
|
155
|
+
fileType:'svg'
|
|
156
|
+
// Note: svg format does not support width, height, backgroundColor, padding attributes
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Get Blob object for further processing**
|
|
161
|
+
```tsx | pure
|
|
162
|
+
const { data: blob, width, height } = await lf.getSnapshotBlob({
|
|
163
|
+
fileType: 'jpeg',
|
|
164
|
+
backgroundColor: '#ffffff',
|
|
165
|
+
quality: 0.8
|
|
166
|
+
})
|
|
167
|
+
// Use Blob object to create temporary URL (e.g., for preview)
|
|
168
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
169
|
+
try {
|
|
170
|
+
// Use blobUrl, e.g., set as image source
|
|
171
|
+
document.getElementById('preview').src = blobUrl;
|
|
172
|
+
} finally {
|
|
173
|
+
// Release URL after use
|
|
174
|
+
URL.revokeObjectURL(blobUrl);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Get Base64 string for further processing**
|
|
179
|
+
```tsx | pure
|
|
180
|
+
const { data: base64 } = await lf.getSnapshotBase64({
|
|
181
|
+
fileType: 'png',
|
|
182
|
+
partial: true // Only export visible area
|
|
183
|
+
});
|
|
184
|
+
// Use Base64 directly for img tag
|
|
185
|
+
document.getElementById('preview').src = base64;
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Custom CSS Styles**
|
|
189
|
+
```tsx | pure
|
|
190
|
+
lf.extension.snapshot.useGlobalRules = false; // Disable global CSS rules to avoid cross-domain issues
|
|
191
|
+
lf.extension.snapshot.customCssRules = `
|
|
192
|
+
.node-container { border: 2px solid blue; }
|
|
193
|
+
.edge-text { font-weight: bold; }
|
|
194
|
+
.lf-node-text { font-size: 14px; font-weight: bold; }
|
|
195
|
+
`;
|
|
196
|
+
```
|
|
197
|
+
**Using in Components**
|
|
198
|
+
```tsx | pure
|
|
199
|
+
const downloadSnapshot = async () => {
|
|
200
|
+
// Export as image and download
|
|
201
|
+
await lf.getSnapshot('Flowchart', {
|
|
202
|
+
fileType: 'png',
|
|
203
|
+
backgroundColor: '#ffffff',
|
|
204
|
+
padding: 40
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Using in Button Click Events**
|
|
210
|
+
```tsx | pure
|
|
211
|
+
// Using in button click events
|
|
212
|
+
document.getElementById('download-btn').addEventListener('click', async () => {
|
|
213
|
+
// Show loading state
|
|
214
|
+
showLoading();
|
|
215
|
+
try {
|
|
216
|
+
// Export image (will automatically apply silent mode and other optimizations)
|
|
217
|
+
await lf.getSnapshot('Flowchart');
|
|
218
|
+
} finally {
|
|
219
|
+
// Hide loading state
|
|
220
|
+
hideLoading();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Export and Upload to Server**
|
|
226
|
+
|
|
227
|
+
```tsx | pure
|
|
228
|
+
// Export as Blob and upload to server
|
|
229
|
+
async function exportAndUpload() {
|
|
230
|
+
const { data: blob } = await lf.getSnapshotBlob({
|
|
231
|
+
fileType: 'png',
|
|
232
|
+
backgroundColor: '#ffffff'
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const formData = new FormData();
|
|
236
|
+
formData.append('file', blob, 'flowchart.png');
|
|
237
|
+
|
|
238
|
+
try {
|
|
239
|
+
const response = await fetch('/api/upload', {
|
|
240
|
+
method: 'POST',
|
|
241
|
+
body: formData
|
|
242
|
+
});
|
|
243
|
+
const result = await response.json();
|
|
244
|
+
console.log('Upload successful:', result);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error('Upload failed:', error);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Other Export Types
|
|
252
|
+
|
|
253
|
+
### xml <Badge>1.0.7 New</Badge>
|
|
254
|
+
|
|
255
|
+
The default data generated by LogicFlow is in json format. Some process engines may require the front end to provide data in xml format. `@logicflow/extension` provides two plugins, `lfJson2Xml` and `lfXml2Json`, for converting json and xml to each other.
|
|
256
|
+
|
|
257
|
+
```jsx | pure
|
|
258
|
+
import LogicFlow from "@logicflow/core";
|
|
259
|
+
import { lfJson2Xml, lfXml2Json } from "@logicflow/extension";
|
|
260
|
+
|
|
261
|
+
const data = {
|
|
262
|
+
// ...
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const lf = new LogicFlow({
|
|
266
|
+
// ...
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
lf.render(data);
|
|
270
|
+
|
|
271
|
+
// json -> xml
|
|
272
|
+
const xml = lfJson2Xml(lf.getGraphData());
|
|
273
|
+
|
|
274
|
+
// xml -> json
|
|
275
|
+
const jsonData = lfXml2Json(xml)
|
|
276
|
+
```
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
---
|
|
2
|
+
nav: 指南
|
|
3
|
+
group:
|
|
4
|
+
title: 插件功能
|
|
5
|
+
order: 3
|
|
6
|
+
title: 导出图片 (Snapshot)
|
|
7
|
+
order: 6
|
|
8
|
+
toc: content
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
我们常常有需要将画布内容以图片的形式导出来的情况,因此LogicFlow提供了一个独立的插件包 `Snapshot` 以支持用户将画布导出为图片。
|
|
12
|
+
## 用法
|
|
13
|
+
|
|
14
|
+
### 注册插件
|
|
15
|
+
|
|
16
|
+
与其他LogicFlow插件一样,Snapshot支持全局注册和局部注册两种方式:
|
|
17
|
+
|
|
18
|
+
```tsx | pure
|
|
19
|
+
import LogicFlow from "@logicflow/core";
|
|
20
|
+
import { Snapshot } from "@logicflow/extension";
|
|
21
|
+
|
|
22
|
+
// 全局注册:所有LogicFlow实例都能使用
|
|
23
|
+
LogicFlow.use(Snapshot);
|
|
24
|
+
|
|
25
|
+
// 局部注册:仅当前实例可用
|
|
26
|
+
const lf = new LogicFlow({
|
|
27
|
+
...config,
|
|
28
|
+
plugins: [Snapshot]
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 基本用法
|
|
33
|
+
|
|
34
|
+
注册插件后,您可以直接通过LogicFlow实例调用导出方法:
|
|
35
|
+
|
|
36
|
+
```tsx | pure
|
|
37
|
+
// 导出为PNG图片并下载
|
|
38
|
+
lf.getSnapshot('流程图');
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 功能特性
|
|
42
|
+
|
|
43
|
+
在2.0版本中,我们对导出功能进行了全面升级:
|
|
44
|
+
|
|
45
|
+
- **多格式支持**:PNG、JPEG、SVG等多种格式
|
|
46
|
+
- **自定义背景和边距**:根据需求调整图片效果
|
|
47
|
+
- **局部渲染**:可选择只导出可见区域,提高效率
|
|
48
|
+
- **自定义样式**:支持添加CSS样式,确保导出图片风格一致
|
|
49
|
+
|
|
50
|
+
### 配置选项
|
|
51
|
+
|
|
52
|
+
导出方法支持`toImageOptions`参数,提供以下配置项:
|
|
53
|
+
|
|
54
|
+
| 属性名 | 类型 | 默认值 | 描述 |
|
|
55
|
+
| --------------- | ------- | ------ | ---------------------------------------------------------------------- |
|
|
56
|
+
| fileType | string | png | 导出格式:`png`、`webp`、`jpeg`、`svg` |
|
|
57
|
+
| width | number | - | 图片宽度(可能导致图形拉伸) |
|
|
58
|
+
| height | number | - | 图片高度(可能导致图形拉伸) |
|
|
59
|
+
| backgroundColor | string | - | 背景色,默认透明 |
|
|
60
|
+
| quality | number | 0.92 | 图片质量,仅对`jpeg`和`webp`有效,取值0-1 |
|
|
61
|
+
| padding | number | 40 | 内边距,单位像素 |
|
|
62
|
+
| partial | boolean | false | 是否只导出可见区域 |
|
|
63
|
+
| safetyFactor | number | 1.1 | 安全系数:用于宽画布场景,导出时按比例扩大画布边界,确保所有元素被包含 |
|
|
64
|
+
| safetyMargin | number | 40 | 安全边距:用于宽画布场景,导出时额外增加边距,避免被裁剪 |
|
|
65
|
+
|
|
66
|
+
:::warning{title=注意事项}
|
|
67
|
+
- 导出SVG格式的图片时不支持`width`、`height`、`backgroundColor`、`padding`属性
|
|
68
|
+
- 自定义宽高可能导致图形拉伸,同时影响内边距
|
|
69
|
+
- 导出时会自动处理宽画布情况,添加安全系数和额外边距
|
|
70
|
+
- 导出过程中会自动开启静默模式,禁用画布交互
|
|
71
|
+
- 自动将SVG中的相对路径图片转换为Base64编码<Badge type="warning">2.0.14新增</Badge>
|
|
72
|
+
- 导出图片超过浏览器对canvas限制时,会自动等比缩放图片尺寸,确保导出成功,但会影响图片清晰度
|
|
73
|
+
- 可通过 `safetyFactor` 与 `safetyMargin` 精细调整宽画布的安全余量,避免元素裁剪
|
|
74
|
+
- `partial` 未显式传入时,默认沿用当前画布的局部渲染状态;导出期间如需切换渲染模式会临时切换并在导出完成后还原
|
|
75
|
+
- 导出时会自动移除锚点与旋转控件,避免辅助元素进入图片
|
|
76
|
+
:::
|
|
77
|
+
|
|
78
|
+
### 自定义CSS样式
|
|
79
|
+
|
|
80
|
+
为保持导出图片与画布效果一致,插件默认加载页面所有CSS规则。如遇跨域问题,可以:
|
|
81
|
+
|
|
82
|
+
```tsx | pure
|
|
83
|
+
// 禁用全局CSS规则
|
|
84
|
+
lf.extension.snapshot.useGlobalRules = false;
|
|
85
|
+
// 添加自定义样式(优先级高)
|
|
86
|
+
lf.extension.snapshot.customCssRules = `
|
|
87
|
+
.uml-wrapper {
|
|
88
|
+
line-height: 1.2;
|
|
89
|
+
text-align: center;
|
|
90
|
+
color: blue;
|
|
91
|
+
}
|
|
92
|
+
`
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## API参考
|
|
96
|
+
|
|
97
|
+
### getSnapshot
|
|
98
|
+
导出图片并下载
|
|
99
|
+
```tsx | pure
|
|
100
|
+
lf.getSnapshot(name: string, toImageOptions?: ToImageOptions)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### getSnapshotBlob
|
|
104
|
+
获取Blob对象
|
|
105
|
+
```tsx | pure
|
|
106
|
+
lf.getSnapshotBlob(backgroundColor?: string, fileType?: string): Promise<{ data: Blob; width: number; height: number }>
|
|
107
|
+
// 2.0.14版本后支持的写法👇🏻
|
|
108
|
+
lf.getSnapshotBlob(
|
|
109
|
+
backgroundColor?: string, // 兼容老写法,传入后会作为toImageOptions.backgroundColor的兜底配置
|
|
110
|
+
fileType?: string, // 兼容老写法,传入后会作为toImageOptions.fileType的兜底配置
|
|
111
|
+
toImageOptions?: ToImageOptions // 新增参数
|
|
112
|
+
)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### getSnapshotBase64
|
|
116
|
+
获取Base64字符串
|
|
117
|
+
```tsx | pure
|
|
118
|
+
lf.getSnapshotBase64(backgroundColor?: string, fileType?: string): Promise<{ data: string; width: number; height: number }>
|
|
119
|
+
// 2.0.14版本后支持的写法👇🏻
|
|
120
|
+
lf.getSnapshotBase64(
|
|
121
|
+
backgroundColor?: string, // 兼容老写法,传入后会作为toImageOptions.backgroundColor的兜底配置
|
|
122
|
+
fileType?: string, // 兼容老写法,传入后会作为toImageOptions.fileType的兜底配置
|
|
123
|
+
toImageOptions?: ToImageOptions // 新增参数
|
|
124
|
+
)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## 使用示例
|
|
128
|
+
|
|
129
|
+
### 功能演示
|
|
130
|
+
|
|
131
|
+
<code id="react-portal" src="@/src/tutorial/extension/snapshot"></code>
|
|
132
|
+
|
|
133
|
+
### 代码示例
|
|
134
|
+
|
|
135
|
+
**基本用法:导出为PNG图片并下载**
|
|
136
|
+
```tsx | pure
|
|
137
|
+
lf.getSnapshot('流程图');
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**高级用法:指定格式、背景色和其他选项**
|
|
141
|
+
```tsx | pure
|
|
142
|
+
lf.getSnapshot('流程图', {
|
|
143
|
+
fileType: 'png', // 可选:'png'、'webp'、'jpeg'、'svg'
|
|
144
|
+
backgroundColor: '#f5f5f5',
|
|
145
|
+
padding: 30, // 内边距,单位为像素
|
|
146
|
+
partial: false, // false: 导出所有元素,true: 只导出可见区域
|
|
147
|
+
quality: 0.92 // 对jpeg和webp格式有效,取值范围0-1
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**导出为SVG格式**
|
|
152
|
+
```tsx | pure
|
|
153
|
+
lf.getSnapshot('流程图', {
|
|
154
|
+
fileType:'svg'
|
|
155
|
+
// 注意:svg格式暂不支持width、height、backgroundColor、padding属性
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**获取Blob对象用于进一步处理**
|
|
160
|
+
```tsx | pure
|
|
161
|
+
const { data: blob, width, height } = await lf.getSnapshotBlob({
|
|
162
|
+
fileType: 'jpeg',
|
|
163
|
+
backgroundColor: '#ffffff',
|
|
164
|
+
quality: 0.8
|
|
165
|
+
})
|
|
166
|
+
// 使用Blob对象创建临时URL(例如预览)
|
|
167
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
168
|
+
try {
|
|
169
|
+
// 使用blobUrl,例如设置为图片源
|
|
170
|
+
document.getElementById('preview').src = blobUrl;
|
|
171
|
+
} finally {
|
|
172
|
+
// 使用完毕后释放URL
|
|
173
|
+
URL.revokeObjectURL(blobUrl);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**获取Base64字符串用于进一步处理**
|
|
178
|
+
```tsx | pure
|
|
179
|
+
const { data: base64 } = await lf.getSnapshotBase64({
|
|
180
|
+
fileType: 'png',
|
|
181
|
+
partial: true // 只导出可见区域
|
|
182
|
+
});
|
|
183
|
+
// 将Base64直接用于img标签
|
|
184
|
+
document.getElementById('preview').src = base64;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**自定义CSS样式**
|
|
188
|
+
```tsx | pure
|
|
189
|
+
lf.extension.snapshot.useGlobalRules = false; // 禁用全局CSS规则,避免跨域问题
|
|
190
|
+
lf.extension.snapshot.customCssRules = `
|
|
191
|
+
.node-container { border: 2px solid blue; }
|
|
192
|
+
.edge-text { font-weight: bold; }
|
|
193
|
+
.lf-node-text { font-size: 14px; font-weight: bold; }
|
|
194
|
+
`;
|
|
195
|
+
```
|
|
196
|
+
**在组件组件中使用**
|
|
197
|
+
```tsx | pure
|
|
198
|
+
const downloadSnapshot = async () => {
|
|
199
|
+
// 导出为图片并下载
|
|
200
|
+
await lf.getSnapshot('流程图', {
|
|
201
|
+
fileType: 'png',
|
|
202
|
+
backgroundColor: '#ffffff',
|
|
203
|
+
padding: 40
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**在按钮点击事件中使用**
|
|
209
|
+
```tsx | pure
|
|
210
|
+
// 在按钮点击事件中使用
|
|
211
|
+
document.getElementById('download-btn').addEventListener('click', async () => {
|
|
212
|
+
// 显示加载状态
|
|
213
|
+
showLoading();
|
|
214
|
+
try {
|
|
215
|
+
// 导出图片(会自动应用静默模式和其他优化)
|
|
216
|
+
await lf.getSnapshot('流程图');
|
|
217
|
+
} finally {
|
|
218
|
+
// 隐藏加载状态
|
|
219
|
+
hideLoading();
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**导出并上传到服务器**
|
|
225
|
+
|
|
226
|
+
```tsx | pure
|
|
227
|
+
// 导出为Blob并上传到服务器
|
|
228
|
+
async function exportAndUpload() {
|
|
229
|
+
const { data: blob } = await lf.getSnapshotBlob({
|
|
230
|
+
fileType: 'png',
|
|
231
|
+
backgroundColor: '#ffffff'
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const formData = new FormData();
|
|
235
|
+
formData.append('file', blob, 'flowchart.png');
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const response = await fetch('/api/upload', {
|
|
239
|
+
method: 'POST',
|
|
240
|
+
body: formData
|
|
241
|
+
});
|
|
242
|
+
const result = await response.json();
|
|
243
|
+
console.log('上传成功:', result);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error('上传失败:', error);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## 其他导出类型
|
|
251
|
+
|
|
252
|
+
### xml <Badge>1.0.7 新增</Badge>
|
|
253
|
+
|
|
254
|
+
LogicFlow 默认生成的数据是 json 格式,可能会有一些流程引擎需要前端提供 xml 格式数据。`@logicflow/extension`提供了`lfJson2Xml`和`lfXml2Json`两个插件,用于将 json 和 xml 进行互相转换。
|
|
255
|
+
|
|
256
|
+
```jsx | pure
|
|
257
|
+
import LogicFlow from "@logicflow/core";
|
|
258
|
+
import { lfJson2Xml, lfXml2Json } from "@logicflow/extension";
|
|
259
|
+
|
|
260
|
+
const data = {
|
|
261
|
+
// ...
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const lf = new LogicFlow({
|
|
265
|
+
// ...
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
lf.render(data);
|
|
269
|
+
|
|
270
|
+
// json -> xml
|
|
271
|
+
const xml = lfJson2Xml(lf.getGraphData());
|
|
272
|
+
|
|
273
|
+
// xml -> json
|
|
274
|
+
const jsonData = lfXml2Json(xml)
|
|
275
|
+
|
|
276
|
+
```
|