svg入门

138 阅读2分钟

SVG是一种基于 XML 的图像文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形。

svg 绘图的流程

  1. 编写 svg 标签,指定宽高
  2. 编写 svg 绘图标签
  3. 编写绘图属性和样式
<svg width="800" height="800">
  <rect
    width="50"
    height="50"
    style="fill: red; stroke-width: 1px; stroke: yellow"
  />
  <line
    x1="100"
    y1="100"
    x2="250"
    y2="75"
    style="stroke: blue; stroke-width: 1"
  />
  <circle
    cx="200"
    cy="200"
    r="50"
    stroke="green"
    stroke-width="2"
    fill="red"
  />
</svg>

viewport和viewBox

  • viewport 是 svg 图像的可见区域,即宽高
  • viewBox 是用于在画布上绘制 svg 图形的坐标系统
<svg
  width="500"
  height="200"
  viewBox="0 0 50 20"
  style="border: 1px solid #000000"
>
  <rect
    x="20"
    y="10"
    width="10"
    height="5"
    style="stroke: #000000; fill: none"
  />
</svg>

svg可见区域的是width=500px height=200px。如果rect的x=600,超过了宽度500,怎么办呢?这就需要一个坐标系统viewBox来决定。那就是viewBox="0 0 50 20"。这个可以理解为宽50个单位,高20个单位,一个单位是500/50 = 10px,用来均分500px的宽度。

从上面的代码可以知道viewBox 坐标系中 1 = 10px,上述代码相当于:

<svg width="500" height="200" style="border: 1px solid #000000">
  <rect x="200" y="100" width="100" height="50" stroke-width="10" style="stroke: #000000; fill:none;"/>
</svg>

svg 组件

SVG 允许我们定义以后需要重复使用的图形元素。

defs标签

可以把所有需要再次使用的引用元素定义在defs元素里面。这样做可以增加SVG内容的易读性和可访问性。在defs元素中定义的图形元素不会直接呈现。 你可以在你的视口的任意地方利用 元素呈现这些元素。

g标签

元素g是用来组合对象容器,添加到g元素上的变换会应用到其所有的子元素上。

symbol

symbol与g标签类似,但symbol可以拥有一个独立的viewBox

// 继承父级的宽高
<svg width="0" height="0">
  <defs>
    <g id="arrow">
      <polyline
        points="30 20, 70 50, 30 80"
        fill="transparent"
        stroke="currentColor"
        stroke-width="3"
      ></polyline>
    </g>
    <symbol id="more" viewBox="0 0 100 100">
      <circle r="5" cx="20" cy="25" fill="currentColor" />
      <circle r="5" cx="20" cy="50" fill="currentColor" />
      <circle r="5" cx="20" cy="75" fill="currentColor" />
      <line
        x1="40"
        y1="25"
        x2="90"
        y2="25"
        stroke="currentColor"
        stroke-width="8"
      />
      <line
        x1="40"
        y1="50"
        x2="90"
        y2="50"
        stroke="currentColor"
        stroke-width="8"
      />
      <line
        x1="40"
        y1="75"
        x2="90"
        y2="75"
        stroke="currentColor"
        stroke-width="8"
      />
    </symbol>
    <symbol id="filledArrowRight" viewBox="0 0 100 100">
      <polyline fill="currentColor" points="20 10, 80 50, 20 90"></polyline>
    </symbol>
    <symbol id="arrowRight" viewBox="0 0 100 100">
      <polyline
        points="20 10, 80 50, 20 90"
        stroke-width="3"
        stroke="currentColor"
        fill="transparent"
      ></polyline>
    </symbol>
  </defs>
</svg>
.icon {
    width: 300px;
    height: 300px;
}
<svg class="icon">
  <use href="#arrow"></use>
</svg>
<svg class="icon">
  <use href="#more"></use>
</svg>
<svg class="icon">
  <use href="#filledArrowRight"></use>
</svg>
<svg class="icon">
  <use href="#arrowRight"></use>
</svg>

svg1.jpg

当我改变.icon的宽高的时候,使用symbol标签的会根据父级的宽高的变化而变大变小,这是因为symbol可以设置viewBox,但是使用g标签的不会,那么如何设置才能使g标签页能随父级宽高变化而变化呢?只需要在使用的时候加上viewBox="0 0 100 100"即可。

<svg class="icon" viewBox="0 0 100 100">
  <use href="#arrow"></use>
</svg>

svg2.jpg