html转图片之html2canvas与domtoimage踩坑(移动端)

5,701 阅读2分钟

1.domtoimage

  • android下同一页面,如果toBlob得到图片数据30M,toJpeg得到图片数据大概为10M;
  • toPng在iOS下得到与原dom宽高相等的空白图片
  • iOS只能用toSvg生成图片、android都可以但是不能将src为svg的图片保存到本地;
  • iOS下微信浏览器中toSvg虽然可以保存,但是能且仅能保存当前页面中可见的图片部分,且图片与原dom宽高相等,非当前可见部分全部空白;
  • iOS下safari浏览器长按保存toSvg生成图片没有反应,应该是浏览器不支持;
  • iOS下chrome浏览器可以保存;

代码:

const UA = window.navigator.userAgent;  // 获取当前设备以及浏览器信息
const isAndroid = UA.indexOf("Android") > 0;    // 判断是否是android
const isIOS = UA.indexOf("iPhone") > 0; // 判断是否是iOS
const node = document.querySelector("#root");   // 需要绘制成图片的dom节点
if (isIOS) {
  domtoimage.toSvg(node).then((dataUrl) => {
    const img = new Image();
    img.src = dataUrl;
    img.onload = () => {
      node.appendChild(img);
    };
  });
} else if (isAndroid) {
  domtoimage.toJpeg(node).then(function (dataUrl) {
    const img = new Image();
    img.src = dataUrl;
    img.onload = () => {
      node.appendChild(img);
    };
  });
} else {}

2.html2canvas

  • 页面内容太长太大会转canvas失败,但是还是走到.then(...)没有catch到异常
  • 图片跨域会导致canvas白屏,第一步一定优先解决跨域,不然可能会有这种各样的问题,解决方案如下:
    • 1.本方案在nginx服务器中对应的server中配置:
    location ~ .*\.(gif|jpg|jpeg|png|bmp||ico)$ {
        #允许跨域请求
        add_header Access-Control-Allow-Origin '*';
        add_header Access-Control-Allow-Headers X-Requested-With;
        add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
    }
    
    • 2.在html2canvas开启跨域访问配置:
    html2canvas(node, { height: node.scrollHeight, useCORS: true }).then(
        function (canvas) {
          const img = new Image();
          img.src = canvas.toDataURL();
          img.onload = () => {
            node.appendChild(img);
          };
        }
      );
    
  • 在一些高清设备中,设备自身的scale值可能是2或者3(获取方式:window.devicePixelRatio;),在html2canvas中有个配置项{ scale: window.devicePixelRatio // 默认值 },表示放大渲染到原显示大小的的倍数,html2canvas说明了各种浏览器上支持的最大像素大小和内存大小,如果超过大小会导致截取失败,表现是可能没有任何反应;
  • 有遇到一种奇怪的情况:截取白屏,但是将scale值调整为1或者2就好了,注意说他奇怪是因为之前有两种情况虽然走到了.then(...)但是内容太长太大截取是没有反应的,现在这个情况是页面有反应,但是是白屏;
  • 还有一些兼容问题参考官方文档中的Unsupported CSS properties:html2canvas.hertzen.com/features
  • 除了官方文档中列出的问题以外,还有一些本人自己出现的问题:z-index并不生效,del标签不支持并且line-through样式也不支持,需要自己想办法处理;

综上,个人觉得domtoimage库是比较好的,但是其svg的处理让人怎么也爽不起来,建议iOS上也将png与jpeg的形式做好到时候必然舍弃html2canvas来弃暗投明;html2canvas虽然功能很强大,但是不注意一些隐藏的坑会让你痛苦好一阵子,但是它真的能满足你。