what
SVG 指的是可伸缩矢量图形 (Scalable Vector Graphics),即放大或者缩小不失真,使用 XML 格式定义图形。
包含形状、样式、标记、滤镜、渐变等。
预定义了七种形状元素:矩形(rect)、圆形(circle)、椭圆(ellipse)、线段(line)、折线(polyline)、多边形(polygon)、路径(path)
。
why
与其他图像格式相比,使用 SVG 的优势有以下几点:
- SVG 可被非常多的工具读取和修改(比如记事本)
- SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
- SVG 是可伸缩的
- SVG 图像可在任何的分辨率下被高质量地打印
- SVG 可在图像质量不下降的情况下被放大
- SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
- SVG 可以与 Java 技术一起运行
- SVG 是开放的标准
- SVG 文件是纯粹的 XML
- 相比 css 来讲,兼容性更好,早于 css3 实现一些特殊效果,功能强大
适用于 大型渲染区域,如百度地图,不适合游戏。用途:
- 静态图形绘制
- 动态动画效果
- 专门事件绑定
how
入门实例
1 | <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="110" height="50" |
要点说明:
- 以 svg 标签包含,version 为 svg 的版本,xmlns 定义 svg 命名空间
- circle 标签创建一个圆,cx 和 cy 属性定义圆的中心坐标,默认是(0,0),r 为半径, fill 为填充颜色, stroke-width 为边框宽带
坐标定位
对于所有元素,SVG 使用的坐标系统或者说网格系统,和Canvas用的差不多(所有计算机绘图都差不多)。这种坐标系统是:以页面的左上角为 (0,0) 坐标点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下。注意,这和你小时候所教的绘图方式是相反的。但是在 HTML 文档中,元素都是用这种方式定位的。
内置图形的 html 属性 或 css 样式
1 | fill(填充颜色) |
常见图形用法
1. 矩形(rect)
1 | <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> |
- x 属性定义矩形的左侧位置(例如,x=”0” 定义矩形到浏览器窗口左侧的距离是 0px)
- y 属性定义矩形的顶端位置(例如,y=”0” 定义矩形到浏览器窗口顶端的距离是 0px)
- rx 和 ry 属性可使矩形产生圆角。
2. 圆形(circle)
1
2
3
4<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>
</svg> - cx 属性定义的椭圆中心的x坐标
- cy 属性定义的椭圆中心的y坐标
3. 椭圆(ellipse)
1
2
3
4<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<ellipse cx="300" cy="80" rx="100" ry="50"
style="fill:yellow;stroke:purple;stroke-width:2"/>
</svg> - rx 属性定义的水平半径
- ry 属性定义的垂直半径
4. 线段(line)
1
2
3
4<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="0" y1="0" x2="200" y2="200"
style="stroke:rgb(255,0,0);stroke-width:2"/>
</svg> - x1 属性在 x 轴定义线条的开始
- y1 属性在 y 轴定义线条的开始
- x2 属性在 x 轴定义线条的结束
- y2 属性在 y 轴定义线条的结束
5. 折线(polyline)
元素是用于创建任何只有直线的形状。 1
2
3
4<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<polyline points="20,20 40,25 60,40 80,120 120,140 200,180"
style="fill:none;stroke:black;stroke-width:3" />
</svg>6. 多边形(polygon)
<polygon>
标签用来创建含有不少于三个边的图形。
多边形是由直线组成,其形状是”封闭”的(所有的线条 连接起来)。1
2
3
4<svg height="210" width="500">
<polygon points="100,10 40,198 190,78 10,78 160,198"
style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" />
</svg> - points 属性定义多边形每个角的 x 和 y 坐标
7. 路径(path)
1
2
3<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path d="M150 0 L75 200 L225 200 Z" />
</svg> - d 路径数据: 注意:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。
1
2
3
4
5
6
7
8
9
10M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Bézier curve
T = smooth quadratic Bézier curveto
A = elliptical Arc
Z = closepath
8. 文本(text)
1 | <svg xmlns="http://www.w3.org/2000/svg" version="1.1" |
9. <defs>
和 <g>
所有互联网的SVG
滤镜定义在<defs>
元素中。<defs>
元素定义短并含有特殊元素(如滤镜)定义。<filter>
标签用来定义SVG滤镜。
1 | <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> |
<defs>
定义可复用的部件<g>
定义统一的样式
10. 事件
常用的时间有 onclick \ onactivate \ onmousedown \ onmouseup \ onmouseover \ onmousemove \ onmouseout \ onload \ onresize \ onunload \ onrepeat
svg 嵌入 Html 中
<embed>
1 | <embed src="circle1.svg" type="image/svg+xml" /> |
<object>
1 | <object data="circle1.svg" type="image/svg+xml"></object> |
<iframe>
1 | <iframe src="circle1.svg"></iframe> |
<svg>
1 | <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> |
svg 滤镜
SVG可用的滤镜是(19个):
1 | feBlend - 与图像相结合的滤镜 |
可以用滤镜实现想要的模糊、阴影等等效果(用来增加对SVG图形的特殊效果),类似 css 滤镜中blur()、contrast()、drop-shadow()
, for example:
1 | <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> |
<filter>
元素id
属性定义一个滤镜的唯一名称in="SourceGraphic"
这个部分定义了由整个图像创建效果<rect>
元素的滤镜属性用来把元素链接到"f1"
滤镜- result 用于 中间结果的输出(也称作 primitives 图元),其他滤镜可以使用 in 属性导入 result
- in2 用于接收某个 result 输出,在此效果上面进行过滤
多个滤镜合并使用
在不同的滤镜利用 result 和 in 属性,可以实现在前一个基本变换基础上建立另一个操作。其中可能涉及的标签可能有feComposite|feMerge|feFlood
等。
feMerge
滤镜允许同时应用滤镜效果而不是按顺序应用滤镜效果。- 遵循 后输入 的层级更高的原则。
1
2
3
4
5
6
7
8
9
10
11<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="f1" x="0" y="0" width="200%" height="200%">
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
</filter>
</defs>
<rect width="90" height="90" stroke="green" stroke-width="3"
fill="yellow" filter="url(#f1)" />
</svg>标签属性
基本每个滤镜标签都有的属性:1
2
3
4
5
6
7
8
9
10x,y - 坐标
width,height - 宽|高
result - 定义一个滤镜效果的输出名称,以便 in
in - 指定滤镜效果的输入源,可以是某个 result ,也可以是下面 6 个值:
SourceGraphic - 图形元素本身作为 输入源
SourceAlpha - 与 SourceGraphic,相比不同在于 只使用元素的非透明部分
BackgroundImage
BackgroundAlpha
FillPaint
StrokePaint
混合模式
css 中,有混合模式 mix-blend-mode
和 background-blend-mode
。
svg 中有 5 个 - normal(正常) | multiply(正片叠底) | screen(滤色) | darken(变暗) | lighten(变亮)
<feColorMatrix>
该滤镜基于转换矩阵对颜色进行变换。每一像素的颜色值([红,绿,蓝,透明度]的矢量)都经过矩阵乘法 (matrix multiplated) 计算出的新颜色。
1 | // 包含两个私有属性 |
saturate 和 hueRotate 与 css 中 filter 中的 saturate 和 hue-rotate 作用一模一样。
图形的表示:数字图形的本质是一个多维矩阵,把图像的R分量放进红色通道里,B分量放到蓝色通道里,G分量放到绿色通道里,经过处理,显示在屏幕上的是我们看到的彩色图像。
1 | // 矩阵计算得到 rgba() 值 |
两种光源及其他
光照滤镜
是 svg 区别于 css 的独特魅力。feSpecularLighting(镜面照明) | feDiffuseLighting (散射光照明)
都为光照滤镜,使用它们照亮一个源图形。feDiffuseLighting
: 来自外部光源,适合模拟太阳光或者灯光照明feSpecularLighting
: 指定从反射面反射的二次光
形态滤镜 <feMorphology>
feMorphology
:形态滤镜,输入源是 图形的 alpha 通道,利用 operator 设置腐蚀(变薄 erode)或者扩张(加粗 dilate), 默认 erode, radius 标识笔触的大小,该模式下的效果程度,默认 0 。
纹理滤镜 <feTurbulence>
turbulence 为 湍流,不稳定气流,svg 能够实现半透明或者波状图像,利用 Perlin 噪声函数 可以实现 人造纹理。feTurbulence
: 可以创建纹理图作为置换图,不需要借助外部图形的纹理效果,即可创建复杂的效果。三个需要注意的属性:
1 | type - fractalNoise (分形噪声更加平滑,更接近云雾)| turbulence (湍流噪声) |
映射置换滤镜 <feDisplacementMap>
feDisplacementMap
为映射置换滤镜,需要掌握很多 PhotoShop 纹理创建或者是图形色彩相关的知识。使用该滤镜用于改变元素和图形的像素位置,将遍历原图的所有像素点,映射到新的位置,形成新图形。可以将纹理滤镜过后的图形进行形变、扭曲、液化等等,转化的一个公式-P(x + scale * (XC*(x,y) - 0.5, y + scale * (YC*(x,y) - 0.5) → P(x,y)
。
svg 渐变
渐变是一种从一种颜色到另一种颜色的平滑过渡。另外,可以把多个颜色的过渡应用到同一个元素上。
SVG渐变主要有两种类型:
- Linear(线性渐变
<linearGradient>
) - Radial(放射渐变
<radialGradient>
)
<linearGradient>
标签必须嵌套在<defs>
的内部。
线性渐变可以定义为水平,垂直或角渐变:
- 当y1和y2相等,而x1和x2不同时,可创建水平渐变
- 当x1和x2相等,而y1和y2不同时,可创建垂直渐变
- 当x1和x2不同,且y1和y2不同时,可创建角形渐变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
<radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:rgb(255,255,255);
stop-opacity:0" />
<stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
</radialGradient>
<style>
.ellipse {
fill: url(#grad);
}
</style>
</defs>
<ellipse cx="200" cy="70" rx="85" ry="55" class="ellipse" />
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg> - 可以利用
class
或者id
在style
里面写fill
或者filter
。url
是 css 滤镜属性的关键字之一,允许引入特定的 svg 过滤器,极大增强了 css 滤镜的能力。