<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Power by Result Search &#187; svg</title>
	<atom:link href="http://www.result-search.com/sty/category/technology/svg/feed" rel="self" type="application/rss+xml" />
	<link>http://www.result-search.com/sty</link>
	<description>Just another weblog</description>
	<lastBuildDate>Wed, 23 Jun 2010 03:12:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>svg 教程</title>
		<link>http://www.result-search.com/sty/2009/04/23/svg-tutorial.html</link>
		<comments>http://www.result-search.com/sty/2009/04/23/svg-tutorial.html#comments</comments>
		<pubDate>Thu, 23 Apr 2009 06:04:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[svg]]></category>

		<guid isPermaLink="false">http://www.yaaahaaa.com/2009/04/23/svg-%e6%95%99%e7%a8%8b/</guid>
		<description><![CDATA[ 本教程适用于那些希望使用可伸缩向量图形（SVG） 创建交互式 SVG 图形并使用 XSLT 从 XML 文件产生这样的 SVG 图像的开发人员。它讨论了 ECMAScript（JavaScript）的用法，ECMAScript 支持用户在不必重新装入浏览器页面的情况下与现有的 SVG 图像进行实时交互并对其进行更改。本教程还演示了 SVG 元素上的链接。
本教程是关于什么的？
SVG 是一个功能强大的可视化工具，它非常适合于显示以 XML 格式保存的数据。本教程演示了如何用 SVG 显示一个简化的交互式楼层平面图。在本教程中，JavaScript 在 SVG 图像中提供了交互性，它支持 Web 页面的访问者缩放图像、在房间之间滚动以及执行其它功能。本教程包括：

创建最初的 SVG 图像
缩放图像
使用 JavaScript 将图像从一个房间滚动到另一个房间
删除 SVG 元素
添加新的 SVG 元素
从 SVG 元素链接到其它文档
使用 XSLT 动态地生成 SVG 文档

工具
本教程向您展示了如何构建 HTML、SVG 和 XSLT 文档。要学习本教程，您需要一个文本编辑器、一个 SVG 查看器和一个 XSLT 引擎：

 纯文本编辑器是创建 SVG 文件所需的唯一工具。虽然支持 XML 的文本编辑器可以检查所编写文件是否具有良好的格式和／或文件的有效性，这对于检测编码错误非常有用，但在本教程中并不是必需的。
 SVG [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"> 本教程适用于那些希望使用可伸缩向量图形（SVG） 创建交互式 SVG 图形并使用 XSLT 从 XML 文件产生这样的 SVG 图像的开发人员。它讨论了 ECMAScript（JavaScript）的用法，ECMAScript 支持用户在不必重新装入浏览器页面的情况下与现有的 SVG 图像进行实时交互并对其进行更改。本教程还演示了 SVG 元素上的链接。<br />
</span><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>本教程是关于什么的？<br />
</strong></span><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">SVG 是一个功能强大的可视化工具，它非常适合于显示以 XML 格式保存的数据。本教程演示了如何用 SVG 显示一个简化的交互式楼层平面图。在本教程中，JavaScript 在 SVG 图像中提供了交互性，它支持 Web 页面的访问者缩放图像、在房间之间滚动以及执行其它功能。本教程包括：</span></p>
<ul>
<li>创建最初的 SVG 图像</li>
<li>缩放图像</li>
<li>使用 JavaScript 将图像从一个房间滚动到另一个房间</li>
<li>删除 SVG 元素</li>
<li>添加新的 SVG 元素</li>
<li>从 SVG 元素链接到其它文档</li>
<li>使用 XSLT 动态地生成 SVG 文档</li>
</ul>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>工具<br />
</strong></span><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">本教程向您展示了如何构建 HTML、SVG 和 XSLT 文档。要学习本教程，您需要一个文本编辑器、一个 SVG 查看器和一个 XSLT 引擎：</span></p>
<ul>
<li> <strong>纯文本编辑器</strong>是创建 SVG 文件所需的唯一工具。虽然支持 XML 的文本编辑器可以检查所编写文件是否具有良好的格式和／或文件的有效性，这对于检测编码错误非常有用，但在本教程中并不是必需的。</li>
<li> <strong>SVG 查看器：</strong>在编写本文时，使用最广泛的 SVG 查看器是 Adobe 的 SVG Viewer V3.0，可以从 <a href="http://www.adobe.com/svg/viewer/install/main.html" target="_new">http://www.adobe.com/svg/viewer/install/main.html</a> 免费获得该查看器。<a href="file:///E:/download/x-iactsvg/x-iactsvg-7-2.html">参考资料</a>中列出了其它一些 SVG 查看器。</li>
<li> <strong>浏览器：</strong>Adobe 查看器可以和 Microsoft Internet Explorer 5.x 及更高版本一起很好地工作，也可以和 Netscape Navigator 4.x 及更高版本一起很好地工作。但 Adobe SVG Viewer V3 不能和 Mozilla 1.0 及更高版本一起可靠地工作，尤其当存在脚本编制的代码时。</li>
<li> <strong>XSLT 处理器：</strong>本示例使用 Saxon XSLT 处理器。可以从 <a href="http://saxon.sourceforge.net/" target="_new">http://saxon.sourceforge.net/</a> 下载该处理器。</li>
</ul>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>关于作者</strong></span></span></span></p>
<p><span><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"> Andrew Watt 是一位有志于研究 XML 技术并在这方面拥有专门技术的独立顾问。他编写了世界上第一本有关 SVG 的书 <em>Designing SVG Web Graphics</em>（New Riders 出版），他是 <em>SVG Unleashed </em>（Sams Publishing 出版）的主要作者，而且还编写了几本有关 XML 和 Web 技术方面的书。他有两个完全讨论 SVG 的网站：<a href="http://www.xmml.com/" target="_new">http://www.xmml.com/</a> 和 <a href="http://www.edititwrite.com/" target="_new">http://www.edititwrite.com/</a>，这两个网站演示了如何使用 SVG 创建一些有用的站点。可以通过 SVGDeveloper@aol.com 与  Andrew 联系。</span></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>目标</strong></span></p>
<p>本教程集中讨论了创建一个简单的楼层平面图， 用户可以访问该楼层平面图来确定计划建造的办公大楼房间的类型和大小。本教程首先讨论一个 HTML 文档，其中包含的 SVG 图像表示大楼某一楼层经过简化的楼层平面图。SVG 图像包括三个房间 － 101 室、102 室和 103 室 － 其中，在首次装入该 HTML 文档时，只能看到 102 室。要看到完整的楼层平面图，用户可以进行缩放以确定总体比例。该 HTML 文档还提供了一些控件，它们支持用户在一楼的三个房间之间进行滚动。还有一些控件允许用户更改所选房间的特征 － 本例中，将 Standard Office 更改成 Executive Office 并改回到 Standard Office。最后，用户能放大或缩小指定房间的大小。</p>
<p>一楼的每个房间还包含到同一幢大楼的二楼平面图的链接，二楼平面图具有相同的功能并具有到一楼的链接。</p>
<p>楼层平面图的功能使用 ECMAScript（JavaScript）代码来提供交互性。该代码演示了使用 HTML 页面上的 ECMAScript 来控制该页面中 SVG 图像元素的一些方面。</p>
<p>本教程最后一部分讨论了使用 XSLT 代码将源 XML 文档转换成一楼楼层平面图的 SVG 图像。</p>
<p>下面我将向您展示这个简单应用程序所包含的组件。<br />
<span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>应用程序的各组成部分</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">整个应用程序包含以下几部分：</span></p>
<ul>
<li> <strong>XML 源文档：</strong>该文档定义了 SVG 图像最初的一些特征。 它可以是静态的 XML 文件（就如这里将显示的），或者就是从数据库轻松生成的 XML。</li>
<li> <strong>XSLT 样式表：</strong>使用 XSLT 转换可以轻松地完成 XML 文档（比方说，可能是楼层平面图的 XML 文档）到那些平面图的 SVG 图像的动态转换。该应用程序还可以使用不同的样式表生成不同的显示。</li>
<li> <strong>SVG 图像：</strong>这是最终将生成的图像，它提供了用户将看到的画面。它本身是 XML 文档，可以使用 XML 编程技术（如文档对象模型（Document Object Model，DOM））来操纵它。</li>
<li> <strong>HTML 容器文档：</strong>要直接在浏览器中显示 SVG 图像，通常需要在一个 HTML 页面中嵌入该图像。 本例中，HTML 文档还包含操纵该 SVG 图像的 Javascript 代码。</li>
</ul>
<p>我首先讨论 SVG 文档本身。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>SVG 文档结构<br />
</strong></span><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">本教程使用了两个 SVG 图像 － 一个表示办公大楼的一楼部分，而第二个 SVG 图像表示二楼对应的房间。每个 SVG 图像都嵌套在 HTML 页面中。我先手工创建一楼的图像，这样我才有可以处理的对象。</span></p>
<p>SVG 图像以 <code>svg</code> 根元素开始：</p>
<pre><code style="font-size: 12px;">&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
              "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"&gt;
&lt;svg
 xmlns="http://www.w3.org/2000/svg"
<strong> width="1200px" height="250px" viewBox="0 0 400 250"</strong> id="RoomsSVG"&gt;

&lt;/svg&gt;</code></pre>
<p>请注意，名称空间的声明指定了这些 SVG 元素位于 SVG 名称空间内，编写这些元素时无需带任何名称空间的前缀。</p>
<p>整个 SVG 图像宽 1200 像素，高 250 像素，视区宽 400 像素，高 250 像素，如 <code>viewBox</code> 属性所示。<code>viewBox</code> 属性的第一和第二个值指出视区左上角位于 (0,0)。<code>viewBox</code> 属性的第三和第四个值指出视区的右下角位于 (400,250)。用户无法看到图像在该视区以外的任何部分。每个房间宽 400 像素，高 250 像素，所以刚开始时该视区只能容纳一个房间。</p>
<p>再次声明，视区只是 SVG 图像中可见的那一部分。在本教程的后面，我将使用 ECMAScript 操纵 <code>viewBox</code> 属性的内容，使得可以向左或向右滚动 SVG 图像。</p>
<p>三个房间中的每一间开始时宽 400 像素，高 250 像素，代表房间宽 40 英尺，深 25 英尺。接下来，我将向您展示如何添加这些房间</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>房间</strong></span><br />
因为这是有关 SVG 的教程，而不是有关内部装饰的教程，所以我就把每个房间表示成大小适当的矩形。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">一楼三个房间（101 室、102 室和 103 室）中每一间的 SVG 代码都遵循相同的基本模式：</span></p>
<pre><code style="font-size: 12px;">&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
              "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"&gt;
&lt;svg
 xmlns="http://www.w3.org/2000/svg"
 width="1200px" height="250px" viewBox="0 0 400 250" id="RoomsSVG"&gt;

<strong>  &lt;svg id="Room101" width="400px" height="250px" x="0px" y="0px"&gt;
    &lt;rect id="Room101Rect" width="100%" height="100%" fill="#CCCCFF"
           stroke="black" stroke-width="5"/&gt;
    &lt;text id="Room101Label" font-size="24pt" x="55px" y="100px"
           fill="black"&gt;Room 101&lt;/text&gt;
    &lt;text id="Room101Type" font-size="24pt" x="55px" y="150px"
           fill="black"&gt;Standard office&lt;/text&gt;
  &lt;/svg&gt;

  &lt;svg id="Room102" width="400px" height="250px" x="400px" y="0px"&gt;
     ...
  &lt;/svg&gt;

  &lt;svg id="Room103" width="400px" height="250px" x="800px" y="0px"&gt;
     ...
  &lt;/svg&gt;</strong>

&lt;/svg&gt;</code></pre>
<p>每个房间的代码都包含在嵌套的 <code>svg</code> 元素中，x 属性和 y 属性确定了该嵌套 <code>svg</code> 元素的位置。</p>
<p>现在回忆一下，该图像宽 1200 像素，但视区的宽只有 400 像素。下面我将使图像在视区中居中。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>使图像居中</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">请注意，最初创建 101 室时指出它应该出现在视区的左上角处：</span></p>
<pre><code style="font-size: 12px;">&lt;svg id="Room101" width="400px" height="250px" <strong>x="0px" y="0px"</strong>&gt;</code></pre>
<p>照原样不变，这意味着在装入页面时，101 室填入视区，但与此相反的是，我希望 102 室填入视区。为此，我要创建一个容器，然后把所有房间都向左移动 400 个像素：</p>
<pre><code style="font-size: 12px;">&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
              "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"&gt;
&lt;svg
 xmlns="http://www.w3.org/2000/svg"
 width="1200px" height="250px" viewBox="0 0 400 250" id="RoomsSVG"&gt;

<strong>&lt;g id="mover" transform="translate(-400,0)"&gt;</strong>
  &lt;svg id="Room101" width="400px" height="250px" x="0px" y="0px"&gt;
    &lt;rect id="Room101Rect" width="100%" height="100%" fill="#CCCCFF"
           stroke="black" stroke-width="5"/&gt;
    &lt;text id="Room101Label" font-size="24pt" x="55px" y="100px"
           fill="black"&gt;Room 101&lt;/text&gt;
    &lt;text id="Room101Type" font-size="24pt" x="55px" y="150px"
           fill="black"&gt;Standard office&lt;/text&gt;
  &lt;/svg&gt;

  &lt;svg id="Room102" width="400px" height="250px" x="400px" y="0px"&gt;
    &lt;rect id="Room102Rect" x="0" y="0" width="100%" height="100%"
           fill="#CCFFCC" stroke="black" stroke-width="5"/&gt;
    &lt;text id="Room102Label" font-size="24pt" x="55px" y="100px"
           fill="black"&gt;Room 102&lt;/text&gt;
    &lt;text id="Room102Type" font-size="24pt" x="55px" y="150px"
           fill="black"&gt;Standard office&lt;/text&gt;
  &lt;/svg&gt;

  &lt;svg id="Room103" width="400px" height="250px" x="800px" y="0px"&gt;
    &lt;rect id="Room103Rect" width="100%" height="100%" fill="#FFCC00"
           stroke="black" stroke-width="5"/&gt;
    &lt;text id="Room103Label" font-size="24pt" x="55px" y="100px"
           fill="black"&gt;Room 103&lt;/text&gt;
    &lt;text id="Room103Type" font-size="24pt" x="55px" y="150px"
           fill="black"&gt;Standard office&lt;/text&gt;
  &lt;/svg&gt;
<strong>&lt;/g&gt;</strong>

&lt;/svg&gt;</code></pre>
<p><code>g</code> 元素充当容器，所以任何指令（如 <code>translate()</code> 转换）都会应用于容器内的任何元素。最终结果是该转换把所有三个房间都向左移动 400 个像素，从而使中间的房间显示在视区中。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>添加链接</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">现在图像上唯一缺少的是从一楼的每个房间到二楼楼层平面图的链接：</span></p>
<pre><code style="font-size: 12px;">&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"&gt;
&lt;svg <strong>xmlns:xlink="http://www.w3.org/1999/xlink"</strong>
 xmlns="http://www.w3.org/2000/svg"
 width="1200px" height="250px" viewBox="0 0 400 250" id="RoomsSVG"&gt;

&lt;g id="mover" transform="translate(-400,0)"&gt;
  &lt;svg id="Room101" width="400px" height="250px" x="0px" y="0px"&gt;
    &lt;rect id="Room101Rect" width="100%" height="100%" fill="#CCCCFF"
          stroke="black" stroke-width="5"/&gt;
    &lt;text id="Room101Label" font-size="24pt" x="55px" y="100px"
          fill="black"&gt;Room 101&lt;/text&gt;
    &lt;text id="Room101Type" font-size="24pt" x="55px" y="150px"
          fill="black"&gt;Standard office&lt;/text&gt;
<strong>    &lt;a xlink:href="Rooms2ndFloor.html"&gt;&lt;text id="Room101Link"
          font-size="15pt" x="55px" y="200px"
          fill="black"&gt;Click to view 2nd Floor&lt;/text&gt;&lt;/a&gt;</strong>&lt;/svg&gt;
...
&lt;/g&gt;

&lt;/svg&gt;</code></pre>
<p>SVG 中的链接类似于 HTML 中的链接，因为它也使用了 <code>a</code> 标记和 <code>href</code> 属性。但 SVG 实际上还是引用了以前推荐的 XLink，所以该文档必须声明 <code>xlink</code> 名称空间，并将它用于 <code>href</code> 属性。否则，该链接就会象一般的 HTML 链接那样工作，如同将 SVG 图像嵌入 HTML 页面时您会看到的那样。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>HTML 容器文档</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">在这个应用程序中，通过使用 <code>embed</code> 元素将 SVG 文件嵌入到 HTML 文档 <strong>Rooms.html</strong> 中。HTML 容器文档中的大部分由 ECMAScript 组成，本教程稍后将详细描述它，但目前我们在此只讨论基本框架：</span></p>
<pre><code style="font-size: 12px;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;XMML Room Design&lt;/title&gt;

&lt;style type="text/css"&gt;
input {width: 150px;}
&lt;/style&gt;

&lt;/head&gt;

&lt;body <strong>onload="Initialize()"</strong> bgcolor="#EEEEFF"&gt;

&lt;form action=""&gt;

&lt;table width="600"&gt;
&lt;tr&gt;
   &lt;td align="center"&gt;

        &lt;h3&gt;XMML Room Design&lt;/h3&gt;
        &lt;h2&gt;Scarman Building&lt;/h2&gt;

<strong>        &lt;embed id="RoomsHere" width="400px" height="250px"
               type="image/svg+xml" src="Rooms.svg"&gt;</strong>&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;table&gt;
&lt;tr&gt;
   &lt;td colspan="4" height="40" align="center"&gt;&lt;b&gt;Current room to edit is: &lt;/b&gt;
               <strong>&lt;span id="currentRoom"&gt;&lt;/span&gt;</strong>&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;
       &lt;input type="button" <strong>onclick="goLeft=true; panDoc()" </strong>
              value="&amp;lt;&amp;lt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Scroll Left" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
       &lt;input type="button" <strong>onclick="toExec()"</strong>
               value="Make Executive Office" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
       &lt;input type="button" <strong>onclick="toStandard()"</strong>
               value="Make Standard Office" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
       &lt;input type="button" <strong>onclick="goRight=true; panDoc()" </strong>
               value="Scroll Right&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;gt;&amp;gt;" /&gt;
   &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
   &lt;td&gt;
      &lt;input type="button" <strong>onclick="zoomIn()"</strong>
               value="Zoom In" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
      &lt;input type="button" <strong>onclick="increaseHeight()"</strong>
               value="Increase Height" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
      &lt;input type="button" <strong>onclick="decreaseHeight()"</strong>
               value="Decrease Height" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
      &lt;input type="button" <strong>onclick="zoomOut()"</strong>
               value="Zoom Out" /&gt;
   &lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;/form&gt;

&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>使用非正式、但却非常有用的 <code>embed</code> 元素嵌入 SVG 图像。<code>embed</code> 元素目前是将 SVG 图像嵌入到 HTML Web 页面的最常用元素，因为在正式的 <code>object</code> 元素的浏览器实现中存在许多局限性。请注意，<code>embed</code> 元素的 <code>type</code> 属性指定了要嵌入的图像的类型为 <code>image/svg+xml</code>，这样浏览器就知道要对它做什么。</p>
<p>该文档有一个包含一些控件的简单表，用户可以使用这些控件进行向左和向右滚动、将房间的特征从“standard（标准）”房间更改成 “executive（行政）”房间然后再更改回 standard、更改活动房间的高度（即实际的深度）以及进行放大和缩小。请注意，每个 <code>button</code> 都有一个 <code>onclick</code> 属性，它指定了在用户单击各个控件时会发生的行为。 在<a href="file:///E:/download/x-iactsvg/x-iactsvg-4-1.html">查看楼层平面图</a>中您将会了解这些处理程序背后的实际脚本。</p>
<p>该文档还有一个 <code>span</code> 元素，它告知用户当前哪个房间是活动的。编制脚本确定了元素的内容。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>查看文档</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">在支持 SVG 的浏览器中打开这个 HTML 文档最初会显示中间那间房间：</span></p>
<div><img src="file:///E:/download/x-iactsvg/images/originalnoscript.gif" alt="楼层平面图的中间房间" width="600" height="525" /></div>
<div><img class="blogimg" src="http://hiphotos.baidu.com/ayiaman/pic/item/e100fe1255da8ac5c3fd7826.jpg" border="0" alt="" /></div>
<p>此时，浏览器发出出错信号，因为 <code>Initialize()</code> 函数还没有就位，但这不是问题。但是，如果没有看到这个房间，那么需要回头检查一下 SVG 查看器的安装。</p>
<div class="tmpDiv"><span><span> </span></span></div>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>视区</strong></span><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">至此，您已创建了一个图像，它比位于这个图像上面的<em>窗口</em>要大。用户可以清晰地看到 102 室，而 101 室在视区左侧，无法看到，103 室在视区右侧，也无法看到。您可以通过以下三种方法中的任一种看见它们：</span></p>
<ol>
<li> <strong>移动图像：</strong>要看到其它两个房间，可以使用 <code>transform</code> 属性移动图像，就象我们对最初的 SVG 图像所做的那样。这样做会使得图像在表示视区的<em>打开的窗口</em>下方移动。但这不是最有效的方法。</li>
<li> <strong>移动视区：</strong>不移动图像，而只是移动视区，使您希望查看的那部分图像位于视区中，这非常类似于在电话簿的某一页上移动放大镜。因为视区的实际边界由浏览器固定在某一位置，所以在用户看来似乎图像本身在移动，但实际上是视区相对于图像在移动。</li>
<li> <strong>缩放图像：</strong>除了移动图像外，也可以使图像变大或变小，以确定通过视区仍可以看到的图片区域，而视区的大小保持不变。</li>
</ol>
<p>本章中，我将向您展示如何移动视区以看到图像的各个部分，以及如何缩放图像以查看更多或更少部分。<br />
<span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>全局变量和初始化</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">您可以在浏览器装入页面时先声明全局变量和调用 <code>Initialize()</code> 函数：</span></p>
<pre><code style="font-size: 12px;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;XMML Room Design&lt;/title&gt;

&lt;style type="text/css"&gt;
input {width: 150px;}
&lt;/style&gt;

<strong>&lt;script type="text/ecmascript"&gt;

// set global variables
var htmlObj, SVGDoc, SVGRoot, viewBox, goLeft, goRight, innerSVG;
var currentSize, currentPosition, currentRoomId, currentRoomLabel;
var svgns = "http://www.w3.org/2000/svg";

function Initialize(){

   htmlObj = document.getElementById("RoomsHere");
   SVGDoc = htmlObj.getSVGDocument();
   SVGRoot = SVGDoc.documentElement;

} // end function Initialize()

&lt;/script&gt;</strong>
&lt;/head&gt;

&lt;body <strong>onload="Initialize()"</strong> bgcolor="#EEEEFF"&gt;

&lt;form action=""&gt;

&lt;table width="600"&gt;
...</code></pre>
<p><code>htmlObj</code> 变量稍后用于对访问 SVG 图像的 <code>embed</code> 元素的引用。<code>SVGDoc</code> 变量表示 SVG 图像的根节点，即主 <code>svg</code> 元素。<code>SVGRoot</code> 变量用于表示 SVG 图像的 <code>document</code> 元素。<code>viewBox</code> 变量用于保存 <code>svg</code> 元素中 <code>document</code> 元素的 <code>viewBox</code> 属性值。</p>
<p><code>svgns</code> 变量表示 SVG 名称空间的名称空间 URI，稍后在创建新元素和属性时会在脚本中用到它。</p>
<p><code>htmlObj</code> 变量使用 HTML 文档的 <code>getElementById()</code> 方法将 <code>embed</code> 元素 －</p>
<pre><code style="font-size: 12px;">&lt;embed <strong>id="RoomsHere"</strong> width="400px"
        height="250px" type="image/svg+xml" src="Rooms.svg"&gt;</code></pre>
<p>－ 标识为要分配给它的值。</p>
<p>接着，<code>getSVGDocument()</code> 方法使 SVG 文档的根节点与 <code>SVGDoc</code> 变量相关联。对 <code>SVGDoc</code> 变量的引用就是对包含在 <code>embed</code> 元素中的 SVG 图像根节点的引用。这样您就创建了一种方法，从而将 HTML 文档中的事件与表示 HTML 文档内显示的部分 SVG 图像的变量相关联。</p>
<p>最后，该脚本使 <code>SVGRoot</code> 变量与 SVG 图像的文档元素相关联。</p>
<p>在开始滚动图像时，您将需要所有这些信息。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>获取当前位置</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"><code>panDoc()</code> 函数控制向左和向右滚动：</span></p>
<pre><code style="font-size: 12px;">...
   SVGRoot = SVGDoc.documentElement;

} // end function Initialize()

<strong>function panDoc(evt){

   viewBox = SVGRoot.getAttribute('viewBox');
   var viewVals = viewBox.split(' ');
   currentPosition = parseFloat(viewVals[0]);

} // end function panDoc()</strong>

&lt;/script&gt;
...</code></pre>
<p>首先，该脚本向 <code>viewBox</code> 变量赋予 <code>svg</code> 文档元素的 <code>viewBox</code> 属性值。回忆一下，<code>SVGRoot</code> 元素表示图像的主 <code>svg</code> 元素，所以 <code>getAttribute()</code> 方法工作时就象它对任何其它 XML 文档操作一样，即检索 <code>viewBox</code> 属性的字符串值。</p>
<p>这里的难点在于 <code>viewBox</code> 实际上是一组用空格分隔的值，您只想要这组值中的第一个值，所以该脚本通过使用 ECMAScript <code>split()</code> 函数抽取出值 <code>0 0 400 250</code> 的各部分，从而创建了数组变量 <code>viewVals</code>。</p>
<p>然后 <code>parseFloat()</code> 方法转换字符串值 <code>0</code>，以便可以将它作为数字值 <code>0</code> 使用。</p>
<p>一旦您获得了当前位置，就可以更改它。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>移动视区</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">接着，确定视区应该向左移还是向右移，并相应地调整 <code>currentPosition</code>：</span></p>
<pre><code style="font-size: 12px;">...
function panDoc(evt){

   viewBox = SVGRoot.getAttribute('viewBox');
   var viewVals = viewBox.split(' ');
   currentPosition = parseFloat(viewVals[0]);

 <strong>  if (goLeft == true){
      if (currentPosition &gt; -400) {
          currentPosition = currentPosition - 200;
      }
      goLeft = false;
   }

   if (goRight == true){
     if (currentPosition &lt; 400) {
          currentPosition = currentPosition + 200;
     }
     goRight = false;
   }

   viewVals[0] = currentPosition;
   SVGRoot.setAttribute('viewBox', viewVals.join(' '));</strong>

} // end function panDoc()
...</code></pre>
<p>如果 <code>goLeft</code> 为 <code>true</code>，那么 <code>panDoc()</code> 将 <code>currentPosition</code> 的值减去 200（如果该值大于 <code>-400</code>）。这防止了 SVG 图像进一步向左滚动超出 101 室的左边界。然后将值 <code>false</code> 赋给 <code>goLeft</code> 变量。</p>
<p>同样，如果准备向右移动，那么脚本将当前位置增加 200 个像素。</p>
<p>现在请回忆一下，您正在移动的是视区，所以当前位置的新值必须返回给 <code>viewBox</code> 属性。一旦该新值已被添加回数组，<code>join()</code> 函数就把 <code>viewBox</code> 变量已更改的值重新组合在一起。然后使用 <code>setAttribute()</code> 方法将该值赋给 <code>svg</code> 元素的 <code>viewBox</code> 属性。</p>
<p>其结果是，SVG 图像仿佛沿着所期望的方向滚动 200 个像素。例如，要完全显示 101 室，用户需要在 <strong>Scroll Left</strong> 文本控件上单击两次。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>激活滚动</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">当用户单击控件时，浏览器就执行 <code>onclick</code> 属性中包含的任何 ECMAScript 代码。在 <strong>Scroll Left</strong> 和 <strong>Scroll Right</strong> 按钮这两种情况中，<code>onclick</code> 属性指定应该向全局变量赋值 <code>true</code>，而且应该调用 <code>panDoc()</code> 函数：</span></p>
<pre><code style="font-size: 12px;">...
&lt;tr&gt;
   &lt;td&gt;
       &lt;input type="button" <strong>onclick="goLeft=true; panDoc()" </strong>
           value="&amp;lt;&amp;lt;&amp;nbsp;&amp;nbsp;&amp;nbsp;<strong>Scroll Left</strong>" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
       &lt;input type="button" onclick="toExec()"
           value="Make Executive Office" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
       &lt;input type="button" onclick="toStandard()"
           value="Make Standard Office" /&gt;
   &lt;/td&gt;
   &lt;td&gt;
       &lt;input type="button" <strong>onclick="goRight=true; panDoc()" </strong>
           value="<strong>Scroll Right</strong>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;gt;&amp;gt;" /&gt;
   &lt;/td&gt;
&lt;/tr&gt;
...</code></pre>
<p>（还可以通过以下这种方法在 Adobe SVG 查看器中移动图像：按住 ALT 键，再按下鼠标左键，然后移动鼠标，但是出于本教程的目的，您需要直接控制视区移动到哪里以及移动多少。）</p>
<p>您也可以通过使图像本身变大或变小来更改通过视区所看到的图像部分。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>放大和缩小</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">这些控件还提供了放大和缩小图像的方法。当用户单击 <strong>Zoom In</strong> 按钮时，浏览器执行 <code>zoomIn()</code> 函数。 当用户单击 <strong>Zoom Out</strong> 按钮时，浏览器执行 <code>zoomOut()</code> 函数：</span></p>
<pre><code style="font-size: 12px;">...
   SVGRoot.setAttribute('viewBox', viewVals.join(' '));

} // end function panDoc()

<strong>function zoomIn(){

   if (SVGRoot.currentScale &lt; 5){
      SVGRoot.currentScale = SVGRoot.currentScale * 1.5;
   }

} // end function zoomIn

function zoomOut(){

   if (SVGRoot.currentScale &gt; 0.3){
      SVGRoot.currentScale = SVGRoot.currentScale * 0.67;
   }

} // end function zoomOut</strong>

&lt;/script&gt;
...</code></pre>
<p><code>zoomIn()</code> 函数很简单。在 <code>Initialize()</code> 函数中已经将 SVG 图像的 <code>svg</code> 文档元素赋予了 <code>SVGRoot</code> 变量，当首次装入 SVG 图像时，<code>SVGRoot</code> 变量的 <code>currentScale</code> 特性值是 1.0。</p>
<p>每次用户单击 <strong>Zoom In</strong> 按钮时，该脚本将 <code>currentScale</code> 特性值乘以 1.5，但只有在该特性的当前值小于 5 时才这样做。这样做的效果是放大 SVG 图像，或者说，如果您喜欢，就是放大该图像的各个部分。</p>
<p><code>zoomOut()</code> 函数与 <code>zoomIn()</code> 的工作方式相同，只不过其作用是缩小图像。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>缩放和平移操作</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">理解更改某个特性会对其它特性产生影响，这一 点很重要。例如，每个“滚动”操作都会让图像朝某个方向或其相反方向移动 200 个像素，所以很自然地，人们会设想，如果该图像已被缩小到常规大小的一半，那么通过一次单击操作就可以滚过宽度为 400 像素的整个房间，但事实并非如此。当比例发生变动后，会影响所有尺寸，正如您在这个图像中可以看到的：</span></p>
<div><img src="file:///E:/download/x-iactsvg/images/zoomandscroll.gif" alt="缩放和滚动的效果" width="600" height="525" /></div>
<div><img class="blogimg" src="http://hiphotos.baidu.com/ayiaman/pic/item/1a2ef635b0d7cb80a61e122d.jpg" border="0" alt="" /></div>
<div class="tmpDiv"><span><span><span><span><span><span><span><span> </span></span></span></span></span></span></span></span></div>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">既然可以控制要看到图像的哪部分，那么我将向您展示如何更改图像本身。</span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>更改房间<br />
</strong></span><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">本教程的目的是创建 SVG 楼层平面图，用户可以操纵它进行一些更改以更好地满足他或她的需要。例如，住宅构建器（home builder）可能支持用户将卧室替换成书房，或者将浴室替换成杂物间。用户也许还能拉长或缩小房间。</span></p>
<p>在本教程中，您将了解所有这些概念，我们支持用户将房间类型从 Executive Office 更改成 Standard Office，然后再改回到 Executive Office，并使房间变大或变小。要对图像作这些更改，您要改变、添加以及除去一些对象，这些对象属于 SVG 图像的文档对象模型（DOM）。</p>
<p>首先，您需要确定要更改 SVG 图像中三个房间的哪一个。</p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: medium;"><strong>确定当前房间</strong></span></p>
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;">为了明确地确定要更改哪个房间，在用户单击 <strong>Make Executive Office</strong> 或 <strong>Make Standard Office</strong> 按钮时，必须确定用户当时可以看到哪个房间。为此，您要对页面添加 <code>setCurrentRoom()</code> 函数：</span></p>
<pre><code style="font-size: 12px;">...
} // end function Initialize()

<strong>function setCurrentRoom(){

   viewBox = SVGRoot.getAttribute('viewBox');
   var viewVals = viewBox.split(' ');
   currentPosition = parseFloat(viewVals[0]);

   if (currentPosition % 400 != 0) {
      currentRoomId = null;
      currentRoomLabel = "None.  Please scroll to desired room.";
   } else if (currentPosition / 400 == 0) {
      currentRoomId = "Room102";
      currentRoomLabel = "Room 102";
   } else if (currentPosition / 400 == -1) {
      currentRoomId = "Room101";
      currentRoomLabel = "Room 101";
   } else if (currentPosition / 400 == 1) {
      currentRoomId = "Room103";
      currentRoomLabel = "Room 103";
   }

}</strong>

function panDoc(evt){
...</code></pre>
<p>这项技术与在<a href="file:///E:/download/x-iactsvg/x-iactsvg-4-3.html">获取当前位置</a>中所用的技术一样，但是现在，您正使用该信息确定当前哪个房间与视区的左边界对齐。如果没有一个房间与它对齐（正如视区离初始位置不是 400 个像素的整数倍这种情况），那么就不存在当前房间，脚本就会相应地设置 <code>currentRoomId</code> 值。在其它情况中，请注意 <code>currentRoomId</code> 值与 SVG 文档内相关 <code>id</code> 值的前缀相匹配（正如<a href="file:///E:/download/x-iactsvg/x-iactsvg-3-2.html">房间</a>中所看到的）。稍后在开始操纵文档时，将使用该信息。</p>
<p>但是除非您在适当的时间执行该函数，否则它对您没有任何好处。</p>
<div class="tmpDiv"><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"></p>
<div class="tmpDiv">
<p><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"><span style="font-family: Verdana,Arial,Helvetica; font-size: x-small;"> </span></span></span></span></div>
<p></span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.result-search.com/sty/2009/04/23/svg-tutorial.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
