将 svg 行和路径合并为一个路径元素 [英] Merging svg line and path into one path element

查看:23
本文介绍了将 svg 行和路径合并为一个路径元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 line 元素和一个 path 元素.我想将它们合并为一个 path 元素,但我没有 svg 绘图经验.

如何将这两个 svg 元素合并为一个 viewport/viewBox,其中 vert-line-2 的顶点"与 y2vert-line-1 的代码>.

.svg-wrapper{宽度:55px;高度:55px;字体大小:0;}.play-vert-line{宽度:100%;}.line-join{位置:相对;左:25px;填充:无;}

<svg class="play-vert-line" height="17"><定义><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"><定义><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"></路径></svg>

解决方案

让我们逐步引导您完成此操作.

解决线性梯度

定义笔画的线性渐变都有 子元素,没有 offset 属性.因此,它们都处于默认值 0.净效果是,由于笔划的所有部分都在渐变矢量原点的正侧,因此笔划具有 #3c3c3c 的统一颜色.fill:none 已移至属性.

<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"><;/线></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>

移动一个父元素中的两个 元素

div.svg-wrapper 交换一个相同大小(55*55)的 svg 元素,两个 svg 放在里面,按照样式表的定义定位和大小.此时的所有百分比值都将交换为绝对值.

应该注意的是,形式上,内部 svgs 必须定义一个 overflow="hidden" 属性(隐式定义剪辑路径).可以安全地将其关闭,因为图形元素不会溢出其视口.

<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"></线></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>

计算子s

的等效变换

此时,内部 svgs 有自己的视口和自己的坐标系.可以按照此算法计算到父视口的转换.然后,可以将 元素替换为 元素.

如果有溢出,则需要 clip-path 属性.

<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"></线><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></svg>

应用变换并将行转换为路径

实际上,只有 元素应用了变换.可以删除组元素,并且在 d 属性中,必须重新计算每个坐标:x' = x + dx,y' = y + dy.

要将 转换为,必须使用d 属性编写行:

d="M   L  "

(L 命令可以省略,正如它暗示的那样.)

<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>

I have one line element and one path element. I would like to merge them into one path element, but I have no experience with svg drawing.

How can I marge these two svg elements into one viewport/viewBox where "top point" of vert-line-2 is joined with y2 of 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>

解决方案

Let's walk you through this step by step.

Resolve linear gradients

The linear gradients defining the strokes both have <stop> child elements that lack offset attributes. Thus, they are all at the default value 0. The net effet is that, since all parts of the stroke are on the positive side of the gradient vector origin, the strokes have a uniform color of #3c3c3c. fill:none has been moved to an attribute.

<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>

Move the two <svg> elements in one parent <svg>

div.svg-wrapper is exchanged for a svg element of the same size (55*55), and the two svgs are placed inside, positioned and sized as defined by the stylesheet. All Percentage values at this point are exchanged for absolute values.

It should be noted that formally, the inner svgs must define a overflow="hidden" attribute (implicitely defining a clip-path). It can be safely left off, since the grafical elements do not overflow their viewport.

<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>

Compute the equivalent transform of the child <svg>s

At this point, the inner svgs have their own viewports and own coordinate system. The transformation to the parent viewport can be computed following this algorithm. Then, the <svg> elements can be exchanged for <g> elements.

If there had been overflow, a clip-path attribute would have been necessary.

<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>

Apply the transform and convert line to path

Effectively, only the <path> element has transform applied. The group elements can be removed, and in the d attribute, every coordinate has to be recomputed: x' = x + dx, y' = y + dy.

To transform <line> to <path>, the d attribute must be written using the start and end coordinates of the line:

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

(The L command can be left off, as it is implied.)

<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>

Merging and joing the two path elements

Since the two path elements are now expressed in the same coordinate systems and have the same presentation attributes (don't forget fill="none"), the d attributes can now simply be concatenated:

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

Joining them has one further complication. The first subpath starts at the upper end, but the second starts on the lower. To join them in a top-to-bottom direction, the direction of the second subpath has to be reversed. In the special case of a C command, all coordinates can simply be reversed in order. For other commands (especially relative path commands), this could be more complicated.

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

You did't say how to join the two subpaths. Let's assume a straight line.

<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>

这篇关于将 svg 行和路径合并为一个路径元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆