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 })
 

实现效果:

JS截取页面+elemelt-upload上传

JS截取页面+elemelt-upload上传

最后提交的时候报了个错

Cannot set property 'status' of null"
 

status是upload组件的上传状态,ready,uploading,success,fail。

因为是手动生成的图片,没有走组件选择图片流程,在封装file对象的时候我把status改成了ready状态,Network查看上传请求成功了,但是组件没有给成功或失败的回调,网上查阅都是说file-list文件集合只读,不能手动更改。

JS截取页面+elemelt-upload上传

折腾了半天最后无奈去读组件源码,发现回调里头有个判断。

JS截取页面+elemelt-upload上传

对比uid...

JS截取页面+elemelt-upload上传

watch监听

JS截取页面+elemelt-upload上传

发现如果没有给uid会帮你根据时间戳给每个对象加了个uid,但是没给内层的文件对象增加,然后拿这个uid去跟文件对象内的uid作比较。

最后在包装file对象的时候给内外层增加的统一的uid。

此类问题没有深度但比较少见,记录一下以免后续遇到。

回复

我来回复
  • 暂无回复内容