html2canvas图片位移_html2canvas截图失真怎么解决?

浏览器端网页截图方案详解

原文链接:玄魂:浏览器端网页截图方案详解​zhuanlan.zhihu.com

玄魂 前端,图形图像,可视化

简介 剖析流行的截图插件 html2canvas 的实现方案,探索其功能上的一些不足之处及不能正确截取的一些场景,比如不支持 CSS 的 box-shadow 截取情况等。探索一种新的实现方式,能够避免多数目前 html2canvas 不支持的情况,解密其原理,深究 Canvas 绘图的机制。 本篇文章你可以学到:纯前端网页截图的基本原理

html2canvas 的核心原理

SVG 内嵌 HTML 的方式

Canvas 渲染 SVG 的方式及各种问题的解决方案

适合人群:前端开发 开篇 平时很多时候,需要把当前页面或者页面某一部分内容保存为图片分享出去,也或者有其他的业务用途,这种在很多的营销场景和裂变的过程都会使用到,那我们要把一个页面的内容转化为图片的这个过程,就是比较需要探讨的了。 首先这种情况,想到的实现方案就是使用 Canvas 来实现,我们探索一下基本实现步骤:把需要分享或者记录的内容绘制到 Canvas 上

把绘制之后的 Canvas 转换为图片

这里需要明确的一点就是,只要把数据绘制到 Canvas 上,这就在 Canvas 画布上形成了被保存在内存中的像素点信息,所以可以直接调用 Canvas 的 API 方法 toDataURL、toBlob,把已经形成的像素信息转化为可以被访问的资源 URI,同时保存在服务器当中。这就很轻松的解决了第二步(把 Canvas 转为图片链接),下面是代码的实现:

在实现了第二步的情况之下,需要关注的就是第一步的内容,怎么把内容绘制到 Canvas 上,我们知道 Canvas 的绘图环境有一个方法是 ctx.drawImage,可以绘制部分元素到 Canvas 上,包含图片元素 Image、svg 元素、视频元素 Video、Canvas 元素、ImageBitmap 数据等,但是对于一般的其他 div 或者列表 li 元素它是不可以被绘制的。 所以,这不是直接调用绘图的 API 就可以办到的,我们就需要思考其他的方法。在一般的实现上,比较常见的就是使用 html2canvas,那么我们先来聊聊 html2canvas 的使用和实现。 html2canvas 的使用及实现 使用 首先看一下 html2cavas 的使用方法:

调用 html2canvas 方法传入想要截取的 Dom,执行之后,返回一个 Promise,接收到的 Canvas 上,就绘制了我们想要截取的 Dom 元素。到这一步之后,我们再调取 Canvas 转图片的方法,就可以对其做其他的处理。 这里它的 html2canvas 方法还支持第二个选项传入一些用户的配置参数,比如是否启用缓存、整个绘图 Canvas 的宽高值等。 在这个转换的过程,在 html2canvas 的内部,是怎么把 Dom 元素绘制到 Canvas 上的,这是咱们需要思考的问题! 实现 首先咱们先献上一个内部的大致流程图:

对比着内部的流程图,就可以理一下整体的思路,整体的思路就是遍历目标节点和子节点,收集样式,计算节点本身的层级关系和根据不同的优先级绘制到画布中,下面基于这个思路,咱们深入一下整个过程。 1. 调用 html2canvs 函数,直接返回一个执行函数,这一步没有什么。 2. 在执行函数的内部第一步是构建配置项 defaultOptions,在合并默认配置的过程中,有一个缓存的配置,它会生成处理缓存的方法。处理缓存类,对于一个页面中的多个不同的地方渲染调用多次的情况做优化,避免同一个资源被多次加载;

缓存类里面控制了所有图片的加载和处理,包括使用 proxy 代理和使用 cors 跨域资源共享这两种情况资源的处理,同时也对 base64 和 blob 这两种形式资源的处理。比如如果渲染 Dom 里面包含一个图片的链接类型是 blob,使用的方式就是如下处理,然后添加到缓存类中,下次使用就不需要再重新请求。

3. 在上一步生成了默认配置的情况之下,传入需要绘制的目标节点 element 和配置到 DocumentCloner 里面,这个过程会克隆目标节点所在的文档节点 document,同时把目标节点也克隆出来。这个过程中,只是克隆了开发者定义的对应节点样式,并不是结合浏览器渲染生成特定视图最后的样式。

如上这个 .box 的元素节点,定义的样式只有高度,但是在浏览器渲染之下,会对它设置默认的文字样式等等。 4. 基于上一步的情况,就需要把克隆出来的目标节点所在的文档节点 document 进行一次浏览器的渲染,然后在收集最终目标节点的样式。于此,把克隆出来的目标节点的 document 装载到一个 iframe 里面,进行一次渲染,然后就可以获取到经过浏览器视图真实呈现的节点样式。

在这个过程中,就可以通过 window.getComputedStyle

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值