web前端编辑器内容-HTML2Canvas 截图的原理

HTML2Canvas 截图的原理

目的:一个canvas元素,上面有绘制一系列的HTML节点

局限:canvas中没法添加具体的Html节点,它只是一张画布

通过canvas.getContext(‘2d’)可以拿到canvas提供的2D渲染上下文,然后在里面绘制形状,文本,图象和其他对象。

文档地址:canvas

  • 矩形-fillRect()
  • 文本-fillText()
  • 图象-drawImage()

等等…

SVG来拯救我们

可缩放矢量图(Scalable Vector Graphics, SVG),是一种可用于描述二维的矢量图,基于XML的标记语言。

SVG中有一个神奇的元素称之为foreignObject

  • 文档地址foreignObject
  • SVG中的 foreignObject元素允许包含来自不同的 XML 命名空间的元素。在浏览器的上下文中,很可能是 XHTML / HTML。
  • 注:ie不支持

解题思路:

  • 创建一个 canvas元素
  • 创建svg文件,使用 Blob构造函数
  • 将svg中的值填充 foreignObject,然后填充想要
  • 复制节点的 HTML
  • 创建 image标签,将image.src = URL.crateObjectURL(svg)
  • 在image完成读取以后,调用canvas的drawImage方法,将图片绘制到画布上
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <canvas id="canvas-image"></canvas>
  <div class="author" id="author" style="color: red;" >
    这是模仿html2canvas使用的
  </div>
  <button>点击一下</button>
</body>
<script>
const drawCanvas = () => {
  // canvas-image元素
  const canvas = document.getElementById('canvas-image')
  canvas.width = 400;
  canvas.height = 400;
  // 需要获取截图的内容
  const element = document.getElementById('author')
  const data = 
    "<svg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'>" + 
      "<foreignObject width='100%' height='100%'>" + 
        "<div xmlns='http://www.w3.org/1999/xhtml'>" + 
          element.innerHTML + 
        "</div>" + 
      "</foreignObject>" +
    "</svg>"
   // 创建svg文件
   const svg = new Blob([data], { type: "image/svg+xml;charset=utf-8"})
   // 创建一个image元素
   const url = URL.createObjectURL(svg)
   const image = new Image()
   image.src = url;
   image.addEventListener('load', () => {
    const ctx = canvas.getContext('2d')
    if(ctx) {
      ctx.drawImage(image, 0, 0)
    }
   })
}
const btn = document.querySelector('button')
btn.addEventListener('click', drawCanvas)
</script>
</html>

在这里插入图片描述
样式没起作用,原因是我们只添加的html,并没有添加样式,如果要做到一样,需要把样式也添加到svg中去,这就是htmlCanvas简单的原理。
内部的原理主要是根据要截图元素的节点进行遍历,根据类型进行复制,添加样式,另外就是对于不支持foreignObject,做兼容性处理。

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值