Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nmsn opened this issue Apr 20, 2023 · 2 comments
Open

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

nmsn opened this issue Apr 20, 2023 · 2 comments

Comments

@nmsn
Copy link
Owner

nmsn commented Apr 20, 2023

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

@nmsn
Copy link
Owner Author

nmsn commented Apr 27, 2023

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
Copy link
Owner Author

nmsn commented Apr 28, 2023

html2canvas

html2canvas

核心流程

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

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

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

其中的核心点为:

  • parseTree 将拷贝的节点中的关键渲染元素整合到 container 元素当中

  • CanvasRenderer

    • ElementPaint 收集副作用
    • StackingContext 注册多层次渲染层级列表
    • parseStackTree 递归处理 container,填充 StackingContext 的列表
  • 产出 canvas

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant