svg入门指北

308 阅读5分钟

Svg葵花宝典

概念:可缩放矢量图形(英语:Scalable Vector Graphics,SVG)是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。

与canvas相比

内容 Canvas Svg
历史 较新,apple技术发展而来 历史悠久,2003年成为w3c标准
功能 功能简单,2D绘图api 功能丰富,各种图形、滤镜、动画等
特点 像素,只能脚本驱动,修改部分需全部重新绘制 矢量,xml、css、脚本均可,修改部分只需修改部分属性就行
支持 主流浏览器,ie9+ 主流浏览器,ie9+,其他svg阅读器
操作对象 基于像素(动态) 基于图形元素
元素 单个html元素 多个图形元素(rect,circle,line...)

应用场景

  1. 很多设计工具或者站点都支持导出svg格式;
  2. 制作高保真图片、logo
  3. 一些海报(html -> svg)的高保真打印

简单demo

  <svg width="200" height="200" id="mysvg">
      <circle r="50" cx="0" cy="0" fill="red" stroke="green" stroke-width="5"/>
  </svg>

解析:

  1. svg是行内元素(同canvas)
  2. svg默认宽高是300*150
  3. svg内每个标签都是可以通过dom进行操作来改变图形的呈现(canvas只能操作canvas标签)
  4. 一般含有图形意义的标签不允许嵌套(g,defs,animate)

常用(图形)标签

通用图形属性

  • stroke: 描边填充颜色
  • stroke-width: 描边宽度
  • x/y: 点在svg面板中的坐标

直线

<svg class="svg-pannel">
  <line
    x1="10"
    y1="10"
    x2="40"
    y2="40"
    stroke="red"
    stroke-width="2"
    stroke-linecap="round"
></line>
</svg>
  • x1/y1、x2/y2: 分别对应直线的两点点坐标
  • stroke-linecap: 直线两端的形状,枚举值有buttsquareround

妹学会?尝试一下

曲线(折线)

<svg class="svg-pannel" fill="green">
  <polyline
    class="polyline"
    points="10,10 30,10 30,30 10,30 10,50 30,50"
  ></polyline>
</svg>
  • points: 折线连接点坐标字符串,每个坐标点x/y逗号分割,各个坐标空格分

妹学会?尝试一下

路径

<svg version="1.1" class="box">
  <path d="M150 0 L75 100 L150 100 Z" />
</svg>

妹学会?尝试一下

(绘制)文本

<svg
  xmlns="http://www.w3.org/2000/svg"
  version="1.1"
  xmlns:xlink="http://www.w3.org/1999/xlink"
>
  <text x="10" y="100" style="fill:red;">
    I love SVG I love SVG
  </text>
</svg>
I love SVG I love SVG I love SVG I love SVG I love SVG I love SVG

妹学会?尝试一下

矩形

  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="box">
    <rect x="100" y="100" width="50" height="50" />
  </svg>

妹学会?尝试一下

圆形

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="box">
  <circle
    cx="100"
    cy="50"
    r="40"
    stroke="white"
    stroke-width="10"
    fill="red"
  />
</svg>
  • cx/cy: 圆的x/y坐标
  • y: 圆的半径

妹学会?尝试一下

画一个虚线段
<svg>
  <line
    x1="100"
    y1="300"
    x2="400"
    y2="300"
    stroke="black"
    stroke-width="10"
  />
  <line
    x1="100"
    y1="300"
    x2="400"
    y2="300"
    stroke-width="10"
    stroke="pink"
    stroke-dasharray="20,40"
  />
</svg>
  • stroke-dasharray: 值为数字字符串,各个数字用,分割,其中第奇数个数字表示实线(段/圆弧)的长度,第偶数个表示实线(段/圆弧)的间距,svg解析的时候会重复复制其值(repeat),直到超过(无法继续排了)整个直线(圆弧)为止,例如直线长100,stroke-dasharray值为20,40,实际复制之后的值是20,40,20,40(20+40+20+40 > 100)

试试?

画一圆弧

思路:画一个指定角度x的圆弧,我们只要求出其长度,然后设置stroke-dasharray第一个值为其长度,圆弧线段之间的距离超过2*Math.pi*r*(360-x)/360即可

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="box">
  <circle
    cx="150"
    cy="150"
    r="100"
    stroke="black"
    stroke-width="10"
    fill="red"
    stroke-dasharray="314,1000000"
  />
</svg>

妹学会?尝试一下 [画一个椭圆]](codesandbox.io/s/tuoyuan-4…)

defs与g标签

在我们开发中,对于一些经常使用的模块我们都会,将其单独封装定义以使后面可以直接拿来用,同理在svg中ddefs就是完成类似功能,defs定义的图形(模版)并不会渲染,而是通过use标签使用之后才会渲染,当然即使不用defs也可以使用use,但那样defs定义的模版图形会立即渲染(加上use标签共计渲染两次),而g标签对包裹图形进行组合成一个整体(图层),后面对g标签对所有操作都会对所有子元素生效,例如整体的渲染,填充色等

<svg class="box">
  <defs>
    <g id="my-svg-group" stroke="white">
      <circle id="rect1" r="50" cx="200" cy="200" />
      <circle
        id="rect2"
        stroke="white"
        r="10"
        cx="175"
        cy="180"
        fill="blue"
      />
      <circle
        id="rect3"
        stroke="white"
        r="10"
        cx="225"
        cy="180"
        fill="blue"
      />
      <circle id="rect4" r="30" cx="200" cy="200" fill="transparent" />
    </g>
  </defs>
  <use xlink:href="#my-svg-group" x="110" />
</svg>

由于g标签本身不支持x/y坐标但是可以配合内嵌svg标签来实现设置坐标的功能

<svg class="box">
  <g transform="translate(200,200)">
    <rect
      y="10"
      width="100"
      height="100"
      style="stroke: #777; stroke-width: 3; fill: #07B492;"
    />
    <text x="0" y="130" style="stroke: pink; fill: white">SVG</text>
  </g>
</svg>

妹学会?尝试一下

最后

本文的所有demo都可以在这里找到