SVG(可伸缩向量图形)基础教程

来源: IBM developerWorks 中国

SVG(可伸缩向量图形)基础教程  
 Written by Nicholas Chase   
2006-Jun-30

来源: IBM developerWorks 中国

简介

  • 我应该学习这个教程吗?


  本教程辅助开发人员理解可伸缩向量图形(SVG)背后的概念以将它们作为静态文档或动态生成的内容创建。

  XML 经验不是必需的,但熟悉至少一种标记语言(如 HTML)是有用的。有关基本的 XML 信息,请参阅教程 Introduction to XML 。在本教程的结束部分的单个脚本编制示例中用到了 JavaScript,不过相当简单。

  • 本教程的内容


  可伸缩向量图形(SVG)使得用文本指定出现在页面上的图像成为可能。例如,传统图形需要指定矩形的每一个像素,而 SVG 只要说明矩形存在,并指出它的大小、位置和其它属性即可。

  它的好处有很多,包括轻松地从数据库信息生成图形(如图或图表)的能力,以及向图形添加动画和交互性的能力。

  本教程演示了构建 SVG 文档必需的概念,如基本形状、路径、文本和绘制模型,还有动画和脚本编制。

  • 关于作者


  Nicholas Chase 曾参与了 Lucent Technologies、Sun Microsystems、Oracle 和 Tampa Bay Buccaneers 等公司的网站开发。Nick 曾经当过高中物理教师、低级放射性废物设施经理、在线科幻杂志编辑、多媒体工程师以及 Oracle 讲师。最近,他担任过位于美国佛罗里达州 Clearwater 的 Site Dynamics Interactive Communications 的首席技术官,他还写了三本有关 Web 开发的书,包括 Java and XML From Scratch(Que)。他喜欢倾听读者的意见,可以通过 nicholas@nicholaschase.com 与他联系。

-----------------------------------------

SVG是什么?

 

  • 向量图形与光栅图形的比较


  在万维网历史的大部分时间里,浏览器显示的图形都是光栅格式的。在光栅图像(如 GIF 或 JPEG 图像)中,文件包含图像中每个像素的颜色值。浏览器读取这些值并做出相应行动。它仅认识到单独的部分,而没有整体概念。

  总的说来,这一系统有其优势,例如忠实再现摄影图像的能力,但它在某些情形下显得不足。例如,尽管浏览器能以不同大小显示一个图像,通常会产生锯齿边缘,在这些地方,浏览器不得不为那些在原始图像中不存在的像素插入或猜测数值。此外,光栅文件格式的二进制性质使得难以(尽管不是不可能)基于数据库信息动态地创建图像,并且动画最多也仅限于“翻动书本”类型的动画,即快速连续地显示单独图像。

  向量图形,通过指定为确定每个像素的值所需的指令而不是指定这些值本身,克服了这些困难中的一部分。例如,向量图形不再为一个直径一英寸的圆提供像素值,而是告诉浏览器创建一个直径一英寸的圆,然后让浏览器(或插件)做其余事情。

  这消除了光栅图形的许多限制;使用向量图形,浏览器只要知道它必须画一个圆。如果图像需要以正常大小的三倍来显示,那么浏览器只要按正确的大小画圆而不必执行光栅图像通常的插入法。类似地,浏览器接收的指令可以更容易地与外部信息源(如应用程序和数据库)绑定,要对图像制作动画,浏览器只要接收有关如何操纵属性(如半径或颜色)的指令即可。

 

  • Web 上的向量图像


  Web 上的第一个向量图像可能是虚拟现实标记语言(VRML)图像。VRML 寻求将 HTML 的简易性带到图像创建中来,然而尽管有一些示例给人以深刻的印象,但它的本来目的是为了 3D 造型,而且它太过复杂以至于从未真正流行起来。

  接着是 Macromedia Flash 的介入。Flash 电影是用 Macromedia 的 Flash 应用程序所创建,它允许创建相当复杂的动画,并且将动画与声音和交互性绑定在一起。因为 Flash 文件主要包含有关如何创建图像的指令,所以它们比传统的 Web 电影小得多(例如 QuickTime 电影)— 而且它们可以缩放。

  但是,Flash 文件仍然是二进制文件,这使得动态创建它们比较困难(尽管不是不可能)。而且对从浏览器可以进行的脚本编制有所限制。

 

  • 使用文本定义图像


  可伸缩向量图形通过使用 XML 定义图像、动画和交互性解决了这些问题中的许多问题。浏览器读取(或者更准确地说,浏览器的插件读取)这些基于文本的指令,然后执行这些指令。例如,一个简单的 SVG 矩形图像可能看起来如下:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

<svg width="300" height="100" xmlns="http://www.w3.org/2000/svg">

<rect x="25" y="10" width="280" height="50" 
fill="red" stroke="blue" stroke-width="3"/>

</svg>

  这个文档指示浏览器创建一个矩形,并提供属性信息,如位置(x, y)、大小(height, width)、颜色(fill, stroke)和线宽(stroke-width)。(全部文档在基本 SVG 文档中讨论。)

 

  • 动画和交互性


  因为这一结构,SVG 非常适合于动画和交互性。要更改图形元素的大小、位置或颜色,脚本只要调整相应的属性即可。

  事实上,SVG 有为事件处理而专门设计的属性(很象 HTML),甚至还有特别适合于动画的元素。例如,下面这一文档创建一个在 8 秒期间沿一条特定路线来回移动并无限重复的棍状图形:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">

<!-- Box around the image -->
<rect x="1" y="1" width="498" height="298"
fill="none" stroke="blue" stroke-width="2" />

<!-- Visible path -->
<path d="M0,300 S150,100 200,200 S400,400 500,0"
fill="none" stroke="red" stroke-width="2" />

<!-- Group of elements to animate -->
<g stroke-width="5" stroke="black">

<!-- Stick figure pieces -->
<circle cx="0" cy="-45" r="10" fill="black"/>
<line x1="-20" y1="-30" x2="0" y2="-25"/>
<line x1="20" y1="-30" x2="0" y2="-25"/>
<line x1="-20" y1="0" x2="0" y2="-10"/>
<line x1="20" y1="0" x2="0" y2="-10"/>
<line x1="0" y1="-10" x2="0" y2="-45"/>

<!-- Animation controls --> 
<animateMotion path="M0,300 S150,100 200,200 S400,400 500,0" 
dur="8s" repeatCount="indefinite"
rotate="auto" />
</g>
</svg>

  因为这完全基于指令,所以一个不是艺术家的人(象本教程的作者)即使不能创造真正的艺术,也可以创建基本的图形和动画。

 

  • 动态创建图形


  SVG 基于文本的性质也允许轻松地“实时”创建图形,因为生成图形只不过是将正确的值输出到页面而已。例如,正象 Java servlet、ASP 页面或 CGI 脚本能从数据库输出数值一样,SVG 可以输出图表或图。下面的图像显示了一个既含有 HTML 表中的纯文本数据又含有 SVG 版本数据的 HTML 页面:



  创建这个 SVG 的服务器端应用程序和创建 HTML 表的一样,而且使用相同数据(缩放 1000 倍以适应页面):

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">

<!-- Box around the image -->
<rect x="0" y="25" width="450" height="120"
fill="none" stroke="blue" stroke-width="2" />

<!-- Headers -->
<text x="15" y="50">Home page</text>
<text x="15" y="75">Product info</text>
<text x="15" y="100">Contact us</text>
<text x="15" y="125">Technical support</text>

<!-- Chart elements -->
<g fill="yellow" stroke="red" stroke-width="3">
<rect x="150" y="40" height="15" width="273.993"/>
<rect x="150" y="65" height="15" width="99.932"/>
<rect x="150" y="90" height="15" width="3.228"/>
<rect x="150" y="115" height="15" width="25.242"/>
</g>

</svg>

  这只是 SVG 能力的一个示例而已。SVG 使创建动态图像就象创建动态 HTML 一样简单。另外,因为 SVG 基于 XML,所以可以用可扩展样式表语言(XSL)变换轻松地创建它。

-----------------------------------------

基本形状

  • 基本 SVG 文档


  从本质上来说,SVG 文档是 XML 文档。这就是说 SVG 文档有某些基本属性:

*所以的标记都有开始标记和结束标记,否则必须注明为空标记。空标记用反斜杠结束,如<rect />。 
*标记必须正确嵌套。 如果一个标记在另一个标记中开始,那么它也必须在那个标记中结束。例如,<g><text>Hello there!</text></g> 是正确的,但 <g><text>Hello there!</g></text> 不正确。 
*文档必须只有一个根。正如一个 <html></html> 元素包含了一个 HTML 页面的所有内容一样,一个 <svg></svg> 元素也包含一个 SVG 文档的所有内容。 
*文档应该以 XML 声明 <?xml version="1.0"?> 开始。 
*文档应该包含一个 DOCTYPE 声明, 该声明指向一个允许元素的列表。SVG 1.0 文档的 DOCTYPE 声明是: 

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>All SVG documents should have a description</desc>

<defs>
<!-- Items can be defined for later use -->
</defs>

<g>
<circle cx="100" cy="100" r="75" fill="green"/>
</g>
</svg>

  • 在HTML页面上包含SVG


  SVG 文档本身就非常有用,但在目前(目前它仍处于开发阶段)将它们添加到 Web 页面会发挥它们最大的作用。将它们添加到 Web 页面也使得在浏览器中显示它们变得更容易;根据用户系统的文件名关联的设置情况,有些浏览器会拒绝打开一个 *.svg 文件,但显示作为 Web 页面一部分的 SVG 图像将不会有问题。

  将 SVG 图像添加到 HTML 页面很简单:只要添加一个具有适当属性的 <object></object> 元素即可:

<html>
<head><title>SVG Demonstration</title></head>
<body>

<h2 style="text-align: center">SVG Demonstration</h2>

<p>A page may have other code besides the SVG image.</p>

<object type="image/svg+xml" data="MySVG.svg"
width="300" height="200">
<img src="NonSVG.gif" mce_src="NonSVG.gif" alt="SVG 图像的静态版本" />
</object>

<p>Using objects allows the browser to decide what to display.</p>

</body>
</html>

  请特别注意 <object></object> 标记上的 height 和 width 属性。如果没有指定它们,有些浏览器将不会正确显示图像。此外,浏览器在执行某些计算(最特别的是用 viewBox 缩放)会考虑这些值,因此,如果没有正确地指定它们(如简单地用大的数值显示可能出现的任何东西),它们可能会干扰图像的正确显示。

  • 基本 SVG 形状

  SVG 定义了六种基本形状,这些基本形状和路径(在路径是什么?中讨论)一道,可以组合起来形成任何可能的图像。每个基本形状都带有指定其位置和大小的属性。它们的颜色和轮廓分别由 fill 和 stroke 属性确定。这些形状是:

圆(circle):显示一个圆心在指定点、半径为指定长度的标准的圆。 
椭圆(ellipse):显示中心在指定点、长轴和短轴半径为指定长度的椭圆。 
矩形(rect):显示左上角在指定点并且高度和宽度为指定值的矩形(包括正方形)。也可以通过指定边角圆的 x 和 y 半径画成圆角矩形。 
线(line):显示两个坐标之间的连线。 
折线(polyline):显示顶点在指定点的一组线。 
多边形(polygon):类似于 polyline,但增加了从最末点到第一点的连线,从而创建了一个闭合形状。 
下面的示例演示了这些形状:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Basic shapes</desc>

<g>
<circle cx="50" cy="50" r="25" />
<ellipse cx="75" cy="125" rx="50" ry="25" />

<rect x="155" y="5" width="75" height="100"/>
<rect x="250" y="5" width="75" height="100" rx="30" ry="20" />

<line x1="0" y1="150" x2="400" y2="150" 
stroke-width="2" stroke="blue"/>

<polyline points="50,175 150,175 150,125 250,200" />
<polygon points="350,75 379,175 355,175 355,200 345,200 
345,175 321,175" />

<rect x="0" y="0" width="400" height="200" 
fill="none" stroke="red" stroke-width="3" />
</g>
</svg>



  • 添加文本


  除了形状以外,SVG 图像还可以包含文本。SVG 给予设计人员和开发人员对文本的大量控制,可以获得很好的图形效果而不必借助失去真实纹理信息的图像(*.gif 或 *.jpg 图像甚至 Flash 电影常常这么做)。

  SVG 的文本和字体能力在以添加文本开始的文本部分讨论,而现在重要的是要理解所有在传统 HTML 页面中通过级联样式表(Cascading Style Sheet)可以获得的效果,也都可以在 SVG 图像内的文本元素中得到。例如:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="125" xmlns="http://www.w3.org/2000/svg">

<desc>Basic text</desc>

<g>
<rect x="0" y="0" width="400" height="125" fill="none" 
stroke="blue" stroke-width="3"/>

<text x="10" y="50" font-size="30">Welcome to the world of</text>
<text x="10" y="100" font-size="40" 
font-family="Monotype Corsiva"
fill="yellow" stroke="red">Scalable Vector Graphics!</text>
</g>
</svg>



  • 渲染顺序


  当组合多种不同元素时,正象 SVG 图像一样,重要的是牢记各项在页面上的放置顺序,因为这关系到谁“在上面”出现。在一个 HTML 页面上,使用 z-index 属性来控制这一分层效果,而对于 SVG 图像,则严格按顺序放置各项。每个后继层放置在那些已放置层的上面。

  如果指定一个元素没有填充色(使用 fill="none"),那么在它下面的各项会显现出来,就象您在这里看到的:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Overlapping shapes</desc>

<g>
<ellipse cx="125" cy="50" rx="50" ry="25" 
fill="none" stroke="black" />
<circle cx="125" cy="50" r="25" fill="dodgerblue" />
<circle cx="125" cy="50" r="10" fill="black" />

<ellipse cx="250" cy="50" rx="50" ry="25" 
fill="none" stroke="black" />
<circle cx="250" cy="50" r="25" fill="dodgerblue" />
<circle cx="250" cy="50" r="10" fill="black" />

<polygon points="65,50 185,50 185,75, 150,100 
100,100 65,75"
fill="none" stroke="purple" stroke-width="4"/>
<polygon points="190,50 310,50 310,75, 275,100 
225,100 190,75"
fill="none" stroke="purple" stroke-width="4"/> 

<line x1="65" y1="50" x2="310" y2="50" 
stroke="plum" stroke-width="2"/> 

</g>
</svg>

  请注意每个元素会覆盖在它之前出现的元素。

------------------------------------------

定义和组

  • 定义可重用部件


  通常在 SVG 图像的构建中,各部分或者是可重用的,或者不便于在图像主体内定义。在这些情况下,通常方便的做法是在文档的定义部分内(作为 <defs></defs> 元素的一部分)通过给这些部分指定以后可在图像主体中调用的标识来创建它们。

  例如,在前面一页中显示的图像有两只眼睛,每只眼睛边缘有一个眼镜镜片。这个文档可以在定义部分中定义一个镜片,然后在文档中调用它两次,而不是创建这个镜片两次(如下一页所示)。类似地,眼睛本身可以包含渐变(gradient),也应该定义这个渐变供以后引用。(在渐变中有更详细的介绍。)

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Referenced items</desc>
<defs>

<polygon id="lens" points="65,50 185,50 185,75, 150,100 
100,100 65,75"
fill="none" stroke="purple" stroke-width="4"/>

<radialGradient id="irisGradient">
<stop offset="25%" stop-color="green" />
<stop offset="100%" stop-color="dodgerblue" />
</radialGradient>

</defs>

<g>
......

  • 将定义的项作为属性使用


  如前一页中定义的多边形和渐变,预定义项的实际用法通常有两种形式。

  在这两种形式下,定义的项都通过其本地 URL(或 URI)引用。象 HTML 页面一样,id 属性创建了文档中的一个引用点。举例说来,这意味着 URI #irisGradient 引用标识为 irisGradient 的文档部分(或渐变定义)。即:可以从圆元素的 fill 属性内部引用它。

<circle cx="125" cy="50" r="25" fill="url(#irisGradient)"/>

  请注意 url() 函数的使用。

  最终代码在本节最后一页显示。请注意渐变现在用于眼睛的虹膜:



  • 将定义的项作为元素使用


  引用预定义项的第二种方法是通过用 <use/> 元素将它们链接到文档。例如:

<use xlink:href="#lens" mce_href="#lens" />

  使用定义中提供的坐标将多边形放置在页面上。

  在这里有两个重要事项要强调。首先,请注意 xlink 名称空间的使用。尽管大多数查看器没有它也将正确显示这一项,但为了保持一致,xlink 名称空间应该在 <svg></svg> 元素上定义,如下一页所示。

  其次,请注意 <use/>元素在以这种方式使用时成为了一个可以拥有自己坐标系统的容器。坐标系统在坐标系统和初始观察口(viewport) 一节中讨论,不过您可以看到一个具体的示例:第二个镜片最初用初始坐标 (190, 50) 创建,也就是相对第一个镜片偏移 125 个像素。而元素 

<use xlink:href="#lens" mce_href="#lens" x="125"/>

  在其原始位置创建第二个镜片,因为它相对于它的“容器”偏移了 125 像素。

  • 编组元素


  最后,SVG 不仅仅可以定义单个元素,这一点或许可以从前面讨论的 <radialGradient></radialGradient> 元素猜测出来。

  为兼顾可读性和方便性,将元素安排在一组中通常是个好办法。针对这一目的,SVG 提供 <g></g> 元素,它创建一个可以将元素置于其中的容器。这个容器可以用来标识元素,或提供一个公共属性(本地定义的属性将会覆盖公共属性)。例如代码

......
<g stroke="red" stroke-width="3">
<ellipse cx="125" cy="50" rx="50" ry="25" 
fill="none" stroke="black" />
<circle cx="125" cy="50" r="25" fill="url(#irisGradient)" />
<circle cx="125" cy="50" r="10" fill="black" />
</g>
......

  创建一个所有笔划都是 3 个像素宽的眼睛(因为没有元素定义笔划宽度),而除了外边框笔划外所有笔划都是红色(因为椭圆定义了笔划颜色)。



  • 组成整体


  最终的文档显示各部分是如何添加的:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<desc>Reusing items</desc>
<defs>

<polygon id="lens" points="65,50 185,50 185,75, 150,100 
100,100 65,75"
fill="none" stroke="purple" stroke-width="4"/>

<radialGradient id="irisGradient">
<stop offset="25%" stop-color="green" />
<stop offset="100%" stop-color="dodgerblue" />
</radialGradient>

<g id="eye">
<ellipse cy="50" rx="50" ry="25" 
fill="none" stroke="black"/>
<circle cy="50" r="25"/>
<circle cy="50" r="10" fill="black"/>
</g>

</defs>

<g>

<use xlink:href="#eye" mce_href="#eye" x="125" fill="url(#irisGradient)"/>
<use xlink:href="#eye" mce_href="#eye" x="250" fill="dodgerblue"/> 

<use xlink:href="#lens" mce_href="#lens"/>
<use xlink:href="#lens" mce_href="#lens" x="125"/>

<line x1="65" y1="50" x2="310" y2="50" 
stroke="plum" stroke-width="2"/> 

</g>
</svg>

  请注意可重用元素也允许每次使用不同的属性值,正如上面虹膜的例子中的填充属性所示。



--------------------
绘制

  • 笔划与填充


  整个教程到目前为止,示例已经演示了围绕对象的笔划或线以及对象内部区域的填充。这些属性实际上还有子属性,也可以设置子属性来创建不同的效果。这些属性包括:

fill:该属性指定用来填充对象内部区域的颜料。大多数情况下,该属性只是一种颜色,但它也可以是渐变或图案(会在图案中介绍)。这个值通常是关键字、颜色说明或指向预定义元素的 URI。 
fill-opacity:该属性指定元素的透明性。值的范围从完全透明(0)到完全不透明(1)。 
stroke:该属性指定元素外边框的外观。象 fill 一样,它引用颜料,尽管通常将它指定为一种简单颜色。 
stroke-width:该属性指定笔划线的宽度。 
stroke-linecap:该属性确定线末端的形状,可取的值有粗端(缺省值)、圆和正方形。 
stroke-linejoin:该属性确定对象各角的外观。允许的值有直角(缺省值)、圆和斜角,它如示例中所示将尖角的边缘“剪掉”。 
stroke-dasharray:该属性是一个整数系列(如 3、2、3、2、4、3、2 和 3),它允许对虚线中每一划的相对长度进行控制。 
stroke-opacity:类似于 fill-opacity,该属性确定元素笔划线的相对透明性。 
您可以在下面看到这些属性的一些示例:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<desc>Stroke and fill</desc>
<defs>

<linearGradient id="lineGradient">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="yellow" />
</linearGradient>

<polygon id="lens" points="65,50 185,50 185,75, 150,100 
100,100 65,75"
fill="pink" stroke="purple" stroke-width="4"
fill-opacity=".5"/>

. . . 

</defs>

<g>

. . .

<line x1="65" y1="50" x2="310" y2="50" 
stroke="plum" stroke-width="2"/> 

<!-- Box with gradient along the outside --> 
<rect x="50" y="125" width="275" height="40" fill="orange"
stroke-width="6" stroke="url(#lineGradient)" />

<!-- Purple line with rounded edges -->
<line x1="65" y1="190" x2="310" y2="190" 
stroke="purple" stroke-width="20"
stroke-linecap="round"/> 

<!-- Blue polygon with beveled corners --> 
<polygon points="50,250 100,225 300,225 200,275" stroke="blue"
fill="none" stroke-width="10" stroke-linejoin="bevel" /> 

</g>
</svg>



  • 颜色


  颜色对于 SVG 图像是极其重要的。单个颜色可以直接使用它们的 RGB 值指定,或者使用差不多 150 个颜色关键字中的一个来间接指定,该关键字也引用 RGB 值。

  RGB 值在 0 到 255 数值范围内指定一种颜色的红、绿、蓝成分的相对亮度。例如:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Colors</desc>
<defs>
</defs>

<g>

<text x="20" y="50" font-size="30">Colors can be specified</text>
<text x="20" y="100" font-size="30">by their
<tspan fill="rgb(255,0,0)">R</tspan>
<tspan fill="rgb(0,255,0)">G</tspan>
<tspan fill="rgb(0,0,255)">B</tspan>
values</text>
<text x="20" y="150" font-size="30">or by keywords such as</text>
<text x="20" y="200" font-size="30">
<tspan fill="lightsteelblue">lightsteelblue</tspan>,
</text>
<text x="20" y="250" font-size="30">
<tspan fill="mediumseagreen">mediumseagreen</tspan>,
</text>
<text x="20" y="300" font-size="30">and
<tspan fill="darkorchid">darkorchid</tspan>.
</text>

</g>
</svg>



  完整的颜色关键字列表是 SVG 建议书的第一部分,您可以在 http://www.w3.org/TR/SVG/types.html#ColorKeywords 中找到。

  • 渐变


  正象您在前面的示例中看到的,渐变提供了将颜色混合在一起的能力。渐变有两种。对于每种情况,代码都指定沿着渐变向量的颜色“停止”或颜色点,渐变到这些点就成为某种颜色。例如,指定红色在 0% 停止,白色在 50% 停止而蓝色在 100% 停止的渐变将逐渐由红色变为白色再变为蓝色,白色在渐变向量的中心。

  可以推断或者直接指定渐变向量。以线性渐变为例,假设它从要填充区域的左缘开始到右缘结束。可以用 x1、y1、x2 和 y2 属性更改这一向量。也可以(依照)使用 gradientTransform 属性对这一向量进行变换。

  以放射性渐变为例,渐变基于一个圆,可以用 cx、cy 和 r 属性调整外部圆(渐变向量终止的地方)的圆心和半径。可以使用 fx 和 fy 属性调整焦点(渐变向量起始的地方)。

  考虑下面这些线性和放射性渐变的示例:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Colors</desc>
<defs>
<linearGradient id="linear1">
<stop offset="0%" stop-color="red"/>
<stop offset="50%" stop-color="white"/>
<stop offset="100%" stop-color="blue"/>
</linearGradient>
<linearGradient id="linear2" x1="100%" y1="0%" x2="0%" 
y2="100%">
. . .
</linearGradient>
<linearGradient id="linear3" gradientTransform="rotate(90)">
. . .
</linearGradient>
<radialGradient id="radial1">
. . .
</radialGradient>
<radialGradient id="radial2" fx="225" fy="225">

. . .
</radialGradient>
<radialGradient id="radial3" cx="25%" cy="25%" r="75%">
. . .
</radialGradient>

</defs>

<g>

<!-- First row -->
<rect x="10" y="10" height="100" width="100" stroke="black" 
fill="url(#linear1)"/>
<rect x="125" y="10" height="100" width="100" stroke="black" 
fill="url(#linear2)"/>
<rect x="240" y="10" height="100" width="100" stroke="black" 
fill="url(#linear3)"/>

<!-- Second row -->
<rect x="10" y="125" height="100" width="100" stroke="black" 
fill="url(#radial1)"/>
<rect x="125" y="125" height="100" width="100" stroke="black" 
fill="url(#radial2)"/>
<rect x="240" y="125" height="100" width="100" stroke="black" 
fill="url(#radial3)"/>

</g>
</svg>



  • 图案


  用图案填充对象在很多地方与用渐变填充类似。两种情况下,都定义填充然后从填充属性内部调用它。

  定义图案与定义任何其它作为 SVG 图像一部分出现的对象相似。它有位置、高度和宽度,通常还有一个或多个包含的对象。位置是基于整个文档还是基于正在被填充的对象由 patternUnits 属性确定,该属性可以设置为 objectBoundingBox 或 userSpaceOnUse;这些属性分别设置基于对象和文档的坐标。与渐变相似,可以变换图案(使用 patternTransform 属性)。

  请考虑下面的示例:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Patterns</desc>
<defs>
<pattern id="notes" x="0" y="0" width="50" height="75" 
patternTransform="rotate(15)" 
patternUnits="userSpaceOnUse">

<ellipse cx="10" cy="30" rx="10" ry="5"/>
<line x1="20" y1="30" x2="20" y2="0" 
stroke-width="3" stroke="black"/>
<line x1="20" y1="0" x2="30" y2="5" 
stroke-width="3" stroke="black"/>

</pattern>
</defs>

<g>
<ellipse cx="175" cy="100" rx="125" ry="60" 
fill="url(#notes)" stroke="black" stroke-width="5"/>
</g>
</svg>



  • 滤镜


  也许 SVG 最强大的功能之一就是给图像添加了滤镜效果。这些效果复制了昂贵的图形操作程序中的许多效果,如光照效果和高斯模糊。对这些滤镜的完整讨论超出了本教程的范围,不过本页讨论了一些基本滤镜。

  对 SVG 图像的滤镜操作包括创建一系列滤镜原语操作,该系列中每个原语操作都有自己的目的。例如,偏移滤镜按指定信息将源图像左移或右移以及上移或下移。高斯模糊原语操作按要求对源图像进行模糊处理。

  源图像不必一定是实际的 SVG 图像。例如,它可以是前一个原语操作的结果。下面的代码将几个滤镜应用到前一页中显示的图案。

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<desc>Filters</desc>
<defs>

<filter id="dropShadow" filterUnits="userSpaceOnUse" 
x="0" y="0" width="400" height="200">
<feOffset in="SourceAlpha" dx="5" dy="5" result="offset"/>
<feGaussianBlur in="offset" stdDeviation="5" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge> 
</filter>

. . .
</defs>

<g>
<ellipse filter="url(#dropShadow)" cx="175" cy="100"
rx="125" ry="60" 
fill="url(#notes)" stroke="black" stroke-width="5"/>
</g>
</svg>

  首先,偏移滤镜将原始椭圆及其图案的 alpha 通道作为源(使用 in 属性)。alpha 通道由与图像中每个非白色像素对应的黑色像素组成,并且用 SourceAlpha 关键字指定。偏移原语操作完成处理然后将结果输出到一个由 result 属性指定的缓冲区(本例中的缓冲区名为 offset )。

  接下来,模糊原语操作接任。它将 in 参数指定的 offset 缓冲区的内容作为源。然后,它将其结果输出到 result 属性指定的名为 blur 的缓冲区。

  这时,滤镜仅由经过偏移和模糊的图像组成。如果滤镜操作到此为止,那么页面上只出现模糊处理的图像。合并原语操作取得 blur 缓冲区的内容然后将它与原始源图形合并,正如当 in 属性引用 SourceGraphic 关键字时所指定的那样。

  所有处理的结果是一幅具有阴影效果的原始图像:

--------------------
坐标和变换

  • 坐标系统和初始观察口(viewport)


  元素在整个教程中都是通过坐标定位的。现在是该讨论这些坐标所适应的系统的时候了。

  当首次访问文档时,用户代理(在大多数情况下,即浏览器)确定图像的观察口。观察口是文档实际可见的部分并且由一个坐标系统组成,该坐标系统以左上角的点(0,0)为原点,其正的 x 轴向右而正的 y 轴向下。坐标系统中的一个像素对应观察口中的一个像素。

  有几个操作可以创建新的坐标系统。变换(接下来介绍)在被变换元素内部创建新的坐标系统,不过可以通过向文档添加另一个 <svg></svg> 元素来直接创建新的坐标系统。考虑下面的示例:具有相同 x 和 y 属性的同一元素在不同的位置显示,这是因为第二个元素实际上属于另一个坐标系统,它从第一个元素偏移 100 个像素:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Coordinates</desc>
<g>
<ellipse cx="100" cy="100" rx="75" ry="60" 
fill="pink" stroke="purple" stroke-width="5"
fill-opacity=".5"/>

<svg x="100" y="0">
<ellipse cx="100" cy="100" rx="75" ry="60" 
fill="pink" stroke="purple" stroke-width="5"
fill-opacity=".5"/>
</svg>
</g>
</svg>



  • 变换


  执行变换改变了元素所在的坐标系统,改变了它的外观。变换可以用来以数种方式改变元素的外观:

translate(x,y):该变换按指定数量偏移元素。 
scale(x, y):该变换更改元素的大小。可以分别控制 x 和 y 方向上缩放量,但如果只指定一个值,那么它将用于两个方向。 
rotate(n):该变换按指定的角度旋转元素。 
skewX(n)/ skewY(n) :这两种变换根据适当的轴按指定的像素数量偏斜元素。 
也可以使用矩阵指定变换,不过这超出了本教程的范围。

  变换是累积的,并且既可以指定为单个变换属性的一部分也可以指定为嵌套元素的一部分,如下所示:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<desc>Coordinates</desc>
<defs>
<rect id="refBox" x="0" y="0" height="100" width="100" 
stroke="purple" stroke-width="3" fill="none"/>
</defs>
<g>
<!-- Top lines -->
<g transform="scale(1, .5) translate(0, 50)">
<path stroke="purple" stroke-width="3" 
d="M25 50 L 125 5 L 225 50" fill="none"/>
</g>

<!-- Left box -->
<use xlink:href="#refBox" mce_href="#refBox" 
transform="translate(25, 50) skewY(15)"/>

<!-- Right box -->
<g transform="translate(25,25)">
<g transform="skewY(-15)">
<g transform="translate(100, 79)">
<use xlink:href="#refBox" mce_href="#refBox"/>
</g>
</g>
</g>

<!-- Text along the side -->
<g transform="rotate(90) translate(0, -250)">
<text font-size="35">Transform!</text>
</g>

</g>
</svg>

  在这个示例中要注意的可能最重要的事就是正在变换的是实际坐标系统。对象本身实际上没有变换,但它所在的坐标系统中的更改使它看起来发生变化。考虑上面的“Transform!”文本。现在正在沿 y 方向将它平移负 250 个像素,因此显而易见文本应该消失,它会在观察口顶部以上显示。然而在平移发生前,坐标系统进行了 90 度旋转,所以负的 y 值实际上使文本向右移动了 250 个像素。



  • 用 viewBox 缩放


  没有任何更改时,初始观察口指定一个大小,其左上方坐标为 0,0,右下方坐标为介于该大小值与 0,0 之间的像素数目。但有时候期望的效果是按可用的大小(不管大小是多少)而不是按图像进行缩放。那就要用到 viewBox 属性了。

  viewBox 属性重新映射观察口,它指定将在观察口左上角和右下角出现的新值。请记住:当在 Web 页面上放置 SVG 图形时,<object></object> 标记的尺寸决定观察口的大小。

  例如,如果眼睛和眼镜添加了 viewBox 属性,如下所示:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="300px" height="200px" 
viewBox="50 0 350 200" preserveAspectRatio="xMinYMin"
xmlns="http://www.w3.org/2000/svg">
<desc>ViewBox</desc>
<defs>

<linearGradient id="lineGradient">
<stop offset="0%" stop-color="red" />
<stop offset="100%" stop-color="yellow" />
</linearGradient>
. . . 

  页面会在任何分配给该图像的框内显示图像,进行适当的缩放。因此下面的 Web 页面:

<html>
<head><title>SVG Demonstration</title></head>
<body>

<object type="image/svg+xml" data="test.svg" 
height="100" width="300">
<img src="NonSVG.gif" mce_src="NonSVG.gif" alt="SVG 图像静态版本" />
</object>

<object type="image/svg+xml" data="test.svg"
height="100" width="100">
<img src="NonSVG.gif" mce_src="NonSVG.gif" alt="SVG 图像静态版本" />
</object>

<object type="image/svg+xml" data="test.svg"
height="300" width="300">
<img src="NonSVG.gif" mce_src="NonSVG.gif" alt="SVG 图像静态版本" />
</object>

</body>
</html>

  以不同大小显示该图像三次:



  preserveAspectRatio 属性确定如何实现缩放。none 值将使图像伸展以适应框,即使这样会引起图像失真。xMinYMin值(如上所示)将图像的最小 x 和 y 值与框的最小 x 和 y 值对齐。其它可能的值有 xMinYMid、xMinYMax、xMidYMin、xMidYMid(缺省值)、xMidYMax、xMaxYMin、xMaxYMid 和 xMaxYMax。

________________________
路径

  • 路径是什么?


  SVG 提供的预定义形状当然是有用的,但有时它们还不足以完成工作。特别是在这两种情况下:第一,当图像需要曲线,它不能由多边形或折线创建,第二,当动画或文本需要沿页面上的特定形状前进时。

  这就需要路径了。路径是一系列命令,用来创建作为图像一部分精确定义的形状。该形状可以是开放的(如线)或闭合的(如多边形),并可以包含一条或多条线、曲线和线段。

  最基本的路径由几条线段组成。例如:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="400"
xmlns="http://www.w3.org/2000/svg">
<desc>A simple path</desc>
<rect x="1" y="1" width="350" height="350"
fill="none" stroke="blue" />
<path d="M 100 100 L 300 50 L 300 250 L 100 300 Z"
fill="red" stroke="blue" stroke-width="3" />
</svg>

  上述代码根据提供的指令生成一个简单的多边形。这些指令如下所示:

M 100 100 :移至点 100, 100。 
L 300 50 :画一条线至点 300, 50。 
L 300 250 :画一条线至点 300, 250。 
L 100 300 :画一条线至点 100, 300。 
Z :通过将线画回到原始点闭合此形状。(更具体地说,回到最近一条“move”命令所指定的点。) 

  最终结果显示如下:



  请注意这里显示的所有命令都是大写字母,这说明这些坐标是相对于整个坐标系统的绝对坐标。使用小写字母命令则指明为相对坐标。因此命令 l 50 50 从当前点创建一条线至距当前点下方和右方各 50 像素的点,那一点可能在任何位置。

  其它简单的线命令包括作水平线的 H (或 h)和作垂直线的 V (或 v)。

  • 曲线


  路径命令可以创建三种类型的曲线:

  椭圆曲线是椭圆的一部分,也称为弧。A (或 a)命令通过指定起点、终点、x 和 y 轴半径、旋度和方向来创建它们,如下所示。

  三次贝塞尔曲线由一个起点、一个终点和两个将曲线“拖”向自己的控制点定义。C (或 c)命令(指定起点和终点)和 S (或 s)命令(假设这条曲线从最近的命令终止的地方继续)创建这些曲线。 
二次贝塞尔曲线与其三次贝塞尔曲线类似,不过仅包含一个控制点。Q(或 q)和 T(或 t)命令可以创建这些曲线。 

  下面的示例显示了一些样本弧,为了清楚除去了文本。弧命令的格式如下:

A radiusX, radiusY rotation large arc flag, sweep flag endX, endY

  因此一个半径为 50 和 25,没有旋度, 使用椭圆长轴部分以及曲线的下段,在距起点右边 50 个像素和下方 25 个像素处终止的弧将使用:

a50,25 0 1,0 50,25

  一些变体如下所示:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
xmlns="http://www.w3.org/2000/svg">
<desc>Curved paths</desc>
<rect x="1" y="1" width="398" height="300"
fill="none" stroke="blue" />

<!-- First row -->
<text x="25" y="30">Large arc flag=1</text>
<text x="25" y="45">Sweep flag=0</text>
<text x="25" y="60">Rotation=0</text>
<path d="M75,100 a50,25 0 1,0 50,25"
stroke="blue" stroke-width="5" fill="none" />

. . . 
<path d="M150,100 a50,25 0 1,1 50,25"
stroke="blue" stroke-width="5" fill="none" />

. . . 
<path d="M275,100 a50,25 -45 1,1 50,25"
stroke="blue" stroke-width="5" fill="none" /> 

<!-- Second row -->
. . . 
<path d="M100,225 a50,25 0 0,1 50,25"
stroke="blue" stroke-width="5" fill="none" />

. . . 
<path d="M225,225 a50,25 0 0,0 50,25"
stroke="blue" stroke-width="5" fill="none" /> 
</svg>

  请注意所有的弧形都有相同的起点和终点,但形状不同。



  贝塞尔曲线的形状由起点和终点以及控制点的位置确定。这些命令的格式如下:

C control1x, control1y, control2x, control2y, endx, endy
S control2x, control2y, endx, endy
Q controlx, controly, endx, endy 
T endx, endy

  对于 S 和 T 命令,假设第一个控制点为前一条曲线的第二个控制点的反射。例如:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
xmlns="http://www.w3.org/2000/svg">
<desc>Curved paths</desc>
<rect x="1" y="1" width="398" height="300"
fill="none" stroke="blue" />

<!-- First row -->
<path d="M75,100 c25,-75 50,50 100,0 s50,-50 150,50"
stroke="blue" stroke-width="5" fill="none" />

<circle cx="175" cy="100" r="5" fill="red" />
<circle cx="75" cy="100" r="5" fill="red" />
<circle cx="325" cy="150" r="5" fill="red" />

<path d="M75,225 q25,-75 100,0 t150,50"
stroke="blue" stroke-width="5" fill="none" />

<circle cx="175" cy="225" r="5" fill="red" />
<circle cx="75" cy="225" r="5" fill="red" />
<circle cx="325" cy="275" r="5" fill="red" />

</svg>



  • 标记


  标记是对路径的自然补充。它们是可以添加到线和路径起点、终点和顶点的元素。最常用的是将箭头添加到线的终点,不过可以使用任何对象。

  过程很简单:定义标记,然后使用 marker-start、marker-end 和 marker-mid 属性将其赋值给相关元素。例如:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="4cm" height="4cm" viewBox="0 0 400 400"
xmlns="http://www.w3.org/2000/svg">
<desc>Markers</desc>
<defs>
<marker id="arrow"
viewBox="0 0 10 10" refX="0" refY="5" 
markerUnits="strokeWidth" markerWidth="3" markerHeight="10"
orient="auto">

<path d="M 0 0 L 10 5 L 0 10 z" fill="yellow" stroke="black"/>

</marker>
</defs>
<rect x="1" y="1" width="398" height="300"
fill="none" stroke="blue" />

<!-- First row -->
<path d="M75,100 c25,-75 50,50 100,0 s50,-50 150,50"
stroke="purple" stroke-width="5" fill="none"
marker-start="url(#arrow)"
marker-mid="url(#arrow)"
marker-end="url(#arrow)" />

<!-- Second row -->
<path d="M75,200 c25,-75 50,50 100,0 s50,-50 150,50"
stroke="purple" stroke-width="3" fill="none"
marker-start="url(#arrow)"
marker-mid="url(#arrow)"
marker-end="url(#arrow)" />
</svg>

  这个标记本身由一个简单的三角形路径组成,它由标记属性决定。已经设置了 viewBox,以便不管框是什么,标记本身总是会填充整个框。因为 markerUnits 值的缘故,框本身受应用标记线的大小影响。markerUnits 属性也被设置为 userSpaceOnUse,这使标记使用常规坐标系统。refX 和 refY 属性确定标记(该标记“附加”到它所标记的线)内的点。最后,标记的方位设为 auto,使它的 Y 轴与线的切线垂直。(为了理解这一方位,标记构建为指向 X 轴方向)。

  请注意标记大小随笔划大小的改变而改变:



————————————————————
文本

  • 添加文本


  SVG 的强大能力之一是它可以将文本控制到标准 HTML 页面不可能有的程度,而无须求助图像或其它插件(后者会带来可访问性挑战)。任何可以在形状或路径上执行的操作(如绘制或滤镜)都可以在文本上执行。

  一个不足之处是 SVG 不执行自动换行。如果文本比允许空间长,则简单地将它切断。多数情况下,创建多行文本需要多个文本元素。

  可以使用 tspan 元素将文本元素分成几部分,允许每部分有各自的样式。在 text 元素中,空格的处理与 HTML 类似;换行和回车变成空格,而多个空格压缩成单个空格,如下面的早期示例所示:

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<desc>Text</desc>
<defs>
</defs>

<g>

<text x="20" y="50" font-size="30">
Colors can be specified
</text>
<text x="20" y="100" font-size="30">by their
<tspan fill="rgb(255,0,0)">R</tspan>
<tspan fill="rgb(0,255,0)">G</tspan>
<tspan fill="rgb(0,0,255)">B</tspan>
values</text>
<text x="20" y="150" font-size="30">
or by keywords such as
</text>
<text x="20" y="200" font-size="30">
<tspan fill="lightsteelblue">lightsteelblue</tspan>,
</text>
<text x="20" y="250" font-size="30">
<tspan fill="mediumseagreen">mediumseagreen</tspan>,
</text>
<text x="20" y="300" font-size="30">and
<tspan fill="darkorchid">darkorchid</tspan>.
</text>

</g>
</svg>



  • 使用 CSS 属性


  实际上,所有的属性(对于所有元素,不仅是文本)都可以用级联样式表与一个元素关联,并且文本的所有 CSS 属性都在 SVG 图像中可用。

  可以直接用样式属性设计元素的样式,或者引用样式表设计元素的样式。不应该解析样式表(因为它们偶尔包含会引起问题的字符),因此将它们置于 XML CDATA 节。

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">

<desc>Text</desc>
<defs>
<style type="text/css">
<![CDATA[
.abbreviation { text-decoration: underline; }
]]> 
</style>
</defs>

<g>

<text x="20" y="50" font-size="30">Colors can be specified</text>
<text x="20" y="100" font-size="30">by their
<tspan fill="rgb(255,0,0)" class="abbreviation">R</tspan>
<tspan fill="rgb(0,255,0)" class="abbreviation">G</tspan>
<tspan fill="rgb(0,0,255)" class="abbreviation">B</tspan>
values</text>
<text x="20" y="150" font-size="30">or by keywords such as</text>
<text x="20" y="200">
<tspan style="fill: lightsteelblue; font-size:30">
lightsteelblue
</tspan>,
</text>
. . .
</g>
</svg>



  • 路径上的文字


  在纯 HTML 中不可能具有的一个 SVG 能力是将文本沿路径排列。要实现这一点,需创建一个链接到预定义的路径信息的 textPath 元素:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<desc>Text on a path</desc>
<defs>
<path id="wavyPath" 
d="M75,100 c25,-75 50,50 100,0 s50,-50 150,50"/>
</defs>
<rect x="1" y="1" width="398" height="200"
fill="none" stroke="blue" />

<text x="50" y="50" font-size="14">
<textPath xlink:href="#wavyPath" mce_href="#wavyPath">
Text travels along any path that you define for it.
</textPath>
</text>

</svg>



————————————
动画和交互性

  • 控制属性


  即使在 SVG 产生以前,动画和交互性已经在 Web 上确立了牢固的地位。尽管实现可能较复杂,但是概念很简单:更改对象属性值,对象本身看起来就会改变。例如,给 x 坐标增加 50 个像素,对象就会向右移动 50 个像素。

  SVG 图像具有相同的概念,但实现却简单得多,这是由于这些能力从开始就构建到语言中。SVG 定义了专用于动画的五种元素:

animate:该元素指定一个特定属性(通过 attributeName 属性),其值在 dur 属性指定的时间内从指定为 from 属性的值变成指定为 to 属性的值。repeatCount 属性指定动画发生多少次。要使动画无限运行,请将 repeatCount 的值设置为 indefinite。动画适用于包含它的元素,因此下面的代码:

<rect x="50" y="50" width="100" height="100" 
fill="none" stroke="purple">
<animate attributeType="CSS" attributeName="stroke-width" 
from="1" to="50" dur="5s" repeatCount="indefinite" />
</rect>

  创建一个正方形,其 stroke-width 逐渐增厚到 50 像素,然后变回到 1 个像素,并再次开始循环。

  animateMotion:该元素提供一种通过指定路径移动元素的简单方法。路径数据与路径元素的 d 属性相同,但用路径元素指定。也可以用 xlink:href 将它链接到 animateMotion 元素。起点和终点由 from 和 to 属性确定,并且可以通过将 rotate 值设为 auto 来设置对象垂直对齐于路径。(也可以将 rotate 属性设为 auto-reverse 以将这个方位改变 180 度。或者可以给定一个特定角度)。如动画和交互性所示:

<animateMotion path="M0,300 S150,100 200,200 S400,400 500,0" 
dur="8s" repeatCount="indefinite" rotate="auto" /> 

  animateColor:该元素提供在一段时间内更改元素颜色的方法。例如,要创建一个在 8 秒钟内由红色变成蓝色的圆:

<circle cx="250" cy="100" r="50" fill="red">
<animateColor attributeType="CSS" attributeName="fill"
from="rgb(255,0,0)" to="rgb(0,0,255)" dur="8s"
repeatCount="indefinite"/>
</circle> 

  animateTransform:该元素在一段时间内执行变换。请记住,这些变换影响整个坐标系统,因此简单地缩放一个矩形还会导致矩形位置的变化。下面的示例不但缩放矩形,还逐渐将它返回到类似位置:

<rect x="333" y="49" width="50" height="50" fill="none" 
stroke="purple">
<animateTransform attributeName="transform" attributeType="XML"
type="scale" from="1" to="3" additive="sum"
begin="3s" dur="6s" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="translate" from="0,0" to="-222,-45" additive="sum"
begin="3s" dur="6s" fill="freeze" />
</rect>

  set:剩下的这个元素可以很容易地设置一个元素在指定时间段内的特殊属性。例如:

<circle cx="250" cy="100" r="50" fill="red">
<set attributeName="r" to="100" begin="1s" dur="5s" fill="remove" />
</circle>



  • 事件的脚本编制


  象 HTML 页面一样,可以设置 SVG 图像以捕获某些事件(如点击鼠标和滚动),并用它们启动脚本。在构建简单 SVG 图像时,可以通过属性捕获这些事件。最常用的是 onclick、onactivate、onmousedown、onmouseup、onmouseover、onmousemove、onmouseout、onload、onresize、 onunload 和 onrepeat。

  当这些事件之一被触发,就可以将事件对象本身提供给脚本,脚本反过来再用它确定哪个对象触发了该事件(也就是点击了什么对象)。然后脚本可以操纵那个对象的特性,如它的属性。

  这一示例回到了图案示例,但在此例中,当用户点击椭圆时,其填充由白色变为使用图案。

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<desc>Scripting the onclick event</desc>
<defs>

<script type="text/ecmascript"> 
<![CDATA[
function hideReveal(evt) {
var imageTarget = evt.target;
var theFill = imageTarget.getAttribute("fill");
if (theFill == 'white')
imageTarget.setAttribute("fill", "url(#notes)");
else
imageTarget.setAttribute("fill", "white");
}
]]> 
</script>

<pattern id="notes" x="0" y="0" width="50" height="75" 
patternTransform="rotate(15)" 
patternUnits="userSpaceOnUse">

<ellipse cx="10" cy="30" rx="10" ry="5"/>
<line x1="20" y1="30" x2="20" y2="0" 
stroke-width="3" stroke="black"/>
<line x1="20" y1="0" x2="30" y2="5" 
stroke-width="3" stroke="black"/>

</pattern>
</defs>

<!-- Outline the drawing area with a blue line -->
<rect x="1" y="1" width="350" height="200" fill="none" stroke="blue"/>

<ellipse οnclick="hideReveal(evt)" cx="175" cy="100" rx="125" ry="60" 
fill="url(#notes)" stroke="black" stroke-width="5"/>


</svg>



————————

结束语

  • 可伸缩向量图形概述


  可伸缩向量图形(SVG)图像是一种使用基于 XML 的文本信息创建图像的方法。这些图像可以由简单的形状(如矩形、圆)或用数学方法指定的更复杂的路径组成。然后可以将这些图像嵌入在 Web 页面中,SVG 查看器可以在那里解释它们。

  可以通过滤镜操纵属于 SVG 图像一部分的对象,以允许复杂的成像效果并且为动态创建的图形和动画提供基础。

  本教程对 SVG 作了介绍,包括以下内容:

* 创建基本文档 
* 形状 
* 路径 
* 文本处理 
* 样式 
* 颜色 
* 图案 
* 动画和脚本编制(简短介绍) 

  • 参考资料


  可伸缩向量图形提供了如此之多的功能,因此要在一个教程中全部介绍它们是不可能的。有关 SVG 及相关主题的更多信息,请参阅以下参考资料:

  要理解 XML 如何工作,请查看 developerWorks 教程 Introduction to XML。 
有关 SVG 功能和属性的完整列表,请参阅万维网联盟Scalable Vector Graphics 1.0 建议书 。 
SVG 的好处之一是可以在不同平台(包括手持设备)上创建图像的能力。要了解用于这一方面可能的 SVG 子集,请在 Mobile SVG: SVGTiny and SVGBasic 中查看 W3C 对用于小型手持设备 SVG 版本的观点。 
Doug Tidwell 在他的教程 Transforming XML into SVG 中讨论了如何从其它数据生成 SVG 图像,该教程是他对使用“可扩展样式表语言变换”来变换 XML 的研究的一部分。 
新的 SVG 工具正迅速涌现。要了解到 2001 年 11 月为止 SVG 工具的情况,请参阅 Antoine Quint 的文章SVG: Where Are We Now? 
  有关 SVG 基础的另一个介绍,请参阅 J. David Eisenberg 撰写的 An Introduction to Scalable Vector Graphics 。 
  Kip Hampton 在他的文章 Creating Scalable Vector Graphics with Perl 中研究了如何使用 CGI 生成 SVG 图像。 
  试试能够轻松提供动态电子商务应用程序的新的 IBM WebSphere Studio 开发环境。 
  Jackson West 撰写的 Real-world SVG 讨论了 SVG 使用中一些实践多于理论的方面。 
  Adobe 在 SVG Zone 中收集了大量令人印象深刻的教程和样本。 
  从 W3C 建议书获取认可的颜色关键字 ,那会为您节省一些时间。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值