html2canvas 和 html-to-image 转换图片对比
使用场景:根据 html 合成图片
html-to-image

核心流程:
- 复制节点及子节点
- 创建
svg- 把生成的节点填入
svg子节点,核心方法foreignObject - 生成
svg的urlstring,核心方法XMLSerializer
- 把生成的节点填入
- 创建
img元素,使用刚刚生成的svgurl - 创建
canvas元素,将生成的img元素,绘制到画布上 - 最终使用
canvas.toDataURL生成base64图片链接
<foreignObject>
该元素通过嵌套一个 HTML 文档在 SVG 中中显示复杂的内容,相当于将一段 HTML 代码注入到 SVG 中
下面的代码将在 SVG 中嵌入一个包含一段文本的 <div> 元素:
<svg width="100" height="100">
<foreignObject x="10" y="10" width="80" height="80">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>This is some HTML content.</p>
</div>
</foreignObject>
</svg>
请注意,由于 SVG 是一种矢量图形格式,而 HTML 是一种基于像素的格式,因此在将 HTML 插入到 SVG 中时可能会出现一些问题,特别是在尺寸缩放方面。此外,某些浏览器可能不支持 <foreignObject> 元素,或在使用时会出现一些限制。
XMLSerializer
XMLSerializer 是一个用于将 DOM 树序列化为 XML 或字符串的 API。它可以将 DOM 树转化为 XML 或字符串,从而将 DOM 节点导出到 XML 或字符串中,以便于存储、传输或打印输出。
XMLSerializer 的使用非常简单,只需要创建一个新的 XMLSerializer 实例,然后调用其 serializeToString() 方法,将要序列化的节点作为参数传递即可。
以下是一个使用 XMLSerializer 序列化 DOM 树为字符串的示例代码:
// 获取需要序列化的 DOM 节点
const node = document.getElementById('my-node');
// 创建 XMLSerializer 实例
const serializer = new XMLSerializer();
// 序列化节点为字符串
const xmlString = serializer.serializeToString(node);
上述代码中,我们首先获取了需要序列化的 DOM 节点,然后创建了一个新的 XMLSerializer 实例,最后调用其 serializeToString() 方法将节点序列化为字符串。
html2canvas

核心流程
可以看到的是在图中存在 foreignObjectRendering 分支
如果配置为 true,则核心逻辑与 html-to-image 一致,使用 svg 的 foreignObject 标签特性来完成 canvas 的生成,不多描述
如果配置为 false,则使用的是纯 canvas 逻辑来实现效果
其中的核心点为:
-
parseTree 将拷贝的节点中的关键渲染元素整合到 container 元素当中
-
CanvasRenderer
- ElementPaint 收集副作用
- StackingContext 注册多层次渲染层级列表
-
parseStackTree 递归处理 container,填充
StackingContext的列表
-
产出 canvas