重叠SVG元素区域填充的最佳方法是什么?

时间:2016-08-03 19:05:36

标签: javascript svg

我正在研究SVG的一些基本图像处理,并尝试为以下挑战找到最佳方法:

我们有一个SVG文件,它有各种SVG元素(圆形,矩形,三角形)。它们彼此重叠,形成了不同形式的新“区域”(见图)。

所以填充实际元素 - 没有问题。但是,如果我只想用特定的交叉区域填充颜色呢?

我目前的想法是:

  • 考虑将所有元素绘制为路径,然后看看我是否可以将整体构图视为一条大路径,然后使用填充规则。
  • 考虑计算区域形状并在其上绘制新形状,然后填充它。
  • 考虑别的什么?

    example of areas

2 个答案:

答案 0 :(得分:5)

迈克尔的过滤方法很酷而且很棘手,但也许有点难以理解。

您也可以使用面具。



<svg width="391" height="400">
  <defs>
    <!-- define the shapes in the image, which we will use for the outlines
         and for creating intersection masks -->
    <rect id="square" x="92" y="48" width="218" height="218"/>
    <polygon id="triangle" points="54,366 277,366 165,142"/>
    <circle id="circle" cx="256" cy="264" r="85"/>
    
    <!-- the masks -->
    <!-- white parts are visible, black parts are invisible -->
    <mask id="square-minus-triangle">
      <!-- square with triangle cut out of it -->
      <use xlink:href="#square" fill="white"/>
      <use xlink:href="#triangle" fill="black"/>
    </mask>
    <mask id="triangle-minus-square">
      <!-- triangle with square cut out of it -->
      <use xlink:href="#triangle" fill="white"/>
      <use xlink:href="#square" fill="black"/>
    </mask>
  </defs>
  
  <!-- background -->
  <rect width="100%" height="100%" fill="#e5e4da"/>
  
  <!-- the intersection shapes (yellow) -->
  <!-- first draw the circle, but use the square-minus-triangle mask.-->
  <use xlink:href="#circle" fill="#e4e400" mask="url(#square-minus-triangle)"/>
  <!-- draw the circle again, but use the triangle-minus-square mask.-->
  <use xlink:href="#circle" fill="#e4e400" mask="url(#triangle-minus-square)"/>
  
  <!-- draw the outlined shapes -->
  <g fill="none" stroke="black" stroke-width="6">
    <use xlink:href="#square"/>
    <use xlink:href="#triangle"/>
    <use xlink:href="#circle"/>
  </g>
</svg>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

您可以使用过滤器执行此操作。一种简单的方法是使用近透明填充,然后使用过滤器将非重叠区域拨到完全透明,重叠区域完全不透明。它使中风有点脆。

<svg height="600px" width="800px">
     <defs>
       <filter id="opacitychange">
         <feComponentTransfer>
           <feFuncA type="linear" intercept="-.05"/>
           </feComponentTransfer>
         <feComponentTransfer>
           <feFuncA type="gamma" amplitude="4" exponent=".4"/>
           </feComponentTransfer>
         </filter>
       </defs>
  
  <g filter="url(#opacitychange)">
     <circle stroke="black"  fill="blue" fill-opacity="0.05" cx="150" cy="150" r="100"/>
     <rect stroke="black" x="200" y="100" width="100" height="300" fill="blue" fill-opacity="0.05"/>
     <polygon stroke="black"  points="50,50 50,400 300,400" fill="blue" fill-opacity="0.05"/>
 </g>    
     </svg>