自从2014年开始陆陆续续的开始就在接触SVG。但由于自身的原因,并没有对SVG进行系统化的学习,在实际的工作项目中并未真正的使用SVG相关的技术。为了储备相关的知识,并尝试在项目中使用SVG,有必要对该技术进行系统化的梳理和学习。所以开始每周会抽出大半的时间来学习和整理SVG相关的知识,希望在几个月后,这方面的技术有所突破。
为了能记录SVG的学习和探索过程,整个学习的路径以及笔记将会在W3cplus的SVG之旅中分享出来。希望对喜欢SVG的同学有所帮助。如果您是这方面的专家,欢迎分享您的经验。
要学习SVG相关的知识,那么就很有必要的知道,SVG是什么?今天我们就简单的来介绍SVG是什么?
图形系统
计算机中描述图形的信息主要有两大系统:栅格图形和矢量图形。
栅格图形
栅格图形(Raster Graphics)又常称为位图或点阵图,是使用像素阵列(Pixel-Array / Dot-Matrix点阵)来表示图像。其实栅格图形也是一种数据结构,代表了有限区域中的稠集(Dense Set),每一个元素至少出现一次,没有其他的数据和元素相关联。在索引,数据压缩等方面有广泛应用。
栅格图形系统中,图像被表示为图片元素或者像素的长方形数组。而栅格图像的像素部分都分配有特定的位置和颜色值。每个像素的颜色信息由RGB组合或者灰度值表示。
根据位深度,可将栅格图形分为1
、4
、8
、16
、24
和32
位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量就越大。比如,位深度为1
的像素位图只有两个可能的值(黑色和白色),所以又称之为二值位图。位深度为8
的图像有2
的8
次方个可能的值(也就是256
)。位深度为 8
的灰度模式图像有 256
个可能的灰色值。
RGB图像由三个颜色通道组成。8
位/像素的 RGB 图像中的每个通道有 256
个可能的值,这意味着该图像有 1600
万个以上可能的颜色值。有时将带有 8
位/通道 (bpc
) 的 RGB 图像称作 24
位图像(8 位 x 3 通道 = 24 位数据/像素
)。通常将使用24
位RGB组合数据位表示的的位图称为真彩色位图。
在浏览器还没有对SVG这样的矢量图进行支持之前,我们在Web中使用的图像都是栅格图形,比如jpg
和gif
等格式的图形。栅格图形的再现能力较强,但是在某些情形下会显得不足。比如,当浏览器以不同大小显示图像时,特别是当一张小图放大显示时,通常会产生锯齿边缘。也就是我们常说的,致使图像失真。
矢量图形
矢量图形是计算机图形学中用点、直线或者多边形等基于数学方程的几何图元表示图像。简单地说,在矢量图形系统中,图像被描述为一系列几何形状。矢量图形阅读器接受在指定坐标集上绘制形状的指令,而不是接受一系列已计算好的像素。
通俗的说:矢量图通过指定为确定每个像素的值所需的指令而不是指定这些值本身,克服了这些困难中的一部分。例如,向量图形不再为一个直径一英寸的圆提供像素值,而是告诉浏览器创建一个直径一英寸的圆,然后让浏览器(或插件)做其余事情。这消除了光栅图形的许多限制;使用向量图形,浏览器只要知道它必须画一个圆。如果图像需要以正常大小的三倍来显示,那么浏览器只要按正确的大小画圆而不必执行光栅图像通常的插入法。类似地,浏览器接收的指令可以更容易地与外部信息源(如应用程序和数据库)绑定,要对图像制作动画,浏览器只要接收有关如何操纵属性(如半径或颜色)的指令即可。
矢量图形相对于栅格图形而言,具有以下几个优势:
- 保存最少的信息,文件大小比位图要小,并且文件大小与物体的大小无关
- 在图像处理软件中,任意放大矢量图形,不会丢失细节或影响清晰度,因为矢量图形是与分辨率无关的。无限地放大这个圆,它仍然保持平滑;用多边形表示的曲线将会显现出不是真正的曲线
- 在放大的时候,直线与曲线都不会成比例地变粗,它只会保持不变或者要小于缩放比例;为了看起来比较平滑,使用简单几何形状表示的不规则曲线将会成比例地变粗,并且看起来不再像这些几何形状
- 保存的物体参数可以在后面修改。这也就是说物体的运动、缩放、旋转、填充等都不会降低绘制的精度。另外,可以用与设备无关的单位表示,这样更好地栅格设备上进行栅格化。
- 从三维的视角来看,由于阴影可以抽象为形成它们的光线,所以矢量图形的阴影渲染更加真实。这样就可以得到真实感的图像及渲染效果。
- 当调整矢量图形的大小、将矢量图形打印到 PostScript 打印机、在 PDF 文件中保存矢量图形或将矢量图形导入到基于矢量的图形应用程序中时,矢量图形都将保持清晰的边缘。因此,对于将在各种输出媒体中按照不同大小使用的图稿(如徽标),矢量图形是最佳选择。
用一张图来形象的表示矢量图和栅格图的区别:
左边的是矢量图,右边的是栅格图
而我们所要学的SVG就是矢量图形,也常称之为可缩放矢量图形(Scalable Vector Graphics,简称SVG)。那么什么是SVG?这也是今天我们主要要了解的东东。
SVG是什么?
SVG是XML语言的一种形式,有点类似XHTML,它可以用来绘制矢量图形,例如下图。SVG可以通过定义必要的线和形状来创建一个图形,也可以修改已有的位图,或者将这两种方式结合起来创建图形。图形和其组成部分可以变形,可以合成,还可以通过滤镜完全改变外观。
SVG推出于1999年,之前有几个相互竞争的格式规范被提交到W3C,但是由于之前1998年提交给W3C的PGML、VML标准构成竞争,所以造成SVG的标准没有完全通过。当下的浏览器支持程度请参考Can I use。即便浏览器实现了一些规范,但实现速度完全不能和它的竞争技术相比,它的竞争技术比如说HTML Canvas,都已经实现了成熟的应用接口。但是SVG也有自身的优点,比如它实现了DOM接口(比Canvas方便),不需要安装第三方插件就可以在浏览器中使用。当然,是否使用SVG还要取决于你要实现什么。
SVG严格遵从XML语法,并用文本格式的描述性语言来描述图像内容,因此是一种和图像分辨率无关的矢量图形格式。SVG允许3种图形对象类型:矢量图形、栅格图像以及文本。图形对象——包括PNG、JPEG这些栅格图像——能够被编组、设计、转换及集成进先前的渲染对象中。文本可以在任何适用于应用程序的XML命名空间之内,从而提高SVG图形的搜索能力和无障碍性。SVG提供的功能集涵盖了嵌套转换、裁剪路径、Alpha通道、滤镜效果、模板对象以及可扩展性。
SVG绘图是交互式和动态的。 例如,可使用脚本来定义和触发动画。这一点与Flash相比很强大。Flash是二进制文件,动态创建和修改都比较困难。而SVG是文本文件,动态操作是相当容易的。而且,SVG直接提供了完成动画的相关元素,操作起来非常方便。
SVG与其他Web标准兼容,并直接支持文档对象模型DOM。这一点也是与HTML5中的Canvas相比很强大的地方。因而,可以很方便的使用脚本实现SVG的很多高级应用。而且SVG的图形元素基本上都支持DOM中的标准事件。可将大量事件处理程序(如onmouseover
和onclick
)分配给任何SVG图形对象。 虽然SVG的渲染速度比不上canvas
元素,但是胜在DOM操作很灵活,这个优势完全可以弥补速度上的劣势。
SVG优点
SVG主要具有以下几个优点:
- 图像文件可读,易于修改和编辑(理论上如此,但实际上却是因为各种不同的SVG档编辑器而可能存储成不易解读的SVG文件)
- 与现有技术可以互动融合。例如,SVG技术本身的动态部分(包括时序控制和动画)就是基于SMIL标准。另外,SVG文件还可嵌入JavaScript(严格地说,应该是ECMAScript)脚本来控制SVG对象
- SVG图形格式可以方便的创建文字索引,从而实现基于内容的图像搜索
- SVG图形格式支持多种滤镜和特殊效果,在不改变图像内容的前提下可以实现位图格式中类似文字阴影的效果
- SVG图形格式可以用来动态生成图形。例如,可用SVG动态生成具有交互功能的地图,嵌入网页中,并显示给终端用户
SVG缺点
SVG有优点也一定会有一些缺点,其缺点主要有:
- 如何和已经占有重要市场份额的矢量图形格式Adobe Animate竞争的问题。
- SVG的本地运行环境下的厂家支持程度。
- 由于原始的SVG档是遵从XML语法,导致数据采用未压缩的方式存放,因此相较于其他的矢量图形格式,同样的文件内容会比其他的文件格式稍大。Adobe因此使用
gzip
压缩开发出压缩的SVG档格式,附档名为.svgz
, 但此种文件格式除了Adobe旗下的软件以外,未被广泛支持使用。 - 旧版的SVG Viewer无法正确显示出使用新版SVG格式的矢量图形。
SVG在Web中的表现方式
在整个系列,我们默认是浏览器对SVG支持,不做过多的讨论。SVG提供了类似HTML的DOM形式。众所周知,HTML提供了标题、段落、表格等内容的元素。与此类似,在SVG中也提供了一些元素,比如用于定义圆、矩形、曲线和多边形等。一个简单的SVG文档由<svg>
根元素(相当于<html>
根元素)和基本的形状元素构成。另外还有一个<g>
元素,用来把若干个基本形状编写成一个组。
对于Web页面或Web应用程序中使用SVG,主要采取的方式由内联到HTML和引用外部的独立的.svg
文件。对于内联到HTML方式,可以像我们平时使用HTML元素一样,直接在HTML代码中使用<svg>
和其相关的图形元素。比如:
<svg width="100%" height="200"><rect width="100%" height="100%" fill="red" /><circle cx="50%" cy="100" r="80" fill="green" /><text x="50%" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text></svg>
除此之外,你可以把上面的<svg>
的所有代码复制到一个编辑器中,然后保存成一个.svg
的文件。然后在HTML页面中通过<img>
、<object>
和<iframe>
元素引用到.svg
文件。你也可以在CSS中通过background-image
和border-image
这样的属性来引用独立的.svg
文件。用来装饰HTML中的元素。而且你也可以通过JavaScript动态创建SVG,并注入到HTML DOM中。这样有一个优点,可以对浏览器使用替代技术,在不能解析SVG的情况下,可以替换创建的内容。
这里提前声明一下,此系列后续的文章,我们介绍的都是内联到HTML的SVG。除非有特别的声明。
SVG文件类型
SVG也具有自己的文件类型格式。SVG文件主要有两种形式。普通SVG文件是包含SVG标记的简单文本文件。推荐使用.svg
作为此类文件的扩展名。
由于在某些应用(比如地图应用等)中使用时,SVG文件可能会很大,SVG标准同样允许gzip
压缩的SVG文件。推荐使用.svgz
作为此类文件扩展名 。使用gzip
压缩的SVG文件格式,需要注意服务器相关的配置。如果服务器配置错误会引起SVG加载失败。不过这里我们不做过多的讨论(在这方面我也是小白)。
SVG的种类
自从2003年成为W3C推荐标准以来,最接近的“完整版”SVG版本是1.1版,它基于1.0版,并且增加了更多便于实现的模块化内容,SVG1.1的第二个版本在2011年成为推荐标准,完整的SVG1.2本来是下一个标准版本,但它又被SVG2.0取代。SVG2.0正在制定当中,它采用了类似CSS3的制定方法,通过若干松散耦合的组件形成一套标准。
除了完整的SVG推荐标准,W3C工作组还在2003年推出了SVG Tiny和SVG Basic。这两个配置文件主要瞄准移动设备。首先SVG Tiny主要是为性能低的小设备生成图元(比如移动端),而SVG Basic实现了完整版SVG里的很多功能,只是舍弃了难以实现的大型渲染(比如动画)。2008年,SVG Tiny1.2成为W3C推荐标准。
开始编写SVG之前
市面上有很多应用软件,比如Inkscape、Adobe Illustrator和Sketch等都可以支持SVG格式的文件,也可以使用这些制图软件,绘制矢量图形,然后导出SVG格式的文件(只是导出的SVG文件会产生一定的垃圾代码,需要手工或者通过一定的工具来处理,这部分我们后续将会涉及到)。但是此系列建议在学习过程中使用文本编辑器。因为只有手动去写SVG代码,才能更好的理解SVG内部的原理。这也是我们学习SVG的最终目标。
各种浏览器对SVG的渲染是有所差异的,但后系的SVG只在Chrome浏览器(当然后续会研究SVG在手淘这样的APP中的应用)。其次,还可以将JavaScript和CSS相关的技术结合一起来用SVG。这将是我们最期待,也是将是最有意思的一部分内容。比如怎么通过CSS来控制SVG的风格,怎么通过JavaScript来更好的控制SVG的动画。
在正式开始之前,你需要基本掌握HTML这样的标记语言,最好是对XML有一定的了解,如果你和我一样对XML不是很熟悉,那么在手动编写SVG代码时需要记住:
- SVG的元素和属性必须按标准格式书写,因为XML是区分大小写的(这一点和HTML不同)
- SVG里的属性值必须用引号引起来,就算是数值也必须这样做
SVG是一个庞大的规范,我们将会从入门级别开始,一旦我们掌握了这此基础内容,我们将继续学习更复杂的部分,从而系统的掌握SVG相关的内容,也是我们学习SVG的最终目标。
学习SVG相关资料
- W3C的SVG规范 V2.0
- Advanced SVG
- Jakob's SVG Tutorial
- MDN: SVG Tutorial
- Medium: SVG Tag
- SVG Examples
- Codepen: SVG Demo
- Codrops: SVG Tag
- W3cplus的SVG教程
总结
通过这篇文章的学习,我们简单的了解了图形系统中的两大系统:栅格图形和矢量图形。并且知道两者之间的区别。最主要的了解SVG的一些概况,对SVG有了一个初步的认识。就算是阅读到文章的末尾,可能还是无法写出任何SVG相关的代码,还是不会用SVG绘制矢量图。但这一切都不是问题,随着后面的学习,我相信我们都能做到。比如给自己定一个小目标,经过对SVG的学习,我们可以写出像下面这样的SVG效果:
如需转载,烦请注明出处:https://www.w3cplus.com/svg/svg-intro.html