SVG 遵循 XML 格式的描述语言来描述矢量图形的内容,支持三种矢量显示对象,包括矢量图形对象(矩形、圆,曲线等)、嵌入式外部对象(PNG、JPEG、SVG 等)和文字对象。SVG 最终的文件格式是文本,对开发人员来说具有良好的可读性和可扩展性。平均来讲,SVG 文件的大小要小于 JPEG 等其他的网络图形格式,而且 SVG 支持利用 gzip 压缩算法进行压缩从而获得很大的压缩比,压缩后生成的文件格式为 SVGZ。因为 SVG 中的矢量显示对象是被描述出来的,所以支持无损的放大缩小,而对于那些栅格图形格式,如 BMP,JPEG 等,放大或是缩小需要利用数值算法进行插值而造成失真。SVG 图形格式支持文字对象,可以很方便的建立文字索引,进而实现基于内容的图像搜索。SVG 格式支持多种滤镜和特殊效果,如给文字内容加上阴影。此外,最重要的一点是 SVG 具有良好的动态性,一方面自身的有基于 SMIL(Synchronized Multimedia Integration Language,同步多媒体集成语言)标准的动态内容;另一方面可以利用 JavaScript 脚本来控制对象,来提供良好的互动。SVG 的这些特性使其得到了广泛的支持和应用。
SVG 通过多种标签元素来构成整个的矢量图形,包括根元素 svg,图形对象:rect(矩形)、circle(圆)、ellipse(椭圆)、line(线)、polygon(多边形)、polyline(多直线图形)、path(路径生成图形)等。滤镜效果:feBlend、feColorMatrix、feComponentTransfer、feComposite、feConvolveMatrix 等,渐变效果:线性渐变和径向渐变。SVG 文档一般是以独立的文件存在的,并且以 .svg 作为扩展名,如果是 GZIP 压缩过的文件则以 .svgz 作为扩展名。下面的清单 2 是一个 SVG 静态图形文件的例子,其中先是定义了一个高斯滤镜的效果和一个线性梯度的效果,随后定义了一个正方形和一个椭圆,将已定义线性梯度应用于前者,高斯滤镜应用于后者。将清单 2 中的内容保存到一个文本文件并以 svg 作为扩展名,用 1.5 以上版本的 Firefox 浏览器打开,就会看到图 3 中所示的内容。
清单 2. SVG 静态图形的文件<svg version="1.1" xmlns="http://www.w3.org/2000/svg" > <defs> <filter> <feGaussianBlur in="SourceGraphic" stdDeviation="5"/> </filter> <linearGradient x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%"/> <stop offset="100%"/> </linearGradient> </defs> <rect x="12" y="12"/> <ellipse cx="240" cy="100" rx="100" ry="50"/> </svg>
图 3. SVG 静态图形在 Firefox 浏览器中的展现上面的例子是用 Firefox 直接打开 SVG 文档文件来浏览,但是在一般的 Web 应用中,更多的情况是将 SVG 文档嵌入到 HTML 页面中,在浏览器渲染页面的时候直接将 SVG 的图像渲染到展现页面上。将 SVG 图形嵌入 HTML 页有四种方式:通过 object 标签,通过 embed 标签,通过 iframe 标签和直接将 SVG 的内容嵌入到页面中。然而,现在支持 SVG 的主流的浏览器包括 Firefox、Safari 等不支持将 SVG 内容直接嵌入的方式,对另外三种方式基本能够支持。清单 3 给出了利用 object 标签、embed 标签和 iframe 标签将上面的 SVG 文档嵌入 HTML 页面的例子。图 4 给出了这个 HTML 文档在 Firefox 上的展现结果。
清单 3. 嵌入 SVG 文档的 HTML 页面<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>SVG as embedded object and nested namespace</title> </head> <body> <h2>Object</h2> <object type="image/svg+xml" data="svg1.svg" ></object> <h2>IFrame</h2> <iframe src ="svg1.svg" width ="500" height ="200" frameborder="no"></iframe> <h2>Embed</h2> <embed src="svg1.svg" /> </body> </html>
图 4. Firefox 打开的嵌入 SVG 文档的 HTML 页面SVG 支持的动态特性既包括 SVG 图像自身的动画也包括 SVG 图像的各种交互功能。SVG 的动画是 SVG 规范中的特性,使用不同的标签元素来声明,它们中有一部分是在 SMIL 定义的,如 animate、set、animateMotion 和 animateColor,剩下的则是 SVG 标准扩展的,如 animateTransform。另外,SVG 还为 animateMotion 标签元素添加了三个属性:path、keyPoints、rotate,以及一个子标签元素 mpath。在下面的例子中,我们将用 animate 和 set 来实现一些效果。animate 允许一个图形元素的某个属性的值在一段时间内等量的变化,而 set 则是在一段时间内将值赋给某个属性,具体如清单 4 中的代码所示。由于 Firefox3. 版本不支持 SVG 的动画,所以这段文档中动画需要用其他支持 SVG 动画的浏览器如 Safari 或是安装 SVG Viewer 才可浏览。
清单 4. 加入动画效果的 SVG 文档<svg version="1.1" xmlns="http://www.w3.org/2000/svg" > <defs> <linearGradient x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%"/> <stop offset="100%"/> </linearGradient> </defs> <rect x="12" y="12"> <animate attributeName="width" to="300" dur="5s" fill="freeze"/> <animate attributeName="width" to="100" begin="5s" dur="5s" fill="freeze"/> <set attributeName="fill" to="yellow" begin="3s" dur="4s"/> </rect> </svg>
SVG 图像的交互包括 SVG 中的链接、事件响应以及脚本支持。SVG 中的每一个图形对象都可以包装在不同的链接标签里面。与 HTML 中的链接的标签相同,SVG 也使用 <a> 来表示链接,将其与一个 xlink:href 属性结合就可以建立一个链接。<a> 和 </a> 标签之间的所有内容作为链接点。SVG 标准支持鼠标和键盘事件,可以在 XML 描述文档中直接定义对这些事件的监听和响应,这些响应一般是某个动画设定,通过上文提到的 set、animate 等来实现。虽然通过 SVG 的 XML 元素已经可以实现一定的动画效果和事件响应,但如果想要实现更复杂的逻辑就需要脚本的支持。SVG 支持通过 JavaScript 脚本访问 SVG 文档构成的 DOM 节点树,查询、修改 DOM 节点的属性,调用其公开的方法,监听其发布的事件。JavaScript 脚本可以通过 script 元素直接嵌入到 SVG 文档中或是通过 script 的 xlink:href 来从外部脚本文件引入。清单 5 中给出的例子是在清单 4 的基础上加入了些 JavaScript 脚本,实现了对原正方形的矢量图形的鼠标单击事件的响应。这个事件处理的函数中进行了一些节点添加和删除的操作:将包含“IBM”文本的 Text 节点删掉,创建了一个包含“BTT”文本的 Text 节点并添加到 SVG 的 DOM 树中。
清单 5. 加入 JavaScript 脚本的 SVG 文档