如何修改SVG多边形的一侧?

时间:2019-05-06 20:15:27

标签: html css svg

我正在尝试更改SVG多边形一侧的颜色。

我已经尝试过SVG线,但是它断开了它们的连接。

这里是一个方便的代码笔:https://codepen.io/anon/pen/gJbowP

.poly-line {
  stroke: #878787;
  stroke-width: 15;
  transition: all 0.8s ease-in-out;
}

#poly-line-c {
  stroke: red;
}

.triangle {
  fill: transparent;
  stroke: #878787;
  stroke-width: 15;
}
<svg height="500" width="500">
<line x1="150" y1="200" x2="30" y2="400" class="poly-line" id="poly-line-a"/>
<line x1="30" y1="400" x2="450" y2="400" class="poly-line" id="poly-line-b"/>
<line x1="150" y1="200" x2="450" y2="400" class="poly-line" id="poly-line-c"/>
</svg>

<svg height="500" width="500">
  <polygon points="150,200 30,400 450,400" class="triangle" />
</svg>

我的问题很简单。如何制作每边均可修改的SVG多边形?

如果需要更多信息,请发表评论。

1 个答案:

答案 0 :(得分:3)

无法将<polygon>的一个边缘着色为另一种颜色。

您可以在多边形的顶部绘制不同颜色的线。

.poly-line {
  stroke: #878787;
  stroke-width: 15;
  transition: all 0.8s ease-in-out;
}

#poly-line-c {
  stroke: red;
}

.triangle {
  fill: transparent;
  stroke: #878787;
  stroke-width: 15;
}
<svg height="500" width="500">
  <polygon points="150,200 30,400 450,400" class="triangle" />
  <line x1="150" y1="200" x2="450" y2="400" class="poly-line" id="poly-line-c"/>
</svg>

或者,如果您想要不那么突兀的外观,则可以使用遮罩或夹子将侧面的倾斜末端包括在内。但是,这需要为每个要用不同颜色着色的多边形的每一面提供唯一的蒙版/剪辑。

在此示例中,我使用javascript计算了所需的剪辑路径多边形。

// Calculates the "incentre" of the triangle.
// The incentre is the point where the three lines that bisect the three angles meet.
function calculateIncentre(ax,ay, bx,by, cx,cy)
{
  var aLen = Math.sqrt((bx-cx)*(bx-cx) + (by-cy)*(by-cy)); // length of line opposite point A
  var bLen = Math.sqrt((ax-cx)*(ax-cx) + (ay-cy)*(ay-cy)); // length of line opposite point B
  var cLen = Math.sqrt((bx-ax)*(bx-ax) + (by-ay)*(by-ay)); // length of line opposite point C
  var p = aLen + bLen + cLen;   // perimeter length of triangle
  return { x: (ax * aLen + bx * bLen + cx * cLen) / p,
           y: (ay * aLen + by * bLen + cy * cLen) / p }
}

//
// Generates a polygon that clips one side of a polygon.
// Make sure the side you care about is first (ie. ax,ay to bx,by)
//
function generateSideClipPolygon(ax,ay, bx,by, cx,cy)
{
  var incentre = calculateIncentre(ax,ay, bx,by, cx,cy);

  // If there is no stroke, you could use the following as the clip.
  //return [ax, ay, incentre.x,incentre.y, bx,by].join(',');
  
  // But since there is a stroke, we need to extend out clip polygon outwards a bit,
  // so that it includes/covers the outside half of the stroke.
  var extraFactor = 1.5;   // (you might need to increase this for larger stroke widths or sharper angles)
  // extend point A
  var dx = ax - incentre.x;
  var dy = ay - incentre.y;
  ax2 = incentre.x + dx * extraFactor;
  ay2 = incentre.y + dy * extraFactor;
  // extend point B
  var dx = bx - incentre.x;
  var dy = by - incentre.y;
  bx2 = incentre.x + dx * extraFactor;
  by2 = incentre.y + dy * extraFactor;
  return [ax2, ay2, incentre.x,incentre.y, bx2,by2].join(',');
}


document.getElementById("side-c").setAttribute("points", generateSideClipPolygon(450,400, 150,200, 30,400));
.poly-line {
  stroke: #878787;
  stroke-width: 15;
  transition: all 0.8s ease-in-out;
}

#poly-line-c {
  stroke: red;
}

.triangle {
  fill: transparent;
  stroke: #878787;
  stroke-width: 15;
}
<svg height="500" width="500">
  <defs>
    <clipPath id="side-c-clip">
      <polygon id="side-c" points=""/>
    </clipPath>
  </defs>
  <polygon points="150,200 30,400 450,400" class="triangle" />
  <polygon points="150,200 30,400 450,400" class="triangle" id="poly-line-c" clip-path="url(#side-c-clip)"/>
</svg>