nmsn / blog

记录日常遇到的问题,需要记录的笔记以及新学到的知识,会进行汇总和分类,自动更新 README,欢迎评论和补充,互相学习
36 stars 0 forks source link

html2canvas 和 html-to-image 转换图片对比 #90

Open nmsn opened 1 year ago

nmsn commented 1 year ago

使用场景:根据 html 合成图片

nmsn commented 1 year ago

html-to-image

未命名绘图

核心流程:

  1. 复制节点及子节点
  2. 创建 svg
    • 把生成的节点填入 svg 子节点,核心方法 foreignObject
    • 生成 svgurl string,核心方法 XMLSerializer
  3. 创建 img 元素,使用刚刚生成的 svg url
  4. 创建 canvas 元素,将生成的img 元素,绘制到画布上
  5. 最终使用 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() 方法将节点序列化为字符串。

nmsn commented 1 year ago

html2canvas

html2canvas

核心流程

可以看到的是在图中存在 foreignObjectRendering 分支

如果配置为 true,则核心逻辑与 html-to-image 一致,使用 svgforeignObject 标签特性来完成 canvas 的生成,不多描述

如果配置为 false,则使用的是纯 canvas 逻辑来实现效果

其中的核心点为: