hookehuyr

导出图片功能

......@@ -110,6 +110,11 @@ const router = createRouter({
name: 'selection-select',
component: () => import('../views/selection-select/index.vue')
},
{
path: '/snapshot',
name: 'snapshot',
component: () => import('../views/snapshot/index.vue')
},
]
})
......
<!--
* @Date: 2025-03-10 14:37:31
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 21:58:47
* @LastEditTime: 2025-03-13 23:00:31
* @FilePath: /logic-flow2/src/views/home.vue
* @Description: 文件描述
-->
......@@ -26,6 +26,7 @@
<el-button type="primary" @click="goTo('adv-dnd-panel-custom')">adv-dnd-panel-custom</el-button>
<el-button type="primary" @click="goTo('mini-map')">mini-map</el-button>
<el-button type="primary" @click="goTo('selection-select')">selection-select</el-button>
<el-button type="primary" @click="goTo('snapshot')">snapshot</el-button>
</template>
<script setup>
......
<!--
* @Date: 2025-03-10 16:52:35
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-13 23:29:32
* @FilePath: /logic-flow2/src/views/snapshot/index.vue
* @Description: 导出图片,只能svg,其他类型效果太差
-->
<template>
<div class="container">
<div ref="container" class="flow-container"></div>
<div class="control-panel">
<el-input v-model="fileName" placeholder="文件名"></el-input>
<el-select v-model="fileType">
<el-option label="PNG" value="png" />
<el-option label="JPEG" value="jpeg" />
<el-option label="SVG" value="svg" />
</el-select>
<el-input-number v-model="width" placeholder="宽度" />
<el-input-number v-model="height" placeholder="高度" />
<el-color-picker v-model="backgroundColor" />
<el-input-number v-model="padding" placeholder="内边距" />
<el-input-number
v-model="quality"
:min="0"
:max="1"
:step="0.1"
placeholder="图片质量"
/>
<el-checkbox v-model="partial">局部渲染</el-checkbox>
<el-button @click="downLoad">下载</el-button>
<el-button @click="previewBlob">预览Blob</el-button>
<el-button @click="previewBase64">预览Base64</el-button>
<div v-if="blobData">
<img :src="blobData" alt="blob preview" />
</div>
<div v-if="base64Data">
<img :src="base64Data" alt="base64 preview" />
</div>
</div>
</div>
</template>
<script setup>
import LogicFlow from '@logicflow/core';
import { Snapshot } from '@logicflow/extension';
const container = ref(null);
let lf = null;
// 状态定义
const fileName = ref('');
const fileType = ref('png');
const width = ref();
const height = ref();
const backgroundColor = ref('white');
const padding = ref();
const quality = ref();
const partial = ref(false);
const blobData = ref('');
const base64Data = ref('');
// 下载方法
const downLoad = async () => {
const params = {
fileType: fileType.value,
backgroundColor: backgroundColor.value,
partial: partial.value,
width: width.value,
height: height.value,
padding: padding.value,
quality: quality.value,
};
console.log(params, 'params');
await lf?.getSnapshot(fileName.value, params);
};
// 预览 blob
const previewBlob = () => {
if (lf) {
base64Data.value = '';
lf.getSnapshotBlob(backgroundColor.value, fileType.value)
.then(({ data, width: w, height: h }) => {
blobData.value = window.URL.createObjectURL(data);
console.log('width, height ', w, h);
});
}
};
// 预览 base64
const previewBase64 = () => {
if (lf) {
blobData.value = '';
lf.getSnapshotBase64(backgroundColor.value)
.then(({ data, width: w, height: h }) => {
base64Data.value = data;
console.log('width, height ', w, h);
});
}
};
onMounted(() => {
lf = new LogicFlow({
container: container.value,
grid: true,
plugins: [Snapshot],
});
lf.on('custom:button-click', (model) => {
lf.setProperties(model.id, {
body: 'LogicFlow',
});
});
// 默认开启css样式
const snapshot = lf.extension.snapshot;
snapshot.useGlobalRules = true;
snapshot.customCssRules = `
.uml-wrapper {
line-height: 1.2;
text-align: center;
color: blue;
}
`;
lf.setTheme({
rect: {
fill: "#BDECFF",
stroke: "#BDEC00",
strokeWidth: 2,
},
});
lf.render({
nodes: [
{
id: 'node1',
type: 'rect',
x: 200,
y: 100,
},
{ id: 'node2', type: 'circle', x: 400, y: 100 },
],
edges: [{ id: 'edge1', sourceNodeId: 'node1', targetNodeId: 'node2' }],
});
lf.translateCenter();
});
</script>
<style scoped>
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
.flow-container {
flex: 1;
width: 100%;
height: 100%;
}
.control-panel {
position: absolute;
top: 20px;
left: 20px;
display: flex;
gap: 10px;
flex-wrap: wrap;
max-width: 80%;
padding: 16px;
background: white;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.control-panel > * {
min-width: 120px;
}
</style>