Линия SVG с градиентным штрихом не будет отображаться прямо
Я пытаюсь реплицировать <hr>
с помощью SVG. Теперь, когда прямая линия с SVG работает отлично, но вторая я поглажу ее градиентом, он больше не будет отображаться по прямой.
Следующий код работает, но обратите внимание: y1 и y2 должны быть разделены на 1 единицу. Если, например, я устанавливаю y1 и y2 - 210, линия исчезнет.
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgba(0,0,0,0);stop-opacity:0" />
<stop offset="50%" style="stop-color:rgba(0,0,0,0.75);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgba(0,0,0,0);stop-opacity:0" />
</linearGradient>
</defs>
<line x1="40" y1="210" x2="460" y2="211" stroke="url(#grad1)" stroke-width="1" />
Вероятно, я просто пропустил какую-то очевидную функцию линейных градиентов, и линия выглядит хорошо, но я бы предпочел просто прямолинейно. Спасибо.
Ответы
Ответ 1
Вы попадаете в последний абзац в этой части спецификации SVG
Объект ключевого словаBoundingBox не следует использовать, если геометрия применимого элемента не имеет ширины или высоты, например, в случае горизонтальной или вертикальной линии, даже если линия имеет фактическую толщину при просмотре из-за отсутствия ненулевой так как ширина штриха игнорируется для вычислений с ограничивающей коробкой. Если геометрия применимого элемента не имеет ширины или высоты, а объектBoundingBox указан, то данный эффект (например, градиент или фильтр) будет проигнорирован.
objectBoundingBox по умолчанию используется для gradientUnits, поэтому вам нужно использовать gradientUnits = "userSpaceOnUse", а затем настроить значения, подходящие для разных систем координат.
Ответ 2
Роберт Лонгсон дает отличное объяснение. Но иногда userSpaceOnUse
является болью, потому что она распространяет интерполяцию по всему холсту, а не только на строку.
Вместо этого вы можете добавить небольшое количество значений, чтобы гарантировать, что размер bbox не равен нулю.
Например,
<line x1="40" y1="210" x2="460" y2="210.001" stroke="url(#grad1)" stroke-width="1" />
будет рисовать прямую линию с градиентом.
Ответ 3
Предполагая, что вам не нужна какая-либо точность, вы можете изменить линию на заполненный путь, как показано ниже
<path d='M 40 209.5 L 460 209.5 L 460 210.5 L 40 210.5' fill='url(#grad1)' />
или, альтернативно, заполненному прямоугольнику, как показано ниже
<rect x=40 y=209.5 width=420 height=1 fill='url(#grad1)' />
Также интересно отметить, что эта проблема затрагивает только вертикальные и горизонтальные линии. Наклонная линия отображается правильно.