Как увеличить толщину линии без увеличения размера SVG элемента

Есть простейший svg

 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" color="red">
  <polygon fill="none" stroke-width="4" stroke="red" points="171.14 230.86,200 171.14,230.86 230.86"></polygon>
</svg>

https://jsfiddle.net/y6qdf90v/

Если в 5 раз увеличить толщину обводки, то будет так

 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" color="red">
  <polygon fill="none" stroke-width="20" stroke="red" points="171.14 230.86,200 171.14,230.86 230.86"></polygon>
</svg>

https://jsfiddle.net/y6qdf90v/1/

Можно ли как-то избежать расширения треугольника наружу? Чтобы при увеличении толщины, увеличивался размер только внутри. И как понять какая максимальная толщина линии доступна для треугольника?

По какой формуле можно пересчитать позицию полигона? Речь именно про svg 1.1. Я читал, что svg 1.2 поддерживает какой-то атрибут, но этот вариант не подходит.


Ответы (1 шт):

Автор решения: Alexandr_TT

Можно ли как-то избежать расширения треугольника наружу? Чтобы при увеличении толщины, увеличивался размер только внутри

Увеличение внешнего размера треугольника при увеличении толщины stroke-width линии происходит из-за симметричного увеличения толщины линии в обе стороны от осевой линии.

Нужно обрезать внешнюю часть линии от осевой, а внутреннюю часть отставить.

Решить эту задачу можно с помощью использования двух полигонов. Один полигон будет взят в качестве основы, второй полигон будет применён в качестве маски к первому полигону.

Представьте, что вы имеете треугольник, в котором выдавливаете треугольником меньшего размера треугольное отверстие. Так как у первого треугольника мы не увеличиваем толщину линии, то и увеличение общего размера треугольника не будет.

При уменьшении внутреннего треугольника толщина линии будет расти.

Маска при fill="black" прорезает треугольное отверстие. При stroke="white" становится видна линия.

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400"  >
    
   <defs>
   <mask id="msk"> 
    <rect width="100%" height="100%" fill="white" />
     <polygon  id="inner" fill="black" stroke-width="4" stroke="white" points="171.14 230.86,200 171.14,230.86 230.86">
       
     </polygon>
   </mask>  
   
  </defs>  
   <rect width="100%" height="100%" fill="wheat" />
 <!-- Первый треугольник полностью закрашен в красный цвет и к нему применена маска, которая вырезает треугольное отверстие, оставляя видимой только внутреннюю ширину линии  -->    
<polygon id="poly"  mask="url(#msk)" fill="red" stroke="none"  points="171.14 230.86,200 171.14,230.86 230.86"></polygon>
</svg> 

Пример анимации, показывающий, как при росте ширины линии stroke-width маски, растёт внутренняя толщина линии, без увеличения общего размера треугольника.

<polygon  id="inner" fill="black" stroke-width="2" stroke="white" points="171.14 230.86,200 171.14,230.86 230.86">
       <animate attributeName="stroke-width" begin="svg1.click" dur="5s" values="2;24" fill="freeze" />
</polygon>

Полный код анимации

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400"  >
    
   <defs>
   <mask id="msk"> 
    <rect width="100%" height="100%" fill="white" />
     <polygon  id="inner" fill="black" stroke-width="2" stroke="white" points="171.14 230.86,200 171.14,230.86 230.86">
       <animate attributeName="stroke-width" begin="svg1.click" dur="5s" values="2;24" fill="freeze" />
     </polygon>
   </mask>  
   
  </defs>  
   <rect width="100%" height="100%" fill="wheat" />
  <polygon id="poly"  mask="url(#msk)" fill="red" stroke="none"  points="171.14 230.86,200 171.14,230.86 230.86"></polygon>
</svg> 

Из примера видно, что толщину линии stroke-width можно увеличивать, пока она не закрасит весь треугольник.

Выберите значение stroke-width, чтобы обеспечить необходимую толщину линии.

→ Ссылка