不知道大家有没有在使用domtoimage中碰到过截图下来的文件经常损坏的问题
由于项目中需要前端做截图并且进行文件上传或保存到本地这个需求。
于是呢,我尝试了在csdn上搜索前端截图的插件,通过比较html2canva和domtoimage以后果断选择了domtoimage这个插件。主要是真的简单,调用就好啦。
import domtoimage from 'dom-to-image'
domtoimage.toPng(el).then(function (dataUrl) {
const link = document.createElement('a')
link.download = fileName + '.png'
link.href = dataUrl
link.click()
})
需要进行图片上传到后台的小伙伴就需要自己将拿到的dataUrl转成blob然后传给后台就可以啦(如果你懒的话也可以让后台做!!!),勤快的小伙伴就自己转一下吧!
const base64ToBlob = (dataUrl, fileName) => {
const arr = dataUrl.split(',')
const m = arr[0].match(/:(.*?);/)[1]
const bstr = window.atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], fileName, { type: m })
}
转完以后用formData包装一下调取你们后台服务上传就好啦
const t = base64ToBlob(dataUrl, fileName + '.jpeg')
const formData = new FormData()
formData.append('file', t)
this.$rest.post({
url : url,
headers: {
'Content-Type': 'multipart/form-data'
},
data: formData
})
写完以后我测试了一边是ok的,下载下来的图片也能看吧只能说。
可是过了一点时间以后我发现截图下载到本地的都是已损坏的文件。这就有点让人摸不着头脑了。
于是我去查看了domtoimage.toPng的源码,并在源码各个调用处debugger了一下,最后发现在toPng函数里调用的draw函数的回调中对绘制完毕的canvas标签进行了console.log,结果发现canvas标签的width参数居然达到了二十多万,height参数一百多万。
function toPng(node, options) {
return draw(node, options || {})
.then(function (canvas) {
return canvas.toDataURL();
});
}
我悟了!!!
由于我们项目中是4k数据大屏的那种页面,所以之前公司大佬为了大屏效果采用了一个名为$flex的方法对页面进行了缩放控制。
$flex (params = { h: 2880, w: 5760 }) {
return {
subscribe: () => {
// iframe 不需要再进行订阅
if (window.top !== window.self) {
return
}
onresize = function () {
setScale()
}
const setScale = () => {
const ratioY = innerHeight / params.h
const ratioX = innerWidth / params.w
document.body.style.transform = 'scale(' + ratioX + ',' + ratioY + ')'
document.body.style.transformOrigin = 'left top'
document.body.style.overflow = 'hidden'
}
setScale()
},
unsubscribe: () => {
onresize = () => {}
document.body.style.transform = 'scale(' + 1 + ',' + 1 + ')'
}
}
}
所以这个width和height异常的大的原因可能是这个。于是我又去看了一下domtoimage的源码,发现第二个参数options,于是我尝试了一下(由于这个页面是4096*2160的)
domtoimage.toPng(el, { width: 4096, height: 2160 })
问题解决!!!
但是我想不通的是之前没有配置的时候明明截图是可以的呀,为什么用着用着就不行了。而且会出现我本地截图成功,线上截图失败的这种问题,有大佬懂的么