前端截图功能踩坑记录

91 阅读2分钟

背景

小P错题本中,需要分享功能,因此考虑在前端实现页面截图

有html2canvas和dom-to-image两个工具,经测试,html2canvas效果很差,因此这里用了dom-to-image去做截图

image.png

场景

前端以离线资源的形式在ios/安卓客户端中运行

dom-to-image的流程是,先将node转换为svg的base64格式,再通过svg的base64转换成其他格式的base64

问题

  1. 调用后,报错,无法成功转换图片。报错见下图

    1. image.png
    2. 一开始以为是dom-to-image的问题,因为git仓库中写着:**Safari is not supported, as it uses a stricter security model on <foreignObject> , **即不支持safari.不过这个库是几年前的,issue中显示新版本的safari已经支持了,因此继续排查
    3. 后续发现处理后的图片都挺大,11M,怀疑是尺寸的问题。经排查,svg的base64生成成功,但是再转成png的base64时报了这个错误。不过在对其他元素进行切图时,图片依旧很大,但是能正常转换
    4. 可以看到,页面中有个饼图,是canvas实现的,因此之后将饼图去掉,发现能正常展示,那么基本可以确定是饼图的问题
    5. 解决方案:将饼图的canvas转换为base64,再通过新建div元素并设置background-image去替换掉canvas。即canvas饼图变成的div的纯图片饼图。处理后,图片就能出来了
  2. 上述饼图处理成div后,在ios前几次往往不能展示

    1. 解决:对饼图做压缩处理,体积减半后能正常显示了
    2. 压缩代码
    3. image.png
  3. 截图出来的图片不清晰

    1. 解决方案:放大canvas 
    2. 通过复制dom-to-image库,并在源码中手动增加支持scale的参数
  4.  加载图片跨域(仅ios存在)

    1. 前端是离线资源的,而图片资源也是离线,因此是本地file:/xxx/index.html请求file:/xxx/xxx.png的场景,从而在ios中会有跨域问题

      1. 经测试,在safari中,本地请求http文件没有跨域问题(前提是cdn没有限制同源),前端在http请求http也没有,唯独本地请求本地会有
    2. 解决:小图片用base64替换,大图片手动用对应https替换,使得加载http文件而不是本地文件

  5. 字体跨域

    1. 暂未处理