Согласованный размер тени на пути svg с невекторным масштабированием

#html #css #svg

Вопрос:

Я пытаюсь создать эффект на пути svg vector="non-scaling-stroke" с использованием тени filter: drop-shadow(...) . Однако, когда путь масштабируется в соответствии с размером экрана (такое масштабирование необходимо), путь остается неизменного размера, но тень растягивается:

 svg {
  width: 1000px; /*just to simulate problem, these would be vw amp; vh units in practice*/
  height: 200px;
}

path {
  filter: drop-shadow(0px 0px 1px blue);
} 
 <svg preserveAspectRatio="none" viewBox="0 0 100 100">
  <path fill="none" stroke="black" stroke-width="5" vector-effect="non-scaling-stroke" d="M0,30 h50 v70"></path>
</svg> 

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

А также с помощью css-фильтра, который я пробовал:

  • использование svg-фильтров отбрасывает тень на путь.
  • размещение фиктивного пути за линией с размытием по Гауссу для имитации тени.

И то, и другое дает один и тот же результат.

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

Спасибо!

Комментарии:

1. Я думаю, проблема в том, что у вас есть один путь, поэтому нет способа заставить тень применяться по-другому на стороне вашего пути. Что вам, скорее всего, потребуется сделать, так это преобразовать SVG в четыре (или два пути, если вы скрываете часть) пути и применить тень сверху/снизу и по бокам по-разному

2. Спасибо, это хорошая идея, но я боюсь, что она не сработает для моей реализации, так как я анимирую линию со смещением штриха, поэтому разделение пути вызовет проблемы с этим.

Ответ №1:

Я думаю, что это могло бы сработать!

 svg {
  width: 1000px;
  /*just to simulate problem, these would be vw amp; vh units in practice*/
  height: 200px;
} 
 <svg preserveAspectRatio="none" viewBox="0 0 100 100">
  <path fill="none" stroke="black" stroke-width="5" vector-effect="non-scaling-stroke" d="M0,30 h50 v70"></path>
   <rect x="0" y="29" width="50" height="2" style="fill:blue;filter: blur(2px);"  />
   <rect x="49.8" y="29" width=".5" height="70" style="fill:blue;filter: blur(.5px);"  />
</svg> 

Комментарии:

1. Спасибо, это хорошо работает! похоже, я не выберусь из этого, не используя js для масштабирования некоторых значений, но масштабирование прямых проще, чем масштабирование пути в моей реализации, так что все в порядке.