第 14 天:如何使用 SVG 绘制弧线

如果您认为立方Béziers曲线是 SVG 中最复杂的部分,那么我要告诉您一个坏消息。弧线要复杂得多。不过好消息是,它们很少用到,在接下来的示例中我们也不会用到太多。

SVG 弧形的不同参数

最后两个参数仍然是弧线的端点。不过,弧线还有五个额外的参数。通过前两个参数,我们可以定义弧线的水平半径和垂直半径。

<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <path 
    d="
      M -40 -40
      A 70 70 0 0 0 40 40"
    fill="none"
    stroke="red"
    stroke-width="2"
  />
</svg>

你可能会意识到,即使起点和终点相同,半径相同,实际上也有四种不同的变化。第 5 个参数是一个布尔标志,告诉我们是否要将弧线反转。

<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <path 
    d="
      M -40 -40
      A 70 70 0 0 1 40 40"
    fill="none"
    stroke="red"
    stroke-width="2"
  />
</svg>

您可能会注意到,在这两种情况下,弧线都是以这些参数所能达到的最短路径结束的。也有可能走很长的路,但仍然保持相同的起点和终点,以及相同的半径。第 4 个参数是另一个布尔标志,用于设置是否要走长路。这也有两种变化。可以镜像,通过将第 5 个参数翻转为另一个值。

<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <path 
    d="
      M -40 -40
      A 70 70 0 1 1 40 40"
    fill="none"
    stroke="red"
    stroke-width="2"
  />
</svg>

更复杂的是,如果我们将水平半径和垂直半径设置为两个不同的值,那么我们就会得到一个椭圆的圆弧。同样的起点和终点,也有 4 种不同的变化。

<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <path 
    d="
      M -40 -40
      A 70 40 0 1 1 40 40"
    fill="none"
    stroke="red"
    stroke-width="2"
  />
</svg>

最后,如果我们绘制一个椭圆,还可以将其旋转一个角度。我们可以通过第 3 个参数进行设置。让事情变得更加曲折的是,我们的假想椭圆并没有围绕其中心旋转,因为这条弧线仍然必须保持相同的起点和终点。

<svg 
  width="200"
  height="200"
  viewBox="-100 -100 200 200"
>
  <path 
    d="
      M -40 -40
      A 70 40 30 1 1 40 40"
    fill="none"
    stroke="red"
    stroke-width="2"
  />
</svg>

点击这里观看弧线的互动演示

画一颗糖果

介绍了这么多,终于到了今天的示例。好消息是,在这个例子中,我们只需要画一条简单的弧线。

<svg 
  width="200"
  height="400"
  viewBox="-100 -200 200 400"
>
  <path
    class="body" 
    d="
      M 50 120
      L 50 -80
      A 50 50 0 0 0 -50 -80"
    stroke="#cd803d"
    stroke-width="45"
  />
</svg>
.body {
  stroke-linecap: round;
  fill: none;
}

绘制糖果时,我们先绘制一条由直线和半圆组成的粗线。然后再画一条同样的线,笔画宽度要稍微细一些。通过设置两种不同的颜色,它们看起来就像是一个是另一个的边框。

最后,我们在这个形状内添加几条直线作为标记。

<svg width="200" height="400" viewBox="-100 -200 200 400">
  <path
    class="body"
    d="
      M 50 120
      L 50 -80
      A 50 50 0 0 0 -50 -80"
    stroke="#cd803d"
    stroke-width="45"
  />

  <path
    class="body"
    d="
      M 50 120
      L 50 -80
      A 50 50 0 0 0 -50 -80"
    stroke="white"
    stroke-width="40"
    class="body"
  />

  <line class="green-mark" x1="-35" y1="-90" x2="-60" y2="-100" />
  <line class="red-mark" x1="-15" y1="-115" x2="-25" y2="-135" />
  <line class="green-mark" x1="20" y1="-110" x2="35" y2="-130" />
  <line class="red-mark" x1="40" y1="-60" x2="60" y2="-80" />
  <line class="green-mark" x1="40" y1="-10" x2="60" y2="-30" />
  <line class="red-mark" x1="40" y1="40" x2="60" y2="20" />
  <line class="green-mark" x1="40" y1="90" x2="60" y2="70" />
</svg>
.body {
  stroke-linecap: round;
  fill: none;
}

.red-mark {
  stroke: #d1495b;
  stroke-width: 2.5px;
}

.green-mark {
  stroke: #234236;
  stroke-width: 2.5px;
}
分享: