Fabric.js 破坏了具有多个路径的 SVG

问题描述 投票:0回答:1

我使用的是之前从 .dxf 转换而来的 SVG 文件。它们包含多个路径。 我使用 fabric.loadSVGFromString 然后使用 fabric.util.groupSVGElements 在画布上加载一个 svg。 然后我使用 canvas.toSVG() 导出画布内容。当我在浏览器或 Inkscape 中加载导出的 SVG 时,SVG 被分段,并且似乎每条路径都是一条单独的线,当有弧线或在 2 条线连接的拐角处时,这一点更加明显。

我假设这是由于 Fabric.util.groupSVGElements 将加载的 svg 分割为不同元素造成的,因为这些路径有多个。

我需要一个解决方案,因为我需要导出的文件像以前一样包含 SVG,并且所有行都不间断。我该如何处理这个问题?

重现步骤:

  1. 使用ADD SVG to canvas按钮将SVG加载到底部画布(红色边框画布)

  2. 使用“显示导出的画布”按钮通过 toSVG() 导出红色边框画布内容 - 其内容将加载到蓝色边框 div

预期结果:svg 线条与 svg 最初一样保持不间断

实际结果:svg 线条被破坏,这在使用放大时可见:(

svg before and after

更多详细信息和jsfiddle链接:https://groups.google.com/g/fabricjs/c/O1HtbMOnOck 或jsfiddle:/IoanaBraica/m4n8uoex/78/

我尝试了多种方法来使用 Fabric 加载这个 svg。将其作为图像加载并不是一个解决方案,因为在画布上操作 svg 之后,我必须将其转换回 DXF,而将结果作为图像是不可能的。

javascript svg fabricjs
1个回答
0
投票

此问题是由某些转换/翻译值中的舍入错误引起的。

显然,fabric.js 计算的翻译值四舍五入到小数点后 2 位。

作为解决方法,您可以在将所有路径加载到 Fabric.js 画布之前组合它们。

/**
 * combine paths helper
 */
function combinePaths(svgMarkup) {
  let svg = new DOMParser().parseFromString(svgMarkup, "text/html").querySelector("svg");
  let paths = svg.querySelectorAll("path");
  let firstPath = paths[0];

  let dCombined = "";
  paths.forEach((path, i) => {
    let d = path.getAttribute("d");
    dCombined += d;
    if (i > 0) {
      path.remove();
    }
  });
  firstPath.setAttribute("d", dCombined);
  let newSVG = new XMLSerializer().serializeToString(svg);
  return newSVG;
}



var canvas = new fabric.Canvas("canv");
var svg = `<?xml version="1.0" standalone="no"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"[]>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body_-601143644_6578" width="6.815056473908554in" height="1.7112020646806974in">
    <g transform="matrix(95.500792 0 0 -95.500792 1.7010636 82.138042)">
      <g>
        <path d="M-4.7087673E-09 0.28821083L0.0073893023 0.25296545L0.01721924 0.21832137L0.029441858 0.18444738L0.04399764 0.15150853L0.060815657 0.11966527L0.079813982 0.08907274L0.10090004 0.059879965L0.12397115 0.032229221L0.14891486 0.0062551864L0.17560967 -0.017915599L0.20392551 -0.040165357L0.23372447 -0.060385697L0.26486131 -0.07847812L0.29718438 -0.094354503L0.33053619 -0.10793744L0.33140596 -0.10825585" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0 0.51393133L0 0.2882109" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.31213705 0.85560461L0.28350142 0.84688668L0.25554367 0.83619245L0.22840002 0.82357406L0.20220271 0.80909293L0.17707937 0.79281967L0.15315239 0.77483352L0.13053833 0.75522213L0.10934739 0.73408105L0.089682809 0.71151324L0.071640364 0.68762868L0.055307976 0.66254372L0.040765217 0.63638057L0.028082929 0.60926672L0.017322919 0.58133422L0.0085375825 0.5527192L0.0017697135 0.52356105L-7.9355301E-09 0.51393123" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M2.4203046 0.23280891L2.383579 0.22032561L2.3478136 0.20531084L2.3131828 0.18783777L2.2798551 0.16799154L2.2479931 0.14586883L2.2177518 0.1215774L2.1892787 0.095235669L2.1627125 0.066971892L2.1381825 0.036923819L2.1158084 0.0052378119L2.0956991 -0.027931725L2.0779526 -0.062423249L2.0626552 -0.098068675L2.0498817 -0.13469435L2.0396942 -0.17212187L2.0321422 -0.21016884L2.0272628 -0.24864994L2.0250795 -0.28737767L2.025603 -0.32616336L2.0288307 -0.36481806L2.0347471 -0.40315344L2.0433232 -0.44098272L2.0545172 -0.47812162L2.0682746 -0.5143892L2.0845285 -0.54960877L2.1031995 -0.58360872L2.1241967 -0.61622343L2.1474179 -0.64729399L2.1727499 -0.67666906L2.2000693 -0.70420548L2.229243 -0.72976911L2.2601289 -0.75323546L2.2925764 -0.77449012L2.3264276 -0.79342958L2.3615174 -0.80996159L2.397675 -0.82400557L2.4347242 -0.83549312L2.4471617 -0.83872452" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.82451884 0.28686318L0.82031025 0.25443185L0.81384958 0.22237308L0.80516837 0.1908431L0.79430892 0.15999548L0.78132404 0.12998053L0.76627709 0.10094445L0.74924134 0.073028757L0.73029979 0.046369387L0.7095447 0.021096273L0.68707721 -0.0026674726L0.66300677 -0.024806068L0.63745068 -0.045211688L0.6105334 -0.063784883L0.58238608 -0.080435202L0.55314587 -0.095081494L0.52295521 -0.10765241L0.52134138 -0.10825581" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M3.2709704 0.23280893L3.2709704 -0.40736173" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M2.4471617 -0.83872457L2.4876074 -0.84711339L2.5285397 -0.85266043L2.5697593 -0.85533871L2.6110653 -0.8551351L2.6522564 -0.85205068L2.6931321 -0.84610035L2.7334931 -0.83731319L2.7731429 -0.82573201L2.8118882 -0.81141324L2.8495403 -0.79442658L2.8859157 -0.77485479L2.9208373 -0.75279333L2.9541349 -0.72834955L2.9856462 -0.70164262L3.0152178 -0.67280261L3.0427056 -0.64197005L3.0679757 -0.60929515L3.0909049 -0.57493706L3.1113816 -0.53906323L3.1293059 -0.5018484L3.1445906 -0.46347389L3.1571613 -0.42412666L3.1616152 -0.40736167" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M3.1616152 -0.40736173L3.2709704 -0.40736173" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.33140589 -0.10825581L0.52134137 -0.10825581" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.82451883 0.28686319L1.9041929 0.28686319" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.82451883 0.41322856L1.9041929 0.41322856" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.82451885 0.41322856L0.81972855 0.44893116L0.8124594 0.48421263L0.80274686 0.51890108L0.79063823 0.55282752L0.77619251 0.58582668L0.75948008 0.61773775L0.74058234 0.6484053L0.71959137 0.67767991L0.69660946 0.70541896L0.67174854 0.73148726L0.64512976 0.75575788L0.61688279 0.77811254L0.58714523 0.79844235L0.55606199 0.81664823L0.52378451 0.8326415L0.49047 0.84634425L0.46320459 0.85560466" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M0.31213707 0.85560463L0.4632046 0.85560463" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M3.2709704 0.23280893L6.8150564 0.23280893" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M6.8150564 0.46596293L6.8150564 0.23280893" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M2.5330992 0.46596293L6.8150564 0.46596293" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M2.4203046 0.26479106L2.4203046 0.23280893" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M2.5330992 0.46596293L2.5330992 0.43739009" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M1.9041929 0.43739009L2.5330992 0.43739009" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M1.9041929 0.26479106L2.4203046 0.26479106" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M1.9041929 0.28686319L1.9041929 0.26479106" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        <path d="M1.9041929 0.43739009L1.9041929 0.41322856" stroke="#000000" stroke-width="0.001481663" stroke-linecap="round" stroke-linejoin="round" fill="none" />
      </g>
    </g>
  </svg>`;

canvas.setWidth(1000);
canvas.setHeight(1000);

function exportSVG() {
  let mySvg = canvas.toSVG();
  canvas.includeDefaultValues = false;
  const res = document.getElementById("result");
  console.log(mySvg);
  res.innerHTML = mySvg;
}

function add() {
  //combine paths
  let svgMerged = combinePaths(svg);

  fabric.loadSVGFromString(svgMerged, function (objects, options) {
    var obj = fabric.util.groupSVGElements(objects, options);

    canvas.add(obj);
    canvas.setActiveObject(obj);
    canvas.requestRenderAll();
  });
}
#result {
    border: 2px solid blue;
}

#canv {
    border: 2px solid red;
}
<div id="result">
    Result:
</div>

<button id="svg" onclick="add()" type="submit">
    ADD SVG to canvas (all good)
</button>
<button id="order" onclick="exportSVG()" type="button">
    Display Exported Canvas (lines are separated - use zoom in to see it)
</button>   

<canvas id="canv" class="cv" style="width: 2400px; height: 2400px"></canvas>
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>

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