【问题标题】:How do you modify one side in an SVG polygon?如何修改 SVG 多边形的一侧?
【发布时间】:2019-05-06 20:15:26
【问题描述】:

我正在尝试更改 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 多边形?

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

【问题讨论】:

  • 在另一个之上绘制多个多边形,并使用 stroke-dasharray 确保只绘制每个部分的一部分,或使用线条/路径分别绘制多边形的线条。
  • 您可以尝试调整this answer 以在一侧应用渐变?还可以查看这些forum fiddles .. 有趣!
  • 解决问题的最简单方法是将.poly-line {stroke-linecap: round;} 添加到您的第一个示例中

标签: html css svg


【解决方案1】:

无法将&lt;polygon&gt; 的一个边缘涂上不同的颜色。

你可以在多边形的顶部画一条不同颜色的线。

.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>

【讨论】:

    猜你喜欢
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    相关资源
    最近更新 更多