可以通过子<path>定义“超级”SVG路径吗?

时间:2017-10-23 20:17:01

标签: svg path grouping fill

我想到SVG会以某种方式允许定义一个形状,这要归功于定义其边界的几条路径 - 隐式或显式关闭或打开。

我试过这个:     

<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   width="200"
   height="200"
   viewBox="0 0 120 120"
   version="1.1">
  <defs>
    <path d="M 20,20 40,20 40,60 100,60 100,100" style="stroke:red;stroke-width:3px;" id="Border1" />
    <path d="M 100,100 L 20,100 20,20" style="stroke:blue;stroke-width:2px;" id="Border2" />
  </defs>
  <g style="fill: green">
    <use xlink:href = "#Border1"/>
    <use xlink:href = "#Border2"/>
  </g>
</svg>

在组中填充一些颜色清楚地表明每条路径都是单独考虑的,而不是整体考虑。

有没有人知道是否有办法实现这一目标?

  1. 能够单独操纵每个边界
  2. 按边界定义一些形状

1 个答案:

答案 0 :(得分:0)

没有。没有。

此类内容已在SVG工作组中提出并进行了讨论。但到目前为止,这已经达到了目的。

您可以编写一些Javascript来从一组边界路径构建区域。

var regions = document.querySelectorAll("path.region");
regions.forEach(function(region) {
  // Get the value of the "data-paths" attribute
  var borderIds = region.dataset.borders.split(',');
  var regionPath = "";
  // Find all the border paths for this region, and add them to the region's path data
  borderIds.forEach(function(id) {
    var borderDef = document.getElementById(id);
    var d = borderDef.getAttribute("d");
    if (regionPath === "") {
       // First border in region
       regionPath = d;
    } else {
       // Subsequent borders need their first 'M' changed to an 'L' to keep the path contiguous
       regionPath += 'L' + d.substr(1);
    }
  })
  region.setAttribute("d", regionPath);
});
<svg
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   width="200"
   height="200"
   viewBox="0 0 120 120"
   version="1.1">
  <defs>
    <path d="M 20,20 40,20 40,60 100,60 100,100" style="stroke:red;stroke-width:3px;" id="Border1" />
    <path d="M 100,100 L 20,100 20,20" style="stroke:blue;stroke-width:2px;" id="Border2" />
  </defs>
  <path style="fill: green" class="region" data-borders="Border1,Border2"/>
</svg>

并非该代码仅在边框列表中的下一个边框路径从最后一个边框路径完成时开始工作。

此外,此代码假定浏览器支持SVG元素的dataset属性。如果您需要支持旧版浏览器,则可能需要使用getAttribute("data-borders")