将 SVG 转换为使用 JS 中的 ctx 命令渲染

问题描述 投票:0回答:1
javascript svg canvas rendering ctx
1个回答
0
投票

要在画布中实现完整的 SVG 渲染器是一项相当艰巨的工作...但是,如果您完全控制要转换的 SVG 导出,您可能能够摆脱像这样的非常有限的实现:

  • 使用
    ctx.scale
    ctx.translate
    来实现
    viewBox
    。这确保我们可以以任何分辨率渲染画布,而不必担心 SVG 绘图的单位系统
  • 使用
    Path2D
    构建基于 SVG
    d
    属性的路径

我已经在评论中提出了这种方法的一些限制,但为了确保我也会在这里列出它们:

  • 仅循环
    path
    元素。如果您需要诸如
    <circle />
    <rect />
    等之类的东西,您必须自己实现这些。
  • 仅接受直接设置到路径元素的
    fill
    属性。
  • transform
    上跳过
    path
    (尽管这个并不难添加)

总而言之,我认为我会推荐一种将

svg
图像渲染为图像数据并将其放入画布中的方法......

const W = 400;
const H = 400;

const svg = document.querySelector("svg");
const cvs = document.querySelector("canvas");
const ctx = cvs.getContext("2d");


const draw = (width, height) => {
  // Viewbox
  const { width: vbw, height: vbh, x, y } = svg.viewBox.baseVal;
  cvs.width = width;
  cvs.height = height;

  ctx.scale(width / vbw, height / vbh);
  ctx.translate(-x, -y);


  // Shortcut: only implement <path />
  for (const path of svg.querySelectorAll("path")) {
    // Shortcut: only support direct fill attributes
    // (e.g. no inheritance from parent <g>)
    const fill = path.getAttribute("fill");
    const d = path.getAttribute("d");

      // Shortcut: skip transform attribute
    const p = new Path2D(d);

    ctx.fillStyle = fill;
    ctx.fill(p);
  }
}

draw(W, H);
svg,
canvas {
  background: #efefef;
}

h2 {
  margin: 0;
}
<h2>SVG</h2>
<svg viewBox="188.1601 295.929 33.6399 36" width="33.6399" height="36" xmlns="http://www.w3.org/2000/svg">
  <path fill="#744EAA" d="M 192.8 299.929 C 195.8 299.929 197.8 301.929 200.8 305.929 C 203.8 309.929 208.757 313.12 212.8 313.929 C 217.8 314.929 221.8 318.929 221.8 324.929 C 221.8 329.826 217.954 331.929 212.8 331.929 C 207.8 331.929 203.8 328.929 198.8 323.929 C 193.8 318.929 188.8 309.929 188.8 305.929 C 188.8 301.929 189.8 299.929 192.8 299.929 Z" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, 0)"/>
  <path fill="#77B255" d="M 190.315 295.929 C 191.563 295.929 191.563 297.177 191.563 298.424 C 191.563 300.188 192.811 299.553 194.059 299.553 C 195.305 299.553 197.8 301.929 197.8 301.929 L 194.058 301.929 C 192.81 301.929 194.058 304.543 192.81 304.543 C 191.562 304.543 191.562 303.355 190.315 303.355 C 189.068 303.355 188.8 306.929 188.8 306.929 C 188.8 306.929 187.196 302.776 189.067 300.905 C 190.315 299.657 187.82 295.929 190.315 295.929 Z" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, 0)"/>
</svg>

<h2>Canvas</h2>
<canvas></canvas>
<br/>
<button onclick="draw(100, 100)">100⨯100px</button>
<button onclick="draw(200, 200)">200⨯200px</button>
<button onclick="draw(400, 400)">400⨯400px</button>

© www.soinside.com 2019 - 2024. All rights reserved.