引子
产品的需求是这样,要保存当前页面为一张图片。商户需要下载这张图片,并打印。
一个库
html2canvas
js将遍历加载页面的 DOM 节点,收集所有元素的信息,然后用这些信息来呈现页面。换句话说,实际上这个库并不是真的对页面进行截图,而是基于从 DOM 读取的元素及属性来一点点的绘制 canvas。 因此,它只能正确地呈现它理解的元素和属性,这意味着有许多 CSS 属性不起作用。
图片模糊问题
移动端像素密度计算的问题
html2canvas支持自定义 canvas 作为配置项传入了,它会根据我们传入的 canvas 为基础开始绘制。所以我们在调用 html2canvas 的时候,可以先创建好一个尺寸合适的 canvas,再传进去。
重要的是设置合适的宽高
- 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
- 设定 canvas css宽高为 DOM 节点宽高
- 将所有绘制内容放大像素比倍 scale
/**
* 绘制canvas
*/
async function drawCanvas(selector) {
// 获取想要转换的 DOM 节点
const dom = document.querySelector(selector);
const box = window.getComputedStyle(dom);
// DOM 节点计算后宽高
const width = parseValue(box.width);
const height = parseValue(box.height);
// 获取像素比
const scaleBy = DPR();
// 创建自定义 canvas 元素
const canvas = document.createElement('canvas');
// 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
canvas.width = width * scaleBy;
canvas.height = height * scaleBy;
// 设定 canvas css宽高为 DOM 节点宽高
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
// 获取画笔
const context = canvas.getContext('2d');
// 将所有绘制内容放大像素比倍
context.scale(scaleBy, scaleBy);
// 将自定义 canvas 作为配置项传入,开始绘制
return await html2canvas(dom, {canvas});
}
作者:丁香园F2E
链接:https://juejin.im/post/5a17c5e26fb9a04527254689
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
污染的画布
HTML 规范中图片有一个 crossorigin 属性,结合合适的 CORS 响应头,就可以实现在画布中使用跨域 元素的图像。
- 图片的域名要返回跨域头
- html2canvas(dom, {canvas, useCORS: true})
canvas生成dataUrl
所以需要将canvas生成dataUrl
canvas.toDataURL(‘image/png’)
dataUrl to file blob
function dataURLtoBlob(data) {
var mimeString = data.split(',')[0].split(':')[1].split(';')[0]
var byteString = atob(data.split(',')[1])
var ab = new ArrayBuffer(byteString.length)
var ia = new Uint8Array(ab)
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
var bb = (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)
if (bb) {
bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)()
bb.append(ab)
return bb.getBlob(mimeString)
} else {
bb = new Blob([ab], {
'type': (mimeString)
})
return bb
}
}
file blob 下载
图片的url需要上传的OSS上之后,才会有。因此,需要先上传的OSS,调用app的接v3/upload接口可以上传图片,但是必须是file对象 得到图片的域名
下载图片
利用bridge的download方法,接受一个url