🖼️ | 本地图片导出后不显示?
先看看官方的导出文档: 图片导出
由于业务需要,需要把画布上的节点保存成图片供其它模块展示,如果你的后端返回的数据格式是前端想要的,那么大不必搞图片的形式,直接把官网的快速上手代码拿过来循环一下就好了......,这里就拿
toPng
的方法来讲解
问题梳理
- 调用
toPng
拿到画布的base64数据 - 把base64的数据传给后端
- 后端把base64的数据转存后生成可访问的图片地址再返回给前端
- 前端开始展示
然而事情却没有这么简单,第一步就遇到了一堆的坑,由于官网上导出的都是它内置的节点,所以导出都没啥问题,但是我使用的是html节点,导出的时候,我节点的图片就死活导不出来,而且导出的样式也是乱的(样式错乱问题)
解决方案
一句话:图片必须得是base64格式的导出才会有图片,不然无法导出节点的图片
- 自定义html节点中把图片转换成base格式的
需要调用 imageToDataUri把图片地址转成base64的数据,这个方法我也是摸索了好久才找到的,官方文档完全没有提及这个方法,如果需要查看其它方法,请打印
DataUri
这个对象
javascript
DataUri.imageToDataUri('/images/operator/datasouce.png',
function (nu, url) {
// 第一个参数无效,用的只是第二个参数,但是第一个参数不写不行
container_img.src = url; // 给图片标签赋值
}
);
- 调用
toPng
生成base64数据
这个步骤中要处理的问题:导出后样式不正确,导出的时候页面闪动
javascript
graph.toPNG(
dataUri => {
console.log('dataUri >>>>', dataUri); // 这个就是base的图片地址
},
{
width: 526,
height: 268,
backgroundColor: 'rgba(25, 87, 121, 0.18)',
quality: 1, // 图片质量 取值范围:0-1,默认0.92
// copyStyles: false,
// 自定义样式表,为了解决导出后节点样式丢失的问题,暂时官方还没有修复这个bug
stylesheet: `
.cu-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cu-container-title {
color: #d3e6f3;
}
.cu-container-img {
width: 53px;
height: 53px;
margin-bottom: 4px;
}
.cu-container-desc {
color: rgba(211, 230, 243, 0.7);
margin-top: 3px;
}
.cu-container-title,
.cu-container-desc {
font-size: 14px;
font-weight: 400;
line-height: 20px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
`
}
);
Tip:图片导出样式和原节点的样式不一致问题:如果你遇到了这个问题,目前最好的方法是不断调整
stylesheet
中的样式,直到导出的样式和原节点的样式几乎一致即可。当然,如果你的甲方不重视页面交互,咱们完全可以使用copyStyles:true
这个属性就行了,这样就不用设置stylesheet
了
🖼️ | 神奇的图片边框
昨天才把html节点中的图片转成base格式的,今天就发现一个用户体验的问题;那么是啥呢?就是我从左侧的树形菜单中拖拽节点的时候(鼠标按下也是同样问题),发现节点的图片区域那里会出现一个边框,持续时间不是很长,就几毫秒的时间,但是当你连续拖拽几个不同节点的时候就会发现这个边框竟然又消失不见了,如果此时重新进入页面,再开始拖动节点,图片的边框又出现了。
问题梳理
- 是否是官方节点自带的边框?如果是,配置项是什么?
- 图片的默认边框是否被清除?还是外围元素的边框导致?
- 图片的加载时机?
- 是否是转base64的问题,毕竟在这之前没有这个情况发生......
带着这些问题,第一时间去翻阅了官方文档,发现没有和这个问题相关的配置项,即使有设置了也不管用;然后就把问题抛到了交流群里面,发现压根没人回答......,那就只能开始第二个方案了:把图片的默认边框都去除掉,比如border,box-shadow,outline这些属性都去除掉了,发现还是没用;好吧,开始第三套方案:使用new Image处理图片的加载时机问题,嗯!不出意外的话,这个方法还是不行
定位问题
经过上面四个方案的尝试后,我大概知道了问题的源头在哪边了,那就是我自定义html节点中图片地址赋值的地方,由于
DataUri.imageToDataUri
这个方法是个异步执行的,所以才会导致在渲染的时候会出现短暂的视觉差
解决方案
- 先给图片赋值个普通的地址(非base64的地址)
- 在
DataUri.imageToDataUri('随便写个参数名',url)
的回调中再把图片的src替换成base64的
javascript
const container_img = document.createElement('img');
container_img.setAttribute('class', 'cu-container-img');
container_img.setAttribute('alt', '节点ico');
container_img.style.cursor = 'pointer';
// 先用远程图片地址给图片的src赋值,然后再重新赋值成base64的格式;这么做的目的就是解决节点拖拽到画布上会出现短暂的边框闪动问题,如果你要复现这个边框,可以把下面这一行代码注掉(不是必现)
container_img.src = img;
// 把图片转成base64方便存储到后端
DataUri.imageToDataUri(img, function (nu, url) {
// 第一个参数无效,用的只是第二个参数,但是第一个参数不写由不行
container_img.src = url;
});