首页 > 解决方案 > 将节点元素转换为图像

问题描述

我正在寻找可以帮助我将 HTML DOM 节点元素转换为图像/png 文件的库或代码片段。

我尝试使用html2canvas库,但它不渲染svg节点,并且在我当前的项目中我有很多节点。我还尝试使用canvg库将页面上的所有SVG元素转换为Canvas元素,但canvg总是在渲染步骤中抛出错误:

未捕获(承诺中)TypeError:无法读取未定义的属性“ImageClass”

用于将 SVG 转换为 Canvas 的代码片段:

export const svgToCanvas = () => {
  const print = document.getElementsByClassName('print-page')[0]
  const svgElements = print.getElementsByTagName('svg')
  _.each(svgElements, e => {
    let xml
    const canvas = document.createElement('canvas')
    canvas.className = 'screenShotTempCanvas'
    xml = (new window.XMLSerializer()).serializeToString(e)
    xml = xml.replace(/xmlns=http:\/\/www\.w3\.org\/2000\/svg/, '')
    canvg(canvas, xml)
    e.parentNode.insertBefore(canvas, e.nextSibling)
    e.classList.add('tempHide')
    e.style.display = 'none'
  })

  const temps = document.getElementsByClassName('.screenShotTempCanvas')
  _.each(temps, e => {
    e.remove()
  })
  const svgs = document.getElementsByClassName('tempHide')
  _.each(svgs, e => {
    if (e) {
      e.style.display = 'block'
      e.classList.remove('tempHide')
    }
  })
}

在canvg代码的这一行抛出错误:

if (nodeEnv) {
    if (!s || s === '') {
        return;
    }
    ImageClass = opts['ImageClass'];  //<= error throws here
    CanvasClass = target.constructor;
    svg.loadXml(target.getContext('2d'), s);
    return;
}

我还尝试使用jsPDFhtml-pdf库将节点转换为 PDF 格式,但在这种情况下,所有样式都从节点中消失,我需要它们不要丢失。

谁能为我提供适当的方法如何将 HTML DOM 节点(富含 SVG 元素)转换为图像?

标签: javascripthtmlsvgcanvashtml2canvas

解决方案


这似乎是 canvg 作者严重错误测试和记录的结果。引发错误的行是作为拉取请求的一部分引入的,据称该请求增加了对在节点环境中执行 canvg 的支持。但似乎只有在node-svg2img中用作依赖项时才对其进行测试。

如果您查看该来源,您会发现以下内容(摘录):

var canvg = require('canvg'),
    Canvas = require('canvas');

function convert(svgContent) {
    var canvas = new Canvas();
    canvg(canvas, svgContent, { ignoreMouse: true, ignoreAnimation: true, ImageClass: Canvas.Image });
    return canvas;
}

如您所见,使用从未记录过canvg的选项调用,其内容依赖于模块画布,该模块画布从未被声明为 canvg 的依赖项。(这不是轻量级的,它是完整的实现。)ImageClass<canvas>

现在您从未说过您在节点中执行所有这些操作,但我会假设您这样做,否则我将不明白为什么会调用导致错误的行。

似乎成功调用document.createElement('canvas')并不表示您已canvas安装该模块。jsdom 文档中的这个注释告诉你需要做什么。

从那里,调用canvg你的代码

import Image from 'canvas';

canvg(canvas, xml, {ImageClass: Image});

应该让你跑步。


推荐阅读