Как изменить одну сторону в многоугольнике SVG? - PullRequest
2 голосов
/ 06 мая 2019

Я пытаюсь изменить цвет одной стороны многоугольника 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 Ответ

3 голосов
/ 07 мая 2019

Нет способа закрасить один край <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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...