SVG.js在具有svgdom的节点处生成的意外折线

时间:2017-09-24 05:28:11

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

我有svg.js在浏览器中生成的不同的svg字符串(正确的)和节点(不正确且具有exsessive内部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.com/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.com/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:不符合图形的原始定义   (折线)。

这是我的错误,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.com/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的情况下没有调用一些清理代码? 我可以手动执行此操作吗?

2 个答案:

答案 0 :(得分:0)

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

在导出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

答案 1 :(得分:0)

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

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

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

希望我能帮忙!