Svg 是什么
SVG,即可缩放矢量图形(Scalable Vector Graphics),是一种 XML 应用,可以以一种简洁、可移植的形式表示图形信息。目前,人们对 SVG 越来越感兴趣。大多数现代浏览器都能显示 SVG 图形,并且大多数矢量绘图软件都能导出 SVG 图形。
SVG 主要可以概括为以下几点:
- SVG 指可缩放矢量图形
- SVG 用来定义用于网格的基于矢量的图形
- SVG图像在放大或改变尺寸的情况下其图形质量不会有所损失
- SVG 由万维网联盟(W3C)制定,是一个开放标准
- SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
SVG严格遵从XML语法,并用文本格式的描述性语言来描述图像内容,因此是一种和图像分辨率无关的矢量图形格式
SVG主要支持以下几种显示对象:
SVG可以实现动态和交互功能。在DOM模型的基础上,SVG开发设计人员可以利用ECMAScript或者SMIL来进行时序控制或对象的操纵。SVG虽然是文本格式,但是SVG支持利用gzip压缩算法减少文件尺寸,压缩后的文件通常用被称为“SVGZ文件”。
浏览器支持
Internet Explorer 9、Firefox、Opera、Chrome 以及 Safari 支持内联 SVG。
Internet Explorer 8或更早版本,可通过安装Adobe SVG Viewer以支持SVG。
SVG优势
- 图像文件可读,易于修改和编辑(理论上如此,但实际上却是因为各种不同的SVG档编辑器而可能存储成不易解读的SVG文件)
- 与现有技术可以互动融合。例如,SVG技术本身的动态部分(包括时序控制和动画)就是基于SMIL标准。另外,SVG文件还可嵌入JavaScript(严格地说,应该是ECMAScript)脚本来控制SVG对象
- SVG图形格式可以方便的创建文字索引,从而实现基于内容的图像搜索(文本独立)
- SVG图形格式支持多种滤镜和特殊效果,在不改变图像内容的前提下可以实现位图格式中类似文字阴影的效果。
- SVG图形格式可以用来动态生成图形。例如,可用SVG动态生成具有交互功能的地图,嵌入网页中,并显示给终端用户。
SVG格式具有以下缺点:
- 由于原始的SVG档是遵从XML语法,导致数据采用未压缩的方式存放,因此相较于其他的矢量图形格式,同样的文件内容会比其他的文件格式稍大。Adobe因此使用gzip压缩开发出压缩的SVG档格式,附档名为 .svgz, 但此种文件格式除了Adobe旗下的软件以外,未被广泛支持使用。
- 旧版的SVG Viewer无法正确显示出使用新版SVG格式的矢量图形。
SVG 的主要竞争者是 Flash。
与 Flash 相比,SVG 最大的优势是与其他标准(比如 XSL 和 DOM)相兼容。而 Flash 则是未开源的私有技术。
版本
- 2001年9月4日,发布SVG 1.0。
- 2003年1月4日,发布SVG 1.1。
- 2003年1月14日,推出SVG移动子版本:SVG Tiny和SVG Basic。
- 2008年12月22日,发布SVG Tiny 1.2。
- 2011年8月16日,发布SVG 1.1(第2版),成为W3C目前推荐的标准。
- W3C目前仍正在研究制定SVG 2。
SVG 的应用
- 图表视图(echart)、地图视图(WEB-GIS)
- 形象(AI)的全网应用
- UI 产品的设计
- SVG 动画
Canvas
Canvas API(画布)是在HTML5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用JavaScript操作的位图(bitmap)。
Canvas 对象表示一个 HTML 画布元素 -<canvas>。它没有自己的行为,但是定义了一个 API 支持脚本化客户端绘图操作。
<canvas> 标记和 SVG以及 VML 之间的一个重要的不同是,<canvas> 有一个基于 JavaScript 的绘图 API,而 SVG 和 VML 使用一个 XML 文档来描述绘图。
这两种方式在功能上是等同的,任何一种都可以用另一种来模拟。从表面上看,它们很不相同,可是,每一种都有强项和弱点。例如,SVG 绘图很容易编辑,只要从其描述中移除元素就行。
要从同一图形的一个 <canvas> 标记中移除元素,往往需要擦掉绘图重新绘制它。
SVG 与 Canvas 区别
<canvas /> | SVG | |
历史 | 较新,由apple私有技术发展而来 | 2003成为W3C标准 version= 1.1 |
功能 | 功能简单,2D绘制API,WEBGL等3D技术 | 功能丰富,各种图形、滤镜、动画等 |
特点 | 像素,只能脚本驱动 | 矢量,XML、CSS,元素操作 |
支持 | 主流浏览器,IE9+ | 主流浏览器,IE9+,其他SVG阅读器 |
操作对象 | 基于像素(动态点阵图) | 基于图形元素 |
元素 | 单个HTML元素 | 多种图形元素 |
驱动 | 只能脚本驱动 | 支持脚本和css |
事件交互 | 用户交互到像素点 | 用户交互到图形和元素 |
性能 | 适合小面积 | 适合大面积。小数量应用场景 |
动画 | 数据驱动 | DOM驱动 |
图形系统
计算机中描述图形信息的两大系统是栅格图形和矢量图形。
栅格图形
在栅格图形系统中,图像被表示为图片元素或者像素的长方形数组如下图片所示。每个像素用其 RGB 颜色值或者颜色表内的索引表示。这一系列也称为 位图,通过以某种压缩格式存储。由于大多数现代显示设备也是栅格设备,显示图像时仅需要一个阅读器将位图解压并将它传输到屏幕上。
矢量图形
矢量图是基于数学的描述。所谓矢量图,就是使用直线和曲线来描述的图形,构成这些图形的元素是一些点、线、矩形、多边形、圆和弧线等,它们都是通过数学公式计算获得的,具有编辑后不失真的特点。它具有颜色、形状、轮廓、大小和屏幕位置等属性。如下图的多啦A梦,他的头是一条怎么样的贝塞尔曲线,它的参数是什么及用什么颜色来填充贝塞尔曲线,通过这种方式描述图片就是矢量图形。
想象一下在一张绘图纸上作图的过程,栅格图形的工作就像是描述哪个方格应该填充什么颜色,而矢量图形的工作则像是描述要绘制从某个点到另一个点的直线或曲线。
<svg width='140' height='170' xmlns='http://wwww.w3.org/2000/svg'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
</svg>
根元素 <svg> 以像素为单位定义了整个图像的 width 和 height,还通过 xmlns 属性定义了 SVG 的命名空间。<title> 元素的内容可以被阅读器显示在标题栏上或者是作为鼠标指针指向图像时的提示, <desc> 元素允许咱们为图像定义完整的描述信息。
基本图形
<rect>、<circle>、<ellipse>、<line>、<polyline>、<polygon>
基本属性
fill、stroke、stroke-width、transform
Example-cat
圆形
咱们可以通过 <circle> 元素来绘制猫的脸部。元素属性的中心点 x 坐标和 y 坐标以为半径。点(0,0) 为图像左上角。水平向右移动时 x 坐标增大,垂直向下移动时 y 坐标增大。为了避免一些误会,API 语义就很明确了,点 (cx, cy) 就表示圆心的位置,r 表示圆的半径。绘图的颜色是表现的一部分,表现信息包含在 style 属性中,这里的轮廓颜色为黑色,填充颜色为 none 以使猫的脸部透明。
<svg width='140'heiight='170'xmlns='http://wwww.w3.org/2000/svg'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
<circlecx='70'cy='95'r='50'style='stroke:black; fill:none'></circle>
</svg>
指定样式的属性
接着在添加两个圆表示两个眼睛。上面的 stroke 与 fill 是写在 style 里面的,但是 SVG 也允许咱们使用单独的属性,而不用全部写在 style 内,如下所示:
<svgwidth='140'heiight='170'xmlns='http://wwww.w3.org/2000/svg'> <title>Cat</title> <desc>Stick Figure of Cat</desc> <!-- 在这里绘制图像 --> <circlecx='70'cy='95'r='50'style='stroke:black; fill:none'></circle> <circlecx='55'cy='80'r='5'stroke='black'fill='#3339933'></circle> <circlecx='85'cy='80'r='5'stroke='black'fill='#3339933'></circle></svg>
图形对象分组
接着使用两个 <line> 元素在猫的右脸上添加胡须,先看下线的示意图:
这很好理解,就不多说了。这里我们需要把胡须作为一个部件,并包装在分组元素 <g> (后面会讲)里面,然后给下 id ,如下所示:
<svgwidth='140'heiight='170'xmlns='http://wwww.w3.org/2000/svg'> <title>Cat</title> <desc>Stick Figure of Cat</desc> <!-- 在这里绘制图像 --> <circlecx='70'cy='95'r='50'style='stroke:black; fill:none'></circle> <circlecx='55'cy='80'r='5'stroke='black'fill='#3339933'></circle> <circlecx='85'cy='80'r='5'stroke='black'fill='#3339933'></circle> <gid='whiskers'> <linex1='75'y1='95'x2='135'y2='85'style='stroke:black'></line> <linex1='75'y1='95'x2='135'y2='105'style='stroke:black'></line> </g></svg>
图形对象分组
接着使用 <use> 复用胡须分组并将它变换(transfrom) 为左侧胡须,如下图所示,首先在 scale 变换中对 x 坐标乘以 -1,翻转坐标系统。这意味原始坐标系统中的点(75, 95) 现在位于 (-75, 95)。接着通过 translate 向左平移调整对应的位置。
<svgwidth='140'heiight='170'xmlns='http://wwww.w3.org/2000/svg'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
<circlecx='70'cy='95'r='50'style='stroke:black; fill:none'></circle> <circlecx='55'cy='80'r='5'stroke='black'fill='#3339933'></circle> <circlecx='85'cy='80'r='5'stroke='black'fill='#3339933'></circle>
<gid='whiskers'>
<linex1='75'y1='95'x2='135'y2='85'style='stroke:black'></line>
<linex1='75'y1='95'x2='135'y2='105'style='stroke:black'></line>
</g>
<usexlink:href="#whiskers"transform='scale(-1 1) translate(-140 0)'></use>
</svg>
其他基本图形
如下图所示,咱们使用 <polyline> 元素构建嘴和耳朵,它接受一对 x 和 y 坐标为 points 属性的值。你可以使用空格或者逗号分隔这些数值。
<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
<circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
<circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
<circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
<g id='whiskers'>
<line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
<line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
</g>
<use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
<!-- 耳朵 -->
<polyline points='108 62,90 10, 70 45, 50, 10, 32, 62' style='stroke:black; fill:none' />
<!-- 嘴 -->
<polyline points='35 110,45 120, 95 120, 105, 110' style='stroke:black; fill:none'/>
</svg>
路径
所有的基本形状都是通用的 <path> 元素的快捷写法。接着使用 <path> 元素为猫添加鼻子。如下所示的代码,翻译过来就是 "移动到坐标(75, 90)。绘制一条到坐标(65,90) 的直线。然后以 x 半径为 5、y 半径为 10 绘制一个椭圆,最后回到坐标 (75, 90) 处"
<svg width='140' heiight='170' xmlns='http://wwww.w3.org/2000/svg'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
<circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
<circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle> <circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
<g id='whiskers'>
<line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
<line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
</g>
<use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
<!-- 耳朵 -->
<polyline points='108 62,90 10, 70 45, 50, 10, 32, 62' style='stroke:black; fill:none' />
<!-- 嘴 -->
<polyline points='35 110,45 120, 95 120, 105, 110' style='stroke:black; fill:none'/>
<!-- 鼻子 -->
<path d='M 75 90 L 65 90 A 5 10 0 0 0 75 90' style='stroke:black; fill:#ffcccc' />
</svg>
路径
由于这只是一个简单的图形,用户可能看不出这是一只猫,所以咱们可以使用元素添加一些文本注释。在元素中,x 和 y 属性用于指定文本的位置,如下所示:
<svg width='140' height='170' xmlns='http://wwww.w3.org/2000/svg' xmlns:xlink='http://wwww.w3.org/1999/xlink'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
<circle cx='70' cy='95' r='50' style='stroke:black; fill:none'></circle>
<circle cx='55' cy='80' r='5' stroke='black' fill='#3339933'></circle>
<circle cx='85' cy='80' r='5' stroke='black' fill='#3339933'></circle>
<g id='whiskers'>
<line x1='75' y1='95' x2='135' y2='85' style='stroke:black'></line>
<line x1='75' y1='95' x2='135' y2='105' style='stroke:black'></line>
</g>
<use xlink:href="#whiskers" transform='scale(-1 1) translate(-140 0)' ></use>
<!-- 耳朵 -->
<polyline points='108 62,90 10, 70 45, 50, 10, 32, 62' style='stroke:black; fill:none' />
<!-- 嘴 -->
<polyline points='35 110,45 120, 95 120, 105, 110' style='stroke:black; fill:none'/>
<!-- 鼻子 --> <path d='M 75 90 L 65 90 A 5 10 0 0 0 75 90' style='stroke:black; fill:#ffcccc' />
<text x="60" y="165" style='font-family:sans-serif;font-size: 14pt; stroke:none; fill: black; '>Cat</text>
</svg>
在网页中使用 SVG
SVG 是一种图件格式,因此可以使用与其他图像类型相同的方式包含在 HTML 页面中。具体可以采用两种方法:将图像包含在 <img> 元素内(当图像是页面的基本组成部分时,推荐这种方式);或者将图像作为另一个元素的 CSS 样式属性插入(当图像主要用来装饰时,推荐这种方式)。
在 元素内包含 SVG
在 <img> 元素内包含 SVG 图像非常简单,只需设置 src 指向 SVG 文件位置即可。如下:
<img src='cat.svg' alt=''/>
在 CSS 中包含 SVG
可以使用 background-image 属性来显示 SVG,如果没有固有尺寸, SVG 会被缩放为元素高度和宽度的 100%,如下所示:
div.background-cat {
background-image: url('cat.svg');
background-size: 100% 100%;
}
在网页中直接使用 SVG 标签
<svg width='140'heiight='170'xmlns='http://wwww.w3.org/2000/svg'>
<title>Cat</title>
<desc>Stick Figure of Cat</desc>
<!-- 在这里绘制图像 -->
<circlecx='70'cy='95'r='50'style='stroke:black; fill:none'></circle>
</svg>
视窗
SVG的属性width、height来控制视窗的大小,也称为SVG容器
世界
SVG里面的代码,就是对SVG世界的定义
视野
世界是无穷大的,视野是观察世界的一个矩形区域。如下图所示
线段
SVG 可以使用元素画出一条直线,使用只需要指定线段的起(x1, y1)止(x2, y2)点。
<svg width='140'height='170'xmlns='http://wwww.w3.org/2000/svg'>
<linex1='0'y1='0'x2='100'y2='100'style='stroke:black'/>
</svg>
<svg width='140'height='170'xmlns='http://wwww.w3.org/2000/svg'>
<!-- 红色 -->
<linex1='10'y1='10'x2='50'y2='10'style='stroke-width:5;stroke:red'/>
<!-- 谈绿色 -->
<linex1='10'y1='20'x2='50'y2='20'style='stroke-width:5;stroke:#9f9f;stroke-opacity: 0.2'/>
<!-- 橘色 -->
<linex1='10'y1='40'x2='50'y2='40'style='stroke-width:5;stroke:rgb(255,128,64);stroke-opacity: 0.5'/>
<!-- 深紫色 -->
<linex1='10'y1='50'x2='50'y2='50'style='stroke-width:5;stroke:rgb(60%,20%,60%);stroke-opacity: 0.8'/>
</svg>
<svgwidth='200'height='200'xmlns='http://wwww.w3.org/2000/svg'>
<!-- 9个像素的虚线,5个像素的空隙 -->
<linex1='10'y1='10'x2='100'y2='10' style='stroke-dasharray:9, 5; stroke: black; stroke-width:2' />
<!-- 5个像素的虚线,3个像素的空隙 ,9个像素的虚线,2个像素的空隙 -->
<linex1='10'y1='30'x2='100'y2='30' style='stroke-dasharray:9, 5, 9, 2; stroke: black; stroke-width:2'/>
<!-- 复制奇数个数 -->
<linex1='10'y1='50'x2='100'y2='50' style='stroke-dasharray:9, 3, 5; stroke: black; stroke-width:2'/>
</svg>
矩形
矩形是最简单基本形状,只需要其左上角 x 和 y 坐标以及它的宽度(width)和高度(height),如果想要指定圆角,可以指定 rx(x方向的圆角半径),该最大值是矩形宽度的一半,同理,ry(y 方向的圆角半径),该最大值是矩形高度的一半。如果只指定了 rx 和 ry 中的一个值,则认为它们相等,矩形内部还可以使用 fill 属性来填充颜色,默认为黑色,用 stroke 来绘制边框,默认透明。
<svg width='300'height='500'xmlns='http://wwww.w3.org/2000/svg'>
<!-- 内部填充为黑色,不绘制边框 -->
<rect x='10'y='10'width='30'height='50'/>
<!-- 内部填充为蓝色,绘制较粗,半透明红色边框-->
<rect x='50'y='10'width='30'height='50' style='fill: #0000ff;stroke: red;stroke-width: 7; stroke-opacity: .5'/>
<!-- rx 和 ry 相等,逐渐增大-->
<rect x='10'y='70'rx='2'ry='2'width='20'height='40' style='stroke:black; fill:none'/>
<!-- rx 和 ry 相等,逐渐增大-->
<rect x='50'y='70'rx='5'width='20'height='40' style='stroke:black; fill:none'/>
<!-- rx 和 ry 不相等 -->
<rect x='10'y='130'rx='10'ry='5'width='20'height='40'style='stroke:black; fill:none'/>
<rect x='50'y='130'rx='10'ry='5'width='10'height='40'style='stroke:black; fill:none'/>
</svg>
椭圆
对于椭圆来说,除了指定圆心和坐标外,还需要同时指定 x 方向的半径和 y 方向的半径,属性分为是 rx 和 ry。对于圆和椭圆来说,如果省略 cx 或者 cy ,则默认为 0,如果半径为 0,则不会显示图形,如果半径为负数,则会报错。
<svg width='300' height='500' xmlns='http://wwww.w3.org/2000/svg'>
<circle cx='30' cy='30' r='20' style='stroke:black; fill:none'/>
<circle cx='80' cy='30' r='20' style='stroke-width:5;stroke:black; fill:none' />
<ellipse cx='30' cy='80' rx='10' ry='20' style='stroke:black; fill:none' />
<ellipse cx='80' cy='80' rx='20' ry='10' style='stroke:black; fill:none' />
</svg>
多边形
咱们可以使用 <polygon> 元素绘制多边形,使用 points 属性指定一系列的 x/y 坐标对,并用逗号或者空格分隔坐标个数必须是偶数。指定坐标不需要在最后指定返回起始坐标, <polygon> 元素会自动回到起始坐标。来几个例子看看
<svgwidth='200'height='200'xmlns='http://wwww.w3.org/2000/svg'>
<!--平等四边形-->
<polygonpoints='15,10 55,10 45,20 5,20' style='fill:red; stroke: black;' />
<!--五角星-->
<polygonpoints='35,37.5 37.9,46.1 46.9,46.1 39.7,51.5 42.3,60.1 35,55 27.7,60.1 30.3,51.5 23.1,46.1 32.1,46.1' style='fill: #ccffcc; stroke: green;' />
<!--不规则图形-->
<polygonpoints='60 60, 65,72 80 60, 90,90 72,85 50,95' style="fill: yellow; fill-opacity:.5; stroke:black" />
</svg>
折线
<polyline> 元素与有相同的属性,不同之处在于图形并不封闭,直接来个事例看看:
<svg width='200' height='200' xmlns='http://wwww.w3.org/2000/svg'>
<polyline points="5,20 20,20 25,10 35,30 45,10 55,30 65,10 74,30 80,20 95,20" style="stroke:black; stroke-width:3; fill:none" />
</svg>
总结
形状元素
线段:<line x1=" "y1=" "x2=" "y2=" "style=" "/>
矩形:<rect x=" "y=" "width=" "height=" "style=" "/>
圆角矩形:<rect x=" "y=" "rx=" "ry=" "style=" "/>
圆形:<circlec x=" "cy=" "r=" "style=" "/>
椭圆形:<ellipsec x=" "cy=" "rx=" "ry=" "style=" "/>
多边形:<polygon points=" "style=" "/>
折线:<polyline points=" "style=" "/>
//注意需把fill设成none