什么是SVG
SVG是一种XML语言,可以用来绘制矢量图形。SVG可以通过定义必要路径和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。
主流的浏览器均支持SVG。
优点:
- 实现了DOM接口(比Canvas方便),方便添加事件
- 可任意伸缩,SVG绘制的图形放大或缩小都不会失真
缺点:渲染慢。浏览器需要根据这些定义计算出在屏幕上渲染时应该呈现的样子。越复杂的SVG会在浏览器中占用很长的处理时间。
SVG提供了一些元素,用于定义圆形、矩形、椭圆、线等。
一个简单的SVG文档由 <svg>
元素和基本的形状元素构成。当然,SVG也可以变得很复杂,支持渐变、旋转、动画、滤镜效果、与JavaScript交互等等。
注意📢:SVG的元素和属性区分大小写,属性值必须用引号引起来。
坐标系统
SVG使用的坐标系统跟HTML文档一样:以页面的左上角为(0,0)坐标点,坐标以像素为单位,x轴正方向是向右,y轴正方向是向下。
基本形状
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>
除此之外,还有 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>
圆形
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>
椭圆
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>
当 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>
折线
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>
多边形
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>
路径
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>
文本
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>
从上图可看出:
- 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>
图片
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>
- 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>
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>
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>
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>
样式属性
以下是常用的样式属性。
- 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)"/>
径向渐变
<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%)
变形
平移
类似 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)。
旋转
类似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°:
多数情况下,我们想要的是绕着中心点旋转。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>
缩放
scale() 变形改变了元素的尺寸。
<svg width="500" height="500">
<rect x="20" y="20" width="20" height="20" transform="scale(1,2)" />
</svg>
通过scale(1,2),把一个正方形变成长方形
斜切
skewX()和skewY(),每个需要一角度以确定元素斜切到多远。
<svg width="500" height="500">
<rect x="20" y="20" width="20" height="20" transform="skewX(45)" />
</svg>
总结
本篇文件从svg的语法以及基本的使用介绍了svg的元素。当然了,在实际开发中,运用svg一般是从UI给出的设计稿中直接导出svg使用的。