Skip to content

屏幕截图实战

引子

产品的需求是这样,要保存当前页面为一张图片。商户需要下载这张图片,并打印。

一个库

html2canvas

js将遍历加载页面的 DOM 节点,收集所有元素的信息,然后用这些信息来呈现页面。换句话说,实际上这个库并不是真的对页面进行截图,而是基于从 DOM 读取的元素及属性来一点点的绘制 canvas。 因此,它只能正确地呈现它理解的元素和属性,这意味着有许多 CSS 属性不起作用。

图片模糊问题

移动端像素密度计算的问题

html2canvas支持自定义 canvas 作为配置项传入了,它会根据我们传入的 canvas 为基础开始绘制。所以我们在调用 html2canvas 的时候,可以先创建好一个尺寸合适的 canvas,再传进去。

重要的是设置合适的宽高

  • 设定 canvas 为 DOM 节点宽高 * 像素比
  • 设定 canvas为 DOM 节点宽高
  • 将所有绘制内容 scale
javascript
/**
 * 绘制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 响应头,就可以实现在画布中使用跨域 元素的图像。

  1. 图片的域名要返回跨域头
  2. html2canvas(dom, {canvas, useCORS: true})

canvas生成dataUrl

所以需要将canvas生成dataUrl

canvas.toDataURL('image/png')

dataUrl to file blob

javascript
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

更新: 2019-03-13 09:58:42
原文: https://www.yuque.com/u3641/dxlfpu/bvdea7