Объединение SVG линии и пути в один элемент пути

У меня есть такой line элемент и один path элемент. Я хотел бы объединить их в один path элемент, но я не имею опыта рисования SVG.

Как я могу объединить эти два элемента SVG в один viewport/viewBox где "верхняя точка" vert-line-2 соединяется с y2 из vert-line-1,

.svg-wrapper{
  width: 55px;
  height: 55px;
  font-size: 0;
}

.play-vert-line{
  width: 100%;
}

.line-join{
  position: relative;
  left: 25px;
  fill: none;
}
<div class="svg-wrapper">
   <svg class="play-vert-line" height="17">
      <defs>
         <linearGradient id="vert-gradient" gradientUnits="userSpaceOnUse" y1="0%" y2="100%" x1="0" x2="0">
            <stop stop-color="#3A9AFC"></stop>
            <stop stop-color="#3c3c3c"></stop>
         </linearGradient>
      </defs>
      <line id="vert-line-1" x1="50%" y1="0" x2="50%" y2="17" stroke="url(#vert-gradient)" stroke-width="2"></line>
   </svg>
   <svg class="line-join" height="15" width="15" viewBox="-1.3 0 15 15">
      <defs>
         <linearGradient id="vert-join-gradient" gradientUnits="userSpaceOnUse" y2="100%" x1="0" x2="0">
            <stop stop-color="#3A9AFC"></stop>
            <stop stop-color="#3c3c3c"></stop>
         </linearGradient>
      </defs>
      <path id="vert-line-2" d="M 11, 10 C 5, 10, 1, 6, 1, 0" stroke="url(#vert-join-gradient)" stroke-width="2"></path>
   </svg>
</div>

1 ответ

Решение

Давайте проведем вас через этот шаг за шагом.

Разрешить линейные градиенты

Линейные градиенты, определяющие штрихи, имеют <stop> недостающие дочерние элементы offset атрибутов. Таким образом, все они имеют значение по умолчанию 0. Чистый результат заключается в том, что, поскольку все части обводки находятся на положительной стороне начала вектора градиента, обводки имеют однородный цвет #3c3c3c, fill:none был перемещен в атрибут.

<div class="svg-wrapper">
   <svg class="play-vert-line" height="17">
      <line id="vert-line-1" x1="50%" y1="0" x2="50%" y2="17" stroke="#3c3c3c" stroke-width="2"></line>
   </svg>
   <svg class="line-join" height="15" width="15" viewBox="-1.3 0 15 15">
      <path id="vert-line-2" d="M 11, 10 C 5, 10, 1, 6, 1, 0"
            stroke="#3c3c3c" stroke-width="2" fill="none"></path>
   </svg>
</svg>

Переместить два <svg> элементы в одном из родителей <svg>

div.svg-wrapper заменяется на элемент svg того же размера (55*55), а два svgs помещаются внутрь, располагаются и измеряются в соответствии с таблицей стилей. Все процентные значения в этой точке обмениваются на абсолютные значения.

Следует отметить, что формально внутренние svgs должны определять overflow="hidden" атрибут (неявно определяющий путь клипа). Его можно безопасно отключить, поскольку графические элементы не выходят за пределы области просмотра.

<svg class="svg-wrapper" width="55" height="55" viewBox="0 0 55 55">
   <svg class="play-vert-line" height="17" width="55">
      <line id="vert-line-1" x1="27.5" y1="0" x2="27.5" y2="17" stroke="#3c3c3c" stroke-width="2"></line>
   </svg>
   <svg class="line-join" x="25" y="17" height="15" width="15" viewBox="-1.3 0 15 15">
      <path id="vert-line-2" d="M 11, 10 C 5, 10, 1, 6, 1, 0"
            stroke="#3c3c3c" stroke-width="2" fill="none"></path>
   </svg>
</svg>

Вычислить эквивалентное преобразование ребенка <svg> s

На этом этапе внутренние svgs имеют свои собственные окна просмотра и собственную систему координат. Преобразование в родительский видовой экран может быть вычислено в соответствии с этим алгоритмом. Затем <svg> элементы можно обменять на <g> элементы.

Если бы был переполнение, clip-path атрибут был бы необходим.

<svg class="svg-wrapper" width="55" height="55" viewBox="0 0 55 55">
   <g class="play-vert-line">
      <line id="vert-line-1" x1="27.5" y1="0" x2="27.5" y2="17" stroke="#3c3c3c" stroke-width="2"></line>
   </g>
   <g class="line-join" transform="translate(26.3, 17)">
      <path id="vert-line-2" d="M 11, 10 C 5, 10, 1, 6, 1, 0"
            stroke="#3c3c3c" stroke-width="2" fill="none"></path>
   </g>
</svg>

Применить преобразование и преобразовать линию в путь

По сути, только <path> к элементу применено преобразование. Элементы группы могут быть удалены, а в d атрибут, каждая координата должна быть пересчитана: x' = x + dx, y' = y + dy.

Преобразовывать <line> в <path>, d Атрибут должен быть записан с использованием начальной и конечной координат строки:

d="M <x1> <y1> L <x2> <y2>"

(Команда L может быть пропущена, как это подразумевается.)

<svg class="svg-wrapper" width="55" height="55" viewBox="0 0 55 55">
    <path id="vert-line-1" d="M 27.5 0 27.5 17" stroke="#3c3c3c" stroke-width="2"></path>
    <path id="vert-line-2" d="M 36.3, 27 C 31.3, 27, 27.3, 23, 27.3, 17"
          stroke="#3c3c3c" stroke-width="2" fill="none"></path>
</svg>

Слияние и соединение двух элементов пути

Поскольку два элемента пути теперь выражены в одних и тех же системах координат и имеют одинаковые атрибуты представления (не забудьте fill="none"), d атрибуты теперь могут быть просто объединены:

d="M 27.5 0 27.5 17 M 36.3, 27 C 31.3, 27, 27.3, 23, 27.3, 17"

Присоединение к ним имеет еще одно осложнение. Первый подпуть начинается с верхнего конца, а второй начинается с нижнего. Чтобы соединить их в направлении сверху вниз, направление второго подпути должно быть обратным. В особом случае команды C все координаты можно просто поменять местами по порядку. Для других команд (особенно команд относительного пути) это может быть более сложным.

d="M 27.5 0 27.5 17 M 27.3, 17 C 27.3, 23, 31.3, 27, 36.3, 27"

Вы не сказали, как соединить два подпути. Давайте предположим, что прямая линия.

<svg class="svg-wrapper" width="55" height="55" viewBox="0 0 55 55">
    <path id="vert-line" d="M 27.5 0 27.5 17 L 27.3, 17 C 27.3, 23, 31.3, 27, 36.3, 27"
          stroke="#3c3c3c" stroke-width="2" fill="none"></path>
</svg>

Другие вопросы по тегам