【问题标题】:Unexpected polyline generated by SVG.js at node with svgdomSVG.js 在具有 svgdom 的节点处生成意外的折线
【发布时间】:2017-09-24 05:28:11
【问题描述】:

我有不同的 svg.js 在浏览器中生成的 svg 字符串(正确的一个)和节点(不正确并且带有过多的内部 svg 元素) 这是我的浏览器代码:

let size = { width: 512, height: 512 };
let entity = { x: 232,
  y: 162,
  rx: 137,
  ry: 146,
  a: 13,
  strokeColor: 0,
  strokeAlfa: 0.8,
  strokeWidth: 2,
  fillColor: 10,
  fillAlfa: 0.8 };
let draw = SVG(document.documentElement).size(size.width,size.height);
  let svg = draw
  .rect(size.width,size.height).fill("#fff");
  draw
  .ellipse(entity.rx,entity.ry)
  .move(entity.x,entity.y)
  .rotate(entity.a)
  .stroke({
    color:'rgb('+entity.strokeColor+','+entity.strokeColor+','+entity.strokeColor+')',
    opacity:entity.strokeAlfa,
    width:entity.strokeWidth
  })
  .fill({
    color:'rgb('+entity.fillColor+','+entity.fillColor+','+entity.fillColor+')',
    opacity:entity.fillAlfa});
    console.log(draw.svg());
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.3/svg.min.js"></script>
在浏览器中生成的 svg 是干净的:
<svg id="SvgjsSvg1006" width="512" height="512" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs">
<defs id="SvgjsDefs1007"></defs>
<rect id="SvgjsRect1008" width="512" height="512" fill="#ffffff"></rect>
<ellipse id="SvgjsEllipse1009" rx="68.5" ry="73" cx="300.5" cy="235" transform="matrix(0.9743700647852352,0.224951054343865,-0.224951054343865,0.9743700647852352,60.56529330284505,-61.57475705486172)" stroke-opacity="0.8" stroke="#000000" stroke-width="2" fill-opacity="0.8" fill="#0a0a0a"></ellipse>
</svg>

但是当我在节点上做同样的事情时:

  const window   = require('svgdom');
  const SVG      = require('svg.js')(window);
  const document = window.document;


let size = { width: 512, height: 512 };
let entity = { x: 232,
  y: 162,
  rx: 137,
  ry: 146,
  a: 13,
  strokeColor: 0,
  strokeAlfa: 0.8,
  strokeWidth: 2,
  fillColor: 10,
  fillAlfa: 0.8 };
let draw = SVG(document.documentElement).size(size.width,size.height);
  let svg = draw
  .rect(size.width,size.height).fill("#fff");
draw
.ellipse(entity.rx,entity.ry)
.move(entity.x,entity.y)
.rotate(entity.a)
.stroke({
  color:'rgb('+entity.strokeColor+','+entity.strokeColor+','+entity.strokeColor+')',
  opacity:entity.strokeAlfa,
  width:entity.strokeWidth
})
.fill({
  color:'rgb('+entity.fillColor+','+entity.fillColor+','+entity.fillColor+')',
  opacity:entity.fillAlfa});
console.log(draw.svg());

我有这个 svg 字符串作为输出:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512">
<defs id="SvgjsDefs1001"></defs>
<svg id="SvgjsSvg1002" width="2" height="0" style="overflow: hidden; top: -100%; left: -100%; position: absolute; opacity: 0">
<polyline id="SvgjsPolyline1003" points="0,0"></polyline>
<path id="SvgjsPath1004" d="M0 0 "></path></svg>
<rect id="SvgjsRect1006" width="512" height="512" fill="#ffffff"></rect>
<ellipse id="SvgjsEllipse1007" rx="68.5" ry="73" cx="300.5" cy="235" transform="matrix(0.9743700647852352,0.224951054343865,-0.224951054343865,0.9743700647852352,60.56529330284505,-61.57475705486172)" stroke-opacity="0.8" stroke="#000000" stroke-width="2" fill-opacity="0.8" fill="#0a0a0a"></ellipse>
</svg>

如您所见 - 内部 svg 元素带有折线和路径。 看起来应该是不可见的,我会忽略它,但后来我把这个svg文件加载到Graphicsmagic(gm)中进行比较,gm不太喜欢这条折线:

错误:gm compare:不合格的绘图图元定义 (折线)。

是我的bug,svgjs还是svgdom?

--- 附加说明:

即使是没有任何操作的空 svg 也会有这条烦人的折线:

  const window   = require('svgdom');
  const SVG      = require('svg.js')(window);
  const document = window.document;

let draw = SVG(document.documentElement);
console.log(draw.svg());

SVG:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs">
<defs id="SvgjsDefs1001"></defs>
<svg id="SvgjsSvg1002" width="2" height="0" style="overflow: hidden; top: -100%; left: -100%; position: absolute; opacity: 0">
<polyline id="SvgjsPolyline1003" points="0,0"></polyline>
<path id="SvgjsPath1004" d="M0 0 "></path></svg></svg>

---更新2

正如我在 svg.js 的源代码中看到的,这 hidden poly was made intentially 可能是在 svgdom 的情况下没有调用一些清理代码? 作为一种解决方法,我可以手动执行吗?

【问题讨论】:

    标签: javascript node.js svg graphicsmagick svg.js


    【解决方案1】:

    如果有人遇到问题,这里有一个解决方法:

    在导出 SVG 字符串之前,您可以删除这个隐藏元素

    _.each(document.querySelectorAll('polyline[points="0,0"]'),function(pl){
        let todel = pl.parentNode;
        todel.parentNode.removeChild(todel);
      });
    

    在此处查看详细信息和更多选项: https://github.com/svgdotjs/svgdom/issues/13

    【讨论】:

    • 您可能想要采用 svg.js 的方式来执行此操作并执行以下操作:canvas.select(querySelector).remove()。看起来更漂亮:)
    【解决方案2】:

    这个问题的答案很简单,但有点难。

    svg.js 在 dom 中生成一个所谓的parser。它只是一个 svg 文档,用于计算路径或点数组的边界框或获取不可见元素的 bbox。 在 html 中,此解析器附加到正文中(因此它不在您的主 svg 中)。 但是,在标准 svgs(即 svgdom )中,解析器必须去某个地方。所以它被添加到主 svg 中。

    这就是你在那里看到的。它的解析器。反正它是不可见的,所以它不会出现。但是是的 - 它使源代码混乱。 不幸的是,这个问题没有解决方法,因为浏览器不想给你不可见元素的 bbox,所以我们需要它。

    希望我能帮上忙!

    【讨论】:

    • 我并不关心这个不可见的元素,直到我尝试用 graphicsmagic 渲染这样的 svg。此库输出错误。我知道根据规范生成的 svg 是正确的,但是 graphicsmagic 非常讨厌单点折线,这可能是个人问题,谁知道呢。
    • 那么删除它是唯一的选择。根据您的回答,我认为您已经解决了这个问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    相关资源
    最近更新 更多