JS截取页面+elemelt-upload上传
分类:javascript
需求:在地图上画分区域并截取指定部分生成图片上传至服务器;
JS截图无非就是将DOM转换成图片,无法做到真正意义上的截图,找来找去能实现这种效果的只有SVG与canvas画布了,网上推荐较多的就是html2canvas了,html2canvas集成了SVG与canvas两种生成方式
canvas只能一点点画出来,相较与SVG有foreignObject标签,能直接将DOM丢进去渲染出来。
html2canvas(document.body, {
useCORS : true
}).then(function(canvas) {
console.log(canvas); // canvas对象
console.log(canvas.toDataURL('image/png')); // base64图片编码
}).catch(function() {
console.log('截取失败');
});
因为在现有功能上新增的需求,之前文件上传使用的elemelt-upload组件,所以现在要把它转换为指定的file对象。
const bytes = window.atob(base64.split(',')[1]);
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
};
let blobObj = new Blob([ab], { type: 'image/png' });
let newfile = new window.File([blobObj], _this.imgName + '.png', { type: blobObj.type })
实现效果:
最后提交的时候报了个错
Cannot set property 'status' of null"
status是upload组件的上传状态,ready,uploading,success,fail。
因为是手动生成的图片,没有走组件选择图片流程,在封装file对象的时候我把status改成了ready状态,Network查看上传请求成功了,但是组件没有给成功或失败的回调,网上查阅都是说file-list文件集合只读,不能手动更改。
折腾了半天最后无奈去读组件源码,发现回调里头有个判断。
对比uid...
watch监听
发现如果没有给uid会帮你根据时间戳给每个对象加了个uid,但是没给内层的文件对象增加,然后拿这个uid去跟文件对象内的uid作比较。
最后在包装file对象的时候给内外层增加的统一的uid。
此类问题没有深度但比较少见,记录一下以免后续遇到。