svg入门

什么是SVG

SVG是一种XML语言,可以用来绘制矢量图形。SVG可以通过定义必要路径和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。

主流的浏览器均支持SVG。

优点:

  • 实现了DOM接口(比Canvas方便),方便添加事件
  • 可任意伸缩,SVG绘制的图形放大或缩小都不会失真

缺点:渲染慢。浏览器需要根据这些定义计算出在屏幕上渲染时应该呈现的样子。越复杂的SVG会在浏览器中占用很长的处理时间。

SVG提供了一些元素,用于定义圆形、矩形、椭圆、线等。
一个简单的SVG文档由 <svg> 元素和基本的形状元素构成。当然,SVG也可以变得很复杂,支持渐变、旋转、动画、滤镜效果、与JavaScript交互等等。

注意📢:SVG的元素和属性区分大小写,属性值必须用引号引起来。

坐标系统

SVG使用的坐标系统跟HTML文档一样:以页面的左上角为(0,0)坐标点,坐标以像素为单位,x轴正方向是向右,y轴正方向是向下。


image.png

基本形状

svg提供了6个基本形状,可以在 <svg> 中创建对应的元素来描述图形。
svg相当于一块布,图形的坐标都是相对于svg而言的。

矩形

矩形 rect 元素,必要的 4 个属性:

  • 左上角的坐标 (x,y)
  • 矩形的宽度 width 和高度 height

如下,在坐标 (0,0) 定义了一个宽高都是30 的矩形:

<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <rect x="0"  y="0"  width="30" height="30"/>
</svg>
image.png

除此之外,还有 rx 和 ry 两个属性用来控制矩形的角:

<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <rect x="0" y="0" rx="10" ry="10" width="30" height="30"/>
</svg>
image.png

圆形

circle 元素用来绘制圆形,只有3个必要属性:

  • r 半径
  • cx 和 cy (圆心坐标)
<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <circle cx="25" cy="75" r="20"/>
</svg>
image.png

椭圆

ellipse 元素可以创建椭圆,跟圆形的区别是,椭圆把半径拆成了 rx(x半径)和ry(y半径):

<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <ellipse cx="75" cy="75" rx="20" ry="15" />
</svg>
image.png

当 rx === ry 时,椭圆就变成了圆。

直线

line 用来描述直线,需要指定起点和终点。
分别是x1、 y1 和 x2 、y2。

<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <line x1="10" x2="50" y1="110" y2="150" stroke="red"/>
</svg>
image.png

折线

polyline用来描述折线。
所谓折线,是由许多连续的线段组成。
也就是说,它包含了很多的点,折线的所有点位置都放在points属性中,写法如下:

  • 每个数字用空格隔开,每个点用逗号分隔开。
  • 每个点必须包含2个数字,一个是x坐标,一个是y坐标。所以点列表 (0,0), (1,1) 和(2,2)可以写成这样:“0 0, 1 1, 2 2”。
<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <polyline points="60 110, 75 130, 80 180, 100 120" stroke="red" fill="transparent"/>
</svg>
image.png

多边形

polygon 用来描述多边形,它和折线很像,也是由连接一组点集的直线构成。不同的是,polygon的路径在最后一个点处会自动回到第一个点,也就是自动闭合。
下面代码只是 把 polyline 换成了 polygon:

<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <polygon points="60 110, 75 130, 80 180, 100 120" stroke="red" fill="transparent"/>
</svg>
image.png

路径

path 用来描述路径,它是所有 SVG 绘制工具中最强大的,也是最复杂的。

你可以用 path 元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线、多边形,以及一些其他的复杂形状(前提是你写得出来)。

d 属性表示绘制命令,它的值是一个长字符串。 每个字母表示一个绘制动作,后面跟着坐标:

  • M:移动到(move to)
  • L:画直线到(line to)
  • H:一条水平线,只接受x坐标
  • V:一条垂直线,只接受y坐标
  • Z:闭合路径
<svg width="200" height="500" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <path d=" M 18,3 L 46,3 V 40 H 61 L 32,68 L 3,40 H 18 Z"/>
</svg>
image.png

文本

text 元素用来添加文本。
属性 x 和属性 y 决定文本在视口中显示的位置。属性 text-anchor,可以有这些值:start、middle、end或inherit,允许决定从这一点开始的文本流的方向。

几个text-anchor值的对比如下:

<svg>
    <text x="0" y="10" >文本</text>
    <text x="0" y="50"  text-anchor="start">文本</text>
    <text x="0" y="90" text-anchor="middle">文本</text>
    <text x="0" y="140" text-anchor="end">文本</text>
</svg>
image.png

从上图可看出:

  • start是默认,表示从文本最左边开始显示。
  • middle表示从文本中间开始显示。
  • end表示从文本末尾开始显示 (没了)。

文本路径

如果要使得文本沿着某条路径排列,则需要使用textPath 元素。把文本放在 textPath 元素内部,然后使用 textPath 元素的 xlink:href 属性引用一个定义好的 path 元素。
在下面的例子,首先定义了一个路径 id 为 path,然后在 textPath 通过 xlink:href 指向该 id 作为文本的 path,最后通过 use 把 path 也画出来:

<svg width="500" height="500" >
    <defs>
        <path id="path"
          d="M10,50
             C10,50 50,0 100,50
             C100,50 150,100 190,50" />
    </defs>
   <g fill="blue" >
      <text x="20">
          <textPath xlink:href="#path">
               textPath
          </textPath>
      </text>
   </g>
   <use xlink:href="#path" fill="none" stroke="blue" />
</svg>
image.png

图片

SVG元素可以包含图像信息。

<svg width="100" height="100" viewBox="0 0 100 100"
     xmlns="http://www.w3.org/2000/svg">
    <image xlink:href="https://lf-cdn-tos.bytescm.com/obj/static/xitu_extension/static/brand.a9595735.svg" x="0" y="0" height="100" width="100" />
</svg>
image.png
  • xlink:href 图片地址。
  • x:图片左顶点x坐标。
  • y:图片左顶点y坐标。
  • width:图片宽度,必须。
  • height:图片高度,必须。

其他元素

g

g 元素用于将多个形状组成一个组,定义在g上的样式对所有子元素生效。

<svg width="300" height="100">
  <g id="circle" fill="red">
    <text x="25" y="20">圆形</text>
    <circle cx="50" cy="50" r="20"/>
  </g>
</svg>
image.png

use

use 用于复用已有的形状,通过设置 href 指定要复制节点的id。
x属性和y属性是use左顶点的坐标。

<svg width="300" height="100">
  <g id="circle">
    <text x="25" y="20">圆形</text>
    <circle cx="50" cy="50" r="20"/>
  </g>
  
  <use href="#circle" x="200" y="0"  />
  <use href="#circle" x="100" y="0" fill="red" />
</svg>
image.png

defs

defs 元素用于定义一个形状,也就是说内部代码不会在页面显示。定义的形状可供 use 元素引用,例如对上面的例子加上一层 defs:

<svg width="300" height="100">
  <defs>
    <g id="circle">
      <text x="25" y="20">圆形</text>
      <circle cx="50" cy="50" r="20"/>
    </g>
  </defs>
  
  <use href="#circle" x="200" y="0"  />
  <use href="#circle" x="100" y="0" fill="red" />
</svg>
image.png

animate

动画元素放在形状元素的内部,用来定义一个元素的某个属性如何踩着时点改变。在指定持续时间里,属性从开始值变成结束值。

  • attirbuteName:父元素的需要被改变的属性名。
  • from:单次动画的初始值。
  • to:单次动画的结束值。
  • dur:单次动画的持续时间,>0。
  • repeatCount:这个属性的值指定了重复的次数。值可以是:number | "indefinite"。
<svg width="500px" height="500px">
  <rect x="0" y="0" width="100" height="100" fill="#feac5e">
    <animate attributeName="width" from="0" to="100" dur="1s" repeatCount="indefinite" />
  </rect>
</svg>
drdde-hbozt.gif

样式属性

以下是常用的样式属性。

  • stroke:线条颜色
  • stroke-width:线条宽度
  • stroke-opacity:线条透明度
  • stroke-linecap:笔画头的形状 butt(默认), round, square
  • fill:填充色,设置形状内部的颜色
  • fill-opacity:填充透明度

渐变

渐变有两种,线性渐变和径向渐变。

线性渐变

svg使用 linearGradient 元素来定义线性渐变。
线性渐变需要预先定义,使用前需要先通过 defs 定义,然后在 linearGradient 元素上指定 id,使用时指定该 id:

<defs>
    <linearGradient id="linear"></linearGradient>
</defs>

接着,在<linearGradient>中创建<stop>元素,添加需要的颜色:

  • stop-color: 想要设定的渐变颜色
  • offset: 在你定义的方向向量上,定义该颜色的生效位置,使用百分比来设置具体的存在位置。
  • stop-opacity: 设定stop-color颜色的透明度
<defs>
    <linearGradient id="linear">
        <stop stop-color="#a0b3d6" offset="0%" />
        <stop stop-color="red" offset="100%" />
    </linearGradient>
</defs>

然后在样式里面通过 id 引入该渐变:

<rect x="0" y="0"  width="30" height="30" fill="url(#linear)"/>
image.png

径向渐变

<radialGradient>有点像是线性渐变和<circle>元素属性的混合。同样需要先创建一个<defs>声明,然后将<radialGradient>添加在其中,并为其赋予唯一的id值以方便后面的填充引用。

<svg width="500" height="400">
    <defs>
        <radialGradient r="50%" cx="50%" cy="50%" id="radial">
            <stop stop-color="#a0b3d6" offset="0%" />
            <stop stop-color="red" offset="100%" />
        </radialGradient>
    </defs>
    <rect x="0" y="0"  width="50" height="50" fill="url(#radial)"/>
    <circle cx="100"  cy="30" r="30" fill="url(#radial)"/>
</svg>
  • cx、cy属性设定圆心点(默认50%)
  • 渐变范围则通过属性r设定(默认50%)


    image.png

变形

平移

类似 CSS 的平移,translate() 用于SVG的平移操作。

<svg width="500" height="500">
    <rect x="0" y="0" width="10" height="10" transform="translate(100,100)" />
</svg>

在上面的例子里面,矩形的左顶点是(0,0),通过平移后,移到了(100,100)。


image.png

旋转

类似CSS的平移,rotate()用于SVG的旋转操作。
旋转默认是以svg的左顶点为中心旋转的。
在下面例子中,把 rect 绕着 svg 左顶点旋转45°:

<svg width="500" height="400">
         <rect x="30" y="30" width="120" height="90" fill="red"/>
         <rect x="30" y="30" width="120" height="90" fill="#a0b3d6" transform="rotate(45)"/>
</svg>

红色矩形是没有旋转的情况,蓝色矩形旋转45°:


image.png

多数情况下,我们想要的是绕着中心点旋转。rotate(c[, x, y]) 可以加上要旋转的中心坐标,例如上面的例子,x = 30 + 120/2 = 90,y = 30 + 90/2 = 75:

<svg width="500" height="400">
         <rect x="30" y="30" width="120" height="90" fill="red"/>
         <rect x="30" y="30" width="120" height="90" fill="#a0b3d6" transform="rotate(45, 90, 75)"/>
</svg>
image.png

缩放

scale() 变形改变了元素的尺寸。

<svg width="500" height="500">
    <rect x="20" y="20" width="20" height="20" transform="scale(1,2)" />
</svg>

通过scale(1,2),把一个正方形变成长方形


image.png

斜切

skewX()和skewY(),每个需要一角度以确定元素斜切到多远。

<svg width="500" height="500">
    <rect x="20" y="20" width="20" height="20" transform="skewX(45)" />
</svg>
image.png

总结

本篇文件从svg的语法以及基本的使用介绍了svg的元素。当然了,在实际开发中,运用svg一般是从UI给出的设计稿中直接导出svg使用的。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、栅格图形和矢量图形栅格图形:也称位图,图像由一组二维像素网格表示。Canvas 2d API 就是一款栅格图形...
    linda102阅读 4,832评论 0 4
  • 本文简介 点赞 + 关注 + 收藏 = 学会了 作为一只前端,只懂 Vue、React 感觉已经和大家拉不开距离了...
    德育处主任阅读 5,262评论 0 19
  • 概念 SVG全称是可缩放矢量图(Scalable Vector Graphics),是一种基于XML语法,用于描述...
    belllee阅读 4,770评论 0 0
  • <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLI...
    穆熙沐阅读 3,153评论 0 1
  • 1.svg文件引入 可通过 , 引入使用 理论上同样可以使用 img 元素,但是在低于4.0版本的Firefox...
    Jmingzi_阅读 2,600评论 0 0