<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://commons.oreilly.com/wiki/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>SVG Essentials/Animating and Scripting SVG - Revision history</title>
		<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;action=history</link>
		<description>Revision history for this page on the wiki</description>
		<language>en</language>
		<generator>MediaWiki 1.11.0</generator>
		<lastBuildDate>Fri, 24 May 2013 11:24:11 GMT</lastBuildDate>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=7377&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 13:40, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 13:40:50 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=6042&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 12:51, 7 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Fri, 07 Mar 2008 12:51:41 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=3714&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 23:40, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 23:40:39 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=3713&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 23:33, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 23:33:32 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=3255&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:52, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:52:48 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=3254&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:38, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:38:57 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Evanlenz: 1 revision(s)</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=2669&amp;oldid=prev</link>
			<description>&lt;p&gt;1 revision(s)&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:22, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:22:08 GMT</pubDate>			<dc:creator>Evanlenz</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=2668&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;←Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Revision as of 22:21, 6 March 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 45:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 45:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-1. Beginning of animation'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-1. Beginning of animation'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt235&lt;/del&gt;.png|Beginning of animation]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt235&lt;/ins&gt;.png|Beginning of animation]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 51:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 51:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-2. Ending of animation'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-2. Ending of animation'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt236&lt;/del&gt;.png|Ending of animation]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt236&lt;/ins&gt;.png|Ending of animation]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 95:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 95:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-3. Stages of multi-object animation'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-3. Stages of multi-object animation'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt237&lt;/del&gt;.png|Stages of multi-object animation]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt237&lt;/ins&gt;.png|Stages of multi-object animation]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 125:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 125:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-4. Stages of synchronized animations'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-4. Stages of synchronized animations'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt238&lt;/del&gt;.png|Stages of synchronized animations]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt238&lt;/ins&gt;.png|Stages of synchronized animations]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 275:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 275:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-5. animateTransform -- before and after'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-5. animateTransform -- before and after'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt241&lt;/del&gt;.png|animateTransform -- before and after]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt241&lt;/ins&gt;.png|animateTransform -- before and after]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 297:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 297:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-6. Multiple animateTransforms -- before and after'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-6. Multiple animateTransforms -- before and after'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt242&lt;/del&gt;.png|Multiple animateTransforms -- before and after]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt242&lt;/ins&gt;.png|Multiple animateTransforms -- before and after]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 340:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 340:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-7. animateMotion along a complex path'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-7. animateMotion along a complex path'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt243&lt;/del&gt;.png|animateMotion along a complex path]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt243&lt;/ins&gt;.png|animateMotion along a complex path]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 366:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 366:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-8. animateMotion along a complex path with auto-rotation'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-8. animateMotion along a complex path with auto-rotation'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt244&lt;/del&gt;.png|animateMotion along a complex path with auto-rotation]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt244&lt;/ins&gt;.png|animateMotion along a complex path with auto-rotation]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 484:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 484:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-9. Screenshots of different selections'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-9. Screenshots of different selections'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt245&lt;/del&gt;.png|Screenshots of different selections]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt245&lt;/ins&gt;.png|Screenshots of different selections]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 581:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 581:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-10. Screenshot of color sliders'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-10. Screenshot of color sliders'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt246&lt;/del&gt;.png|Screenshot of color sliders]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt246&lt;/ins&gt;.png|Screenshot of color sliders]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 700:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 700:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-11. Screenshot of labeled color sliders'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-11. Screenshot of labeled color sliders'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt251&lt;/del&gt;.png|Screenshot of labeled color sliders]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt251&lt;/ins&gt;.png|Screenshot of labeled color sliders]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 869:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 869:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-12. Screenshot of HTML and SVG interaction'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-12. Screenshot of HTML and SVG interaction'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt260&lt;/del&gt;.png|Screenshot of HTML and SVG interaction]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt260&lt;/ins&gt;.png|Screenshot of HTML and SVG interaction]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 879:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 879:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-13. Screenshot of two stages of scripting with animation'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-13. Screenshot of two stages of scripting with animation'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt261&lt;/del&gt;.png|Screenshot of two stages of scripting with animation]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt261&lt;/ins&gt;.png|Screenshot of two stages of scripting with animation]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1,079:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1,079:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-14. Beginning and ending of scripted path change'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;'''Figure 11-14. Beginning and ending of scripted path change'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;-&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;del style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials/I_11_tt263&lt;/del&gt;.png|Beginning and ending of scripted path change]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;[[Image:SVG &lt;ins style=&quot;color: red; font-weight: bold; text-decoration: none;&quot;&gt;Essentials_I_11_tt263&lt;/ins&gt;.png|Beginning and ending of scripted path change]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key wikicontent:diff:version:1.11a:oldid:2425:newid:2668 --&gt;
&lt;/table&gt;</description>
			<pubDate>Thu, 06 Mar 2008 22:21:01 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
		<item>
			<title>Docbook2Wiki: Initial conversion from Docbook</title>
			<link>http://commons.oreilly.com/wiki/index.php?title=SVG_Essentials/Animating_and_Scripting_SVG&amp;diff=2425&amp;oldid=prev</link>
			<description>&lt;p&gt;Initial conversion from Docbook&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SVG Essentials/TOC}}&lt;br /&gt;
Up to this point we have produced static images; once constructed, they never change. In this chapter, we will examine two methods of making graphic images move. The first method, animation, is movement that is controlled by you, the author. The second method, scripting, lets the person viewing the graphic interact with and modify the image.&lt;br /&gt;
&lt;br /&gt;
In [[SVG Essentials/Filters|Chapter 10]] we suggested that filters should be used as a means to enhance a graphic's message, not as an end in themselves. This suggestion is even more crucial with animation. Drunk with the power of animation, you will be tempted to turn your every graphic into an all-dancing, all-singing, Broadway spectacular. As long as your goal is experimentation, this is fine. If your goal is to convey a message, however, nothing is worse than gratuitous use or overuse of animation. Let me state this clearly: nobody except the company CEO is interested in repeated viewing of a spinning, flashing, color-changing, strobe-lit version of the company logo.&lt;br /&gt;
&lt;br /&gt;
In this chapter, our message ''is'' the animation, so most of our examples will be remarkably free of any content. We will, of course, avoid gratuitous and overwrought animation as much as possible.&lt;br /&gt;
&lt;br /&gt;
== Animation Basics ==&lt;br /&gt;
&lt;br /&gt;
The animation features of SVG are based on the World Wide Web Consortium's Synchronized Multimedia Integration Language Level 2 (SMIL2) specification ''http://www.w3.org/TR/smil20/''. In this system, you specify the starting and ending values of the attribute, color, motion, or transformation that you wish to animate; the time at which the animation should begin; and the duration of the animation. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-1|Example 11-1]] shows this in action.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-1. The incredible shrinking rectangle'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;rect x=&amp;quot;10&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot; height=&amp;quot;20&amp;quot; stroke=&amp;quot;black&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;     '''[1]'''&lt;br /&gt;
     &amp;lt;animate     '''[2]'''&lt;br /&gt;
         attributeName=&amp;quot;width&amp;quot;     '''[3]'''&lt;br /&gt;
         attributeType=&amp;quot;XML&amp;quot;     '''[4]'''&lt;br /&gt;
         from=&amp;quot;200&amp;quot; to=&amp;quot;20&amp;quot;     '''[5]'''&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;5s&amp;quot;     '''[6]'''&lt;br /&gt;
         fill=&amp;quot;freeze&amp;quot; /&amp;gt;     '''[7]'''&lt;br /&gt;
 &amp;lt;/rect&amp;gt;     '''[8]'''&lt;br /&gt;
             &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[1]'''&amp;lt;/tt&amp;gt; A &amp;lt;tt&amp;gt;&amp;lt;rect&amp;gt;&amp;lt;/tt&amp;gt; element ''without'' the ending &amp;lt;tt&amp;gt;/&amp;gt;&amp;lt;/tt&amp;gt;. The animation will be contained within the element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[2]'''&amp;lt;/tt&amp;gt; Begin specification of animation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[3]'''&amp;lt;/tt&amp;gt; Specify the attribute whose value should change over time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[4]'''&amp;lt;/tt&amp;gt; Width is an XML attribute in the &amp;lt;tt&amp;gt;&amp;lt;rect&amp;gt;&amp;lt;/tt&amp;gt; element. The other common value of &amp;lt;tt&amp;gt;attributeType&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;CSS&amp;lt;/tt&amp;gt;, indicating that the property we want to change is a CSS property. If you leave this off, the default value of &amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt; is used; it searches through CSS properties first and then XML attributes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[5]'''&amp;lt;/tt&amp;gt; The starting and ending values for the attribute. In this example, the starting value is 200 and the ending value is 20.&amp;lt;ref&amp;gt;There is also a &amp;lt;tt&amp;gt;by&amp;lt;/tt&amp;gt; attribute, which you may use instead of &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt;; it is an offset that is added to the starting &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; value; the result is the ending value.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[6]'''&amp;lt;/tt&amp;gt; The beginning and duration times for the animation. In this example, we measure time in seconds, specified by the &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; after the number. For more details, see [[SVG Essentials/Animating and Scripting SVG#How Time Is Measured|Section 11.2]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[7]'''&amp;lt;/tt&amp;gt; After the five-second duration, keep the attribute at its end value. If you remove this line, the attribute will return to its original value of 200 after the five-second animation has finished. This is the SMIL &amp;lt;tt&amp;gt;fill&amp;lt;/tt&amp;gt; attribute, which tells the animation engine how to fill up the remaining time. Don't confuse it with SVG's &amp;lt;tt&amp;gt;fill&amp;lt;/tt&amp;gt; attribute, which tells SVG how to paint an object.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[8]'''&amp;lt;/tt&amp;gt; We have to close the &amp;lt;tt&amp;gt;&amp;lt;rect&amp;gt;&amp;lt;/tt&amp;gt; element, since it is now a container element.&lt;br /&gt;
&lt;br /&gt;
[[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-1|Figure 11-1]] and [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-2|Figure 11-2]] show the beginning and ending stages of the animation. They can't do justice to the actual effect, so we strongly recommend that you download the Adobe SVG Viewer plugin and try the example. Type it into a file, enclosed in the appropriate &amp;lt;tt&amp;gt;&amp;lt;?xml?&amp;gt;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;&amp;lt;svg&amp;gt;&amp;lt;/tt&amp;gt; tags, and open it within your browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-1&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-1. Beginning of animation'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt235.png|Beginning of animation]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-2. Ending of animation'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt236.png|Ending of animation]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's move on to a more ambitious example. In [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-2|Example 11-2]] we'll start with a 20-by-20 green square that will grow to 250-by-200 over the space of 8 seconds. For the first three seconds, the opacity of the green will increase, then decrease for the next three seconds. Note that &amp;lt;tt&amp;gt;fill-opacity&amp;lt;/tt&amp;gt; is referred to with &amp;lt;tt&amp;gt;attributeType=&amp;quot;CSS&amp;quot;&amp;lt;/tt&amp;gt; since it was set in a &amp;lt;tt&amp;gt;style&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-2&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-2. Multiple animations on a single object'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;rect x=&amp;quot;10&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;20&amp;quot; height=&amp;quot;20&amp;quot;&lt;br /&gt;
     style=&amp;quot;stroke: black; fill: green; style: fill-opacity: 0.25;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;animate attributeName=&amp;quot;width&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
     from=&amp;quot;20&amp;quot; to=&amp;quot;250&amp;quot; begin=&amp;quot;0s&amp;quot; dur=&amp;quot;8s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;animate attributeName=&amp;quot;height&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
     from=&amp;quot;20&amp;quot; to=&amp;quot;200&amp;quot; begin=&amp;quot;0s&amp;quot; dur=&amp;quot;8s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;animate attributeName=&amp;quot;fill-opacity&amp;quot; attributeType=&amp;quot;CSS&amp;quot;&lt;br /&gt;
     from=&amp;quot;0.25&amp;quot; to=&amp;quot;1&amp;quot; begin=&amp;quot;0s&amp;quot; dur=&amp;quot;3s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;animate attributeName=&amp;quot;fill-opacity&amp;quot; attributeType=&amp;quot;CSS&amp;quot;&lt;br /&gt;
     from=&amp;quot;1&amp;quot; to=&amp;quot;0.25&amp;quot; begin=&amp;quot;3s&amp;quot; dur=&amp;quot;3s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/rect&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our last simple example, [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-3|Example 11-3]], animates a square and a circle. The square will expand from 20-by-20 to 120-by-120 over the space of eight seconds. Two seconds after the beginning of the animation, the circle's radius will start expanding from 20 to 50 over the space of four seconds. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-3|Figure 11-3]] shows a combined screenshot of the animation at four times: zero seconds, when the animation begins; two seconds, when the circle starts to grow; six seconds, when the circle finishes growing; and eight seconds, when the animation is finished.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-3. Simple animation of multiple objects'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;rect x=&amp;quot;10&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;20&amp;quot; height=&amp;quot;20&amp;quot;&lt;br /&gt;
     style=&amp;quot;stroke: black; fill: #cfc;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;width&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
          begin=&amp;quot;0s&amp;quot; dur=&amp;quot;8s&amp;quot; from=&amp;quot;20&amp;quot; to=&amp;quot;120&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;height&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
          begin=&amp;quot;0s&amp;quot; dur=&amp;quot;8s&amp;quot; from=&amp;quot;20&amp;quot; to=&amp;quot;120&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/rect&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;70&amp;quot; cy=&amp;quot;70&amp;quot; r=&amp;quot;20&amp;quot;&lt;br /&gt;
     style=&amp;quot;fill: #ccf; stroke: black;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;r&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;2s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;20&amp;quot; to=&amp;quot;50&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-3&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-3. Stages of multi-object animation'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt237.png|Stages of multi-object animation]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How Time Is Measured ==&lt;br /&gt;
&lt;br /&gt;
SVG's animation clock starts ticking when the SVG has finished loading, and it stops ticking when the user leaves the page. You may specify a beginning or duration for a particular animation segment as a numeric value in one of these ways:&lt;br /&gt;
&lt;br /&gt;
* A full clock value in hours, minutes, and seconds (&amp;lt;tt&amp;gt;1:20:23&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* A partial clock value in minutes and seconds (&amp;lt;tt&amp;gt;2:15&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* A time value followed by a &amp;quot;metric,&amp;quot; which is one of &amp;lt;tt&amp;gt;h&amp;lt;/tt&amp;gt; (hours), &amp;lt;tt&amp;gt;min&amp;lt;/tt&amp;gt; (minutes), &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; (seconds), or &amp;lt;tt&amp;gt;ms&amp;lt;/tt&amp;gt; (milliseconds), for example &amp;lt;tt&amp;gt;dur=&amp;quot;3.5s&amp;quot;&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;begin=&amp;quot;1min&amp;quot;&amp;lt;/tt&amp;gt;. If no metric is specified, the default is seconds. You may not put any whitespace between the value and the metric.&lt;br /&gt;
&lt;br /&gt;
You may also tie an animation's beginning time to the beginning or end of another animation. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-4|Example 11-4]] shows two circles; the second one will start expanding as soon as the first one has stopped shrinking. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-4|Figure 11-4]] shows the important stages of the animation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-4. Synchronization of animations'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot; style=&amp;quot;fill: #f9f; stroke: gray;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate '''id=&amp;quot;c1&amp;quot;''' attributeName=&amp;quot;r&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;30&amp;quot; to=&amp;quot;10&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;120&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;10&amp;quot; style=&amp;quot;fill: #9f9; stroke: gray;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;r&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;'''c1.end'''&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;10&amp;quot; to=&amp;quot;30&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-4&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-4. Stages of synchronized animations'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt238.png|Stages of synchronized animations]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also possible to add an offset to this synchronization. To make an animation start two seconds after another animation, you would use a construction of the form &amp;lt;tt&amp;gt;begin=&amp;quot;otherAnim.end+2s&amp;quot;&amp;lt;/tt&amp;gt;. (You may add whitespace around the plus sign.) The offset must be positive; to make an animation's start point &amp;lt;tt&amp;gt;begin=&amp;quot;otherAnim.end-2s&amp;quot;&amp;lt;/tt&amp;gt; would require the computer to look into the future, and there is no such thing as Psychic Vector Graphics. In [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-5|Example 11-5]], the second circle begins to grow one and a fourth seconds after the first circle begins shrinking.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-5. Synchronization of animations with offsets'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot; style=&amp;quot;fill: #f9f; stroke: gray;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate '''id=&amp;quot;c1&amp;quot;''' attributeName=&amp;quot;r&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;30&amp;quot; to=&amp;quot;10&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;120&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;10&amp;quot; style=&amp;quot;fill: #9f9; stroke: gray;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;r&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;'''c1.begin+1.25s'''&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;10&amp;quot; to=&amp;quot;30&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now that we know about synchronizing animations, we can introduce the &amp;lt;tt&amp;gt;end&amp;lt;/tt&amp;gt; attribute, which sets an end time for an animation. This is ''not'' a substitute for the &amp;lt;tt&amp;gt;dur&amp;lt;/tt&amp;gt; attribute! The following animation will start six seconds after the page loads, and will last for twelve seconds or until an animation named &amp;lt;tt&amp;gt;otherAnim&amp;lt;/tt&amp;gt; ends; whichever comes first.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animate attributeName=&amp;quot;width&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
     begin=&amp;quot;6s&amp;quot; dur=&amp;quot;12s&amp;quot; '''end=&amp;quot;otherAnim.end&amp;quot;'''&lt;br /&gt;
     from=&amp;quot;10&amp;quot; to=&amp;quot;100&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can, of course, set the value of &amp;lt;tt&amp;gt;end&amp;lt;/tt&amp;gt; to a number; this is useful for halting an animation partway through so that you can see if everything is in the right place. This is how we were able to create [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-3|Figure 11-3]]. The following animation starts at six seconds, and should last for twelve seconds, but is halted at nine seconds.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animate attributeName=&amp;quot;width&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
     begin=&amp;quot;6s&amp;quot; dur=&amp;quot;12s&amp;quot; '''end=&amp;quot;9s&amp;quot;'''&lt;br /&gt;
     from=&amp;quot;10&amp;quot; to=&amp;quot;100&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Repeated Action ==&lt;br /&gt;
&lt;br /&gt;
The animations we've produced so far occur exactly once; we set &amp;lt;tt&amp;gt;fill&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;freeze&amp;lt;/tt&amp;gt; to keep the final stage of the animation. If we want to have the object return to its pre-animation state, we omit the attribute. (This is equivalent to setting &amp;lt;tt&amp;gt;fill&amp;lt;/tt&amp;gt; to the default value of &amp;lt;tt&amp;gt;remove&amp;lt;/tt&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Two other attributes allow you to repeat an animation. The first of them, &amp;lt;tt&amp;gt;repeatCount&amp;lt;/tt&amp;gt;, is set to an integer value telling how many times you want a particular animation to repeat. The second, &amp;lt;tt&amp;gt;repeatDur&amp;lt;/tt&amp;gt;, is set to a time telling how long the repetition should last. If you want an animation to repeat until the user leaves the page, set either &amp;lt;tt&amp;gt;repeatCount&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;repeatDur&amp;lt;/tt&amp;gt; to the value &amp;lt;tt&amp;gt;indefinite&amp;lt;/tt&amp;gt;. The animation in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-6|Example 11-6]] shows two circles. The upper circle moves from left to right in two repetitions of five seconds each. The second circle moves from right to left for a total of eight seconds.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-6. Example of repeated animation'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot; style=&amp;quot;fill: none; stroke: red;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;cx&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;5s&amp;quot; '''repeatCount=&amp;quot;2&amp;quot;'''&lt;br /&gt;
         from=&amp;quot;60&amp;quot; to=&amp;quot;260&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;260&amp;quot; cy=&amp;quot;130&amp;quot; r=&amp;quot;30&amp;quot; style=&amp;quot;fill: #ccf; stroke: black;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;cx&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;5s&amp;quot; '''repeatDur=&amp;quot;8s&amp;quot;'''&lt;br /&gt;
         from=&amp;quot;260&amp;quot; to=&amp;quot;60&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Just as it was possible to synchronize an animation with the beginning or ending of another animation, we can tie the start of one animation to the start of a specific repetition of another animation. You give the first animation an &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;, then set the &amp;lt;tt&amp;gt;begin&amp;lt;/tt&amp;gt; of the second animation to &amp;lt;tt&amp;gt;''id''&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;.repeat(&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''count''&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;)&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;''count''&amp;lt;/tt&amp;gt; is a number beginning at zero for the first repetition. In [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-7|Example 11-7]], we have an upper circle moving from left to right three times, requiring five seconds for each repetition. The lower square will go right to left only once, and will not begin until halfway through the second repetition. (We use an offset to achieve this effect.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-7. Synchronizing an animation with a repetition'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot;&lt;br /&gt;
     style=&amp;quot;fill: none; stroke: red;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate '''id=&amp;quot;circle-anim&amp;quot;''' attributeName=&amp;quot;cx&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;5s&amp;quot; '''repeatCount=&amp;quot;3&amp;quot;'''&lt;br /&gt;
         from=&amp;quot;60&amp;quot; to=&amp;quot;260&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;rect x=&amp;quot;230&amp;quot; y=&amp;quot;100&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot;&lt;br /&gt;
     style=&amp;quot;fill: #ccf; stroke: black;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate attributeName=&amp;quot;x&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;'''circle-anim.repeat(1) + 2.5s'''&amp;quot; dur=&amp;quot;5s&amp;quot;&lt;br /&gt;
         from=&amp;quot;230&amp;quot; to=&amp;quot;30&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/rect&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The set Element ==&lt;br /&gt;
&lt;br /&gt;
All of these animations have modified numeric values over time. You may want to set a non-numeric attribute or property though. For example, you might want an initially invisible text item to become visible at a certain time; there's no real need for both a &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt;. Thus, we have the convenient shorthand of the &amp;lt;tt&amp;gt;&amp;lt;set&amp;gt;&amp;lt;/tt&amp;gt; element, which needs only a &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attribute and the proper timing information. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-8|Example 11-8]] shrinks a circle down to zero, then reveals text one-half second after the circle is gone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-8. Example of set element'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot; style=&amp;quot;fill: #ff9; stroke: gray;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animate id=&amp;quot;c1&amp;quot; attributeName=&amp;quot;r&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;30&amp;quot; to=&amp;quot;0&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;text text-anchor=&amp;quot;middle&amp;quot; x=&amp;quot;60&amp;quot; y=&amp;quot;60&amp;quot; style=&amp;quot;visibility: hidden;&amp;quot;&amp;gt;&lt;br /&gt;
     '''&amp;lt;set attributeName=&amp;quot;visibility&amp;quot; attributeType=&amp;quot;CSS&amp;quot;'''&lt;br /&gt;
 '''        to=&amp;quot;visible&amp;quot; begin=&amp;quot;4.5s&amp;quot; dur=&amp;quot;1s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;'''  &lt;br /&gt;
     All gone!&lt;br /&gt;
 &amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The animateColor Element ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;&amp;lt;animate&amp;gt;&amp;lt;/tt&amp;gt; element doesn't work with colors, since a color is not represented as a simple numeric value. Instead, the special &amp;lt;tt&amp;gt;&amp;lt;animateColor&amp;gt;&amp;lt;/tt&amp;gt; element fills that purpose. Its &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attributes are color values, as described in [[SVG Essentials/Basic Shapes|Chapter 3]], in [[SVG Essentials/Basic Shapes#stroke Color|Section 3.2.2]]. In [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-9|Example 11-9]] we animate the fill and stroke colors of a circle, changing the fill from light yellow to red and the gray outline to blue. Both animations start two seconds after the page loads; this gives you time to see the original colors.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-9&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-9. Example of animateColor'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot;&lt;br /&gt;
 	style=&amp;quot;fill: #ff9; stroke: gray; stroke-width: 10;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animateColor attributeName=&amp;quot;fill&amp;quot;&lt;br /&gt;
         begin=&amp;quot;2s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;#ff9&amp;quot; to=&amp;quot;red&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;animateColor attributeName=&amp;quot;stroke&amp;quot;&lt;br /&gt;
         begin=&amp;quot;2s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;gray&amp;quot; to=&amp;quot;blue&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
If you have several animations for a particular object, one animation can refer to the previous one with the keyword &amp;lt;tt&amp;gt;prev&amp;lt;/tt&amp;gt;. We could rewrite the preceding example as [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-10|Example 11-10]]. Tying two related animations together with &amp;lt;tt&amp;gt;prev&amp;lt;/tt&amp;gt; lets you change them both by editing just the first one.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-10&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-10. Use of the prev keyword in animation'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;60&amp;quot; cy=&amp;quot;60&amp;quot; r=&amp;quot;30&amp;quot;&lt;br /&gt;
 	style=&amp;quot;fill: #ff9; stroke: gray; stroke-width: 10;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animateColor attributeName=&amp;quot;fill&amp;quot;&lt;br /&gt;
         begin=&amp;quot;2s&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;#ff9&amp;quot; to=&amp;quot;red&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;animateColor attributeName=&amp;quot;stroke&amp;quot;&lt;br /&gt;
         begin=&amp;quot;'''prev.begin'''&amp;quot; dur=&amp;quot;4s&amp;quot; from=&amp;quot;gray&amp;quot; to=&amp;quot;blue&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/circle&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The animateTransform Element ==&lt;br /&gt;
&lt;br /&gt;
Just as &amp;lt;tt&amp;gt;&amp;lt;animate&amp;gt;&amp;lt;/tt&amp;gt; doesn't work with colors, it doesn't work with rotate, translate, scale, or skew transformations either, since they're all &amp;quot;wrapped up&amp;quot; inside the &amp;lt;tt&amp;gt;transform&amp;lt;/tt&amp;gt; attribute. The &amp;lt;tt&amp;gt;&amp;lt;animateTransform&amp;gt;&amp;lt;/tt&amp;gt; element comes to the rescue. You set its &amp;lt;tt&amp;gt;attributeName&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;transform&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute's value then specifies the transformation whose values should change (one of &amp;lt;tt&amp;gt;translate&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;scale&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;rotate&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;skewX&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;skewY&amp;lt;/tt&amp;gt;). The &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; values are specified as appropriate for the transform that you're animating.&lt;br /&gt;
&lt;br /&gt;
[[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-11|Example 11-11]] stretches a rectangle from normal scale to a scale of four times in the horizontal direction and two times in the vertical direction. Note that we've centered the rectangle around the origin so it doesn't move as it scales; we place it inside a &amp;lt;tt&amp;gt;&amp;lt;g&amp;gt;&amp;lt;/tt&amp;gt; so it can be translated to a more convenient location. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-5|Figure 11-5]] shows the beginning and end of the animation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-11&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-11. Example of animateTransform'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;g transform=&amp;quot;translate(120,60)&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;rect x=&amp;quot;-10&amp;quot; y=&amp;quot;-10&amp;quot; width=&amp;quot;20&amp;quot; height=&amp;quot;20&amp;quot;&lt;br /&gt;
     style=&amp;quot;fill: #ff9; stroke: black;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animateTransform attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         '''attributeName=&amp;quot;transform&amp;quot; type=&amp;quot;scale&amp;quot;'''&lt;br /&gt;
         from=&amp;quot;1&amp;quot; to=&amp;quot;4 2&amp;quot;&lt;br /&gt;
         begin=&amp;quot;0s&amp;quot; dur=&amp;quot;4s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
     Stretch&lt;br /&gt;
 &amp;lt;/rect&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-5&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-5. animateTransform -- before and after'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt241.png|animateTransform -- before and after]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you intend to animate more than one transformation, you must use the &amp;lt;tt&amp;gt;additive&amp;lt;/tt&amp;gt; attribute. The default value of &amp;lt;tt&amp;gt;additive&amp;lt;/tt&amp;gt; is &amp;lt;tt&amp;gt;replace&amp;lt;/tt&amp;gt;, which replaces the specified transformation in the object being animated. This won't work in a series of animations, since the second animation would override the first one. By setting &amp;lt;tt&amp;gt;additive&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, SVG will accumulate the transformations. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-12|Example 11-12]] stretches and rotates the rectangle; the before and after pictures are in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-6|Figure 11-6]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-12&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-12. Example of multiple animateTransform elements'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;rect x=&amp;quot;-10&amp;quot; y=&amp;quot;-10&amp;quot; width=&amp;quot;20&amp;quot; height=&amp;quot;20&amp;quot;&lt;br /&gt;
     style=&amp;quot;fill: #ff9; stroke: black;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animateTransform attributeName=&amp;quot;transform&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         type=&amp;quot;scale&amp;quot; from=&amp;quot;1&amp;quot; to=&amp;quot;4 2&amp;quot;&lt;br /&gt;
         '''additive=&amp;quot;sum&amp;quot;''' begin=&amp;quot;0s&amp;quot; dur=&amp;quot;4s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;animateTransform attributeName=&amp;quot;transform&amp;quot; attributeType=&amp;quot;XML&amp;quot;&lt;br /&gt;
         type=&amp;quot;rotate&amp;quot; from=&amp;quot;0&amp;quot; to=&amp;quot;45&amp;quot;&lt;br /&gt;
         '''additive=&amp;quot;sum&amp;quot;''' begin=&amp;quot;0s&amp;quot; dur=&amp;quot;4s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/rect&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-6&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-6. Multiple animateTransforms -- before and after'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt242.png|Multiple animateTransforms -- before and after]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The animateMotion Element ==&lt;br /&gt;
&lt;br /&gt;
By using &amp;lt;tt&amp;gt;translate&amp;lt;/tt&amp;gt; with the &amp;lt;tt&amp;gt;&amp;lt;animateTransform&amp;gt;&amp;lt;/tt&amp;gt; element, you can cause an object to animate along a straight-line path. The &amp;lt;tt&amp;gt;&amp;lt;animateMotion&amp;gt;&amp;lt;/tt&amp;gt; element lets you do this as well; additionally, it allows you to animate an object along an arbitrary path.&lt;br /&gt;
&lt;br /&gt;
If you insist on using &amp;lt;tt&amp;gt;&amp;lt;animateMotion&amp;gt;&amp;lt;/tt&amp;gt; for straight-line motion, you simply set the &amp;lt;tt&amp;gt;from&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;to&amp;lt;/tt&amp;gt; attributes, assigning them each a pair of (''x'', ''y'') coordinates. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-13|Example 11-13]] moves a grouped circle and rectangle from (0,0) to (60,30).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-13&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-13. Animation along a linear path'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;g&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;30&amp;quot; height=&amp;quot;30&amp;quot; style=&amp;quot;fill: #ccc;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;circle cx=&amp;quot;30&amp;quot; cy=&amp;quot;30&amp;quot; r=&amp;quot;15&amp;quot; style=&amp;quot;fill: #cfc; stroke: green;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;animateMotion from=&amp;quot;0,0&amp;quot; to=&amp;quot;60,30&amp;quot; dur=&amp;quot;4s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want a more complex path to follow, use the &amp;lt;tt&amp;gt;path&amp;lt;/tt&amp;gt; attribute instead; its value is in the same format as the &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; attribute in the &amp;lt;tt&amp;gt;&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt; element. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-14|Example 11-14]], adapted from the SVG specification, animates a triangle along a cubic Bézier curve path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-14&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-14. Animation along a complex path'''&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;lt;!-- show the path along which the triangle will move --&amp;gt;&lt;br /&gt;
 &amp;lt;path d=&amp;quot;M50,125 C 100,25 150,225, 200, 125&amp;quot;&lt;br /&gt;
         style=&amp;quot;fill: none; stroke: blue;&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;amp;lt;!-- Triangle to be moved along the motion path.&lt;br /&gt;
    It is defined with an upright orientation with the base of&lt;br /&gt;
    the triangle centered horizontally just above the origin. --&amp;gt;&lt;br /&gt;
 &amp;lt;path d=&amp;quot;M-10,-3 L10,-3 L0,-25z&amp;quot; style=&amp;quot;fill: yellow; stroke: red;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;animateMotion&lt;br /&gt;
         '''path=&amp;quot;M50,125 C 100,25 150,225, 200, 125&amp;quot;'''&lt;br /&gt;
         dur=&amp;quot;6s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/path&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-7|Figure 11-7]], the triangle stays upright throughout its entire path.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-7&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-7. animateMotion along a complex path'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt243.png|animateMotion along a complex path]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you would prefer that the object tilt so its x-axis is always parallel to the slope of the path, just add the &amp;lt;tt&amp;gt;rotate&amp;lt;/tt&amp;gt; attribute with a value of &amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt; to the &amp;lt;tt&amp;gt;&amp;lt;animateMotion&amp;gt;&amp;lt;/tt&amp;gt; element. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-15|Example 11-15]] shows the SVG and [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-8|Figure 11-8]] shows screenshots taken at various stages of the animation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-15&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-15. Animation along a complex path with auto-rotation'''&lt;br /&gt;
&lt;br /&gt;
 &amp;amp;lt;!-- show the path along which the triangle will move --&amp;gt;&lt;br /&gt;
 &amp;lt;path d=&amp;quot;M50,125 C 100,25 150,225, 200, 125&amp;quot;&lt;br /&gt;
         style=&amp;quot;fill: none; stroke: blue;&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;amp;lt;!-- Triangle to be moved along the motion path.&lt;br /&gt;
    It is defined with an upright orientation with the base of&lt;br /&gt;
    the triangle centered horizontally just above the origin. --&amp;gt;&lt;br /&gt;
 &amp;lt;path d=&amp;quot;M-10,-3 L10,-3 L0,-25z&amp;quot; style=&amp;quot;fill: yellow; stroke: red;&amp;quot; &amp;gt;&lt;br /&gt;
     &amp;lt;animateMotion&lt;br /&gt;
         '''path=&amp;quot;M50,125 C 100,25 150,225, 200, 125&amp;quot;'''&lt;br /&gt;
                '''rotate=&amp;quot;auto&amp;quot;'''&lt;br /&gt;
         dur=&amp;quot;6s&amp;quot; fill=&amp;quot;freeze&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/path&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-8&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-8. animateMotion along a complex path with auto-rotation'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt244.png|animateMotion along a complex path with auto-rotation]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Put simply, when you leave off the &amp;lt;tt&amp;gt;rotate&amp;lt;/tt&amp;gt; attribute, you get the default value of zero, and the object acts like a hot-air balloon floating along the path. If you set &amp;lt;tt&amp;gt;rotate&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;auto&amp;lt;/tt&amp;gt;, the object acts like a car on a roller coaster, tilting up and down as the path does.&lt;br /&gt;
&lt;br /&gt;
You can also set &amp;lt;tt&amp;gt;rotate&amp;lt;/tt&amp;gt; to a numeric value, which will set the rotation of the object throughout the animation. Thus, if you wanted an object rotated 45 degrees no matter what direction the path took, you'd use &amp;lt;tt&amp;gt;rotate=&amp;quot;45&amp;quot;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-15|Example 11-15]], we drew the path in blue so that it was visible, and then duplicated the path in the &amp;lt;tt&amp;gt;&amp;lt;animateMotion&amp;gt;&amp;lt;/tt&amp;gt; element. You can avoid this duplication by adding an &amp;lt;tt&amp;gt;&amp;lt;mpath&amp;gt;&amp;lt;/tt&amp;gt; element within the &amp;lt;tt&amp;gt;&amp;lt;animateMotion&amp;gt;&amp;lt;/tt&amp;gt; element. The &amp;lt;tt&amp;gt;&amp;lt;mpath&amp;gt;&amp;lt;/tt&amp;gt; will contain an &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attribute that references the path you want to use. This also comes in handy when you have one path you wish to use to animate multiple objects. Here's the preceding example, rewritten as [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-16|Example 11-16]], using &amp;lt;tt&amp;gt;&amp;lt;mpath&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-16&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-16. Motion along a complex path using mpath'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;path '''id=&amp;quot;cubicCurve&amp;quot;''' d=&amp;quot;M50,125 C 100,25 150,225, 200, 125&amp;quot;&lt;br /&gt;
         style=&amp;quot;fill: none; stroke: blue;&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;path d=&amp;quot;M-10,-3 L10,-3 L0,-25z&amp;quot; style=&amp;quot;fill: yellow; stroke: red;&amp;quot; &amp;gt;&lt;br /&gt;
     &amp;lt;animateMotion dur=&amp;quot;6s&amp;quot; rotate=&amp;quot;auto&amp;quot; fill=&amp;quot;freeze&amp;quot;&amp;gt;&lt;br /&gt;
         '''&amp;lt;mpath xlink:href=&amp;quot;#cubicCurve&amp;quot;/&amp;gt;'''&lt;br /&gt;
     &amp;lt;/animateMotion&amp;gt;&lt;br /&gt;
 &amp;lt;/path&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Using Links in SVG ==&lt;br /&gt;
&lt;br /&gt;
To this point, you, the author of the SVG document, have made all the decisions about a graphic. You decide what a static image should look like, and if there are any animations, you decide when they start and stop. In this section, we will see how to hand some of that control over to the person who is viewing your document.&lt;br /&gt;
&lt;br /&gt;
The easiest sort of interactivity to provide is linking, accomplished with the &amp;lt;tt&amp;gt;&amp;lt;a&amp;gt;&amp;lt;/tt&amp;gt; element. By enclosing a graphic in this element, it becomes active; when clicked, you go to the URL specified in the &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; attribute. You can link to another SVG file or, depending upon your environment, a web page. In [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-17|Example 11-17]], clicking the word &amp;quot;Cat&amp;quot; will link to an SVG drawing of a cat; clicking the red, green, and blue shapes will link to the World Wide Web Consortium's SVG page. All the items within the second link are individually linked to the same destination, not the entire bounding box. When you test this example and move the cursor between the shapes, you will see that those areas are not linked.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-17&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-17. Links in SVG'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;a xlink:href=&amp;quot;cat.svg&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;text x=&amp;quot;100&amp;quot; y=&amp;quot;30&amp;quot; style=&amp;quot;font-size: 12pt;&amp;quot;&amp;gt;Cat&amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;/a&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a xlink:href=&amp;quot;http://www.w3.org/SVG/&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;circle cx=&amp;quot;50&amp;quot; cy=&amp;quot;70&amp;quot; r=&amp;quot;20&amp;quot; style=&amp;quot;fill: red;&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;rect x=&amp;quot;75&amp;quot; y=&amp;quot;50&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;40&amp;quot; style=&amp;quot;fill: green;&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;path d=&amp;quot;M120 90, 140 50, 160 90 Z&amp;quot; style=&amp;quot;fill: blue;&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/a&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It's worth noting that &amp;lt;tt&amp;gt;xlink:href&amp;lt;/tt&amp;gt; has a namespace prefix; though this attribute is duplicated in the SVG specification, it belongs to the XLink specification. The SVG DTD handles the namespace declaration.&lt;br /&gt;
&lt;br /&gt;
== Scripting SVG ==&lt;br /&gt;
&lt;br /&gt;
The next step up from linking — and it's a big step — is scripting. You can write a program in ECMA Script (the European Computer Manufacturer's Association standard version of what is commonly called JavaScript) to interact with an SVG graphic. Interaction occurs when graphic objects respond to events.&lt;br /&gt;
&lt;br /&gt;
Objects can respond to mouse events associated with clicking the mouse button: &amp;lt;tt&amp;gt;click&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;mousedown&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;mouseup&amp;lt;/tt&amp;gt;;&amp;lt;ref&amp;gt;A &amp;lt;tt&amp;gt;click&amp;lt;/tt&amp;gt; event is defined as a &amp;lt;tt&amp;gt;mousedown&amp;lt;/tt&amp;gt; followed by a &amp;lt;tt&amp;gt;mouseup&amp;lt;/tt&amp;gt;; all three are different events, and cannot be used synonymously.&amp;lt;/ref&amp;gt; events associated with moving the mouse: &amp;lt;tt&amp;gt;mouseover&amp;lt;/tt&amp;gt; (the mouse pointer is within the object), &amp;lt;tt&amp;gt;mouseout&amp;lt;/tt&amp;gt; (the mouse pointer leaves the object), and &amp;lt;tt&amp;gt;mousemove&amp;lt;/tt&amp;gt;; events associated with an object's status: &amp;lt;tt&amp;gt;load&amp;lt;/tt&amp;gt; (the object has been fully parsed and is ready to render); and the non-standardized events associated with pressing keys: &amp;lt;tt&amp;gt;keydown&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;keyup&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
The names listed here are the names of the events. We'll be using attributes to specify the functions which should handle the events. These event handler attributes begin with the word &amp;lt;tt&amp;gt;on&amp;lt;/tt&amp;gt;. Thus, &amp;lt;tt&amp;gt;onclick&amp;lt;/tt&amp;gt; is an attribute whose value specifies a function that handles a &amp;lt;tt&amp;gt;click&amp;lt;/tt&amp;gt; event.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To allow an object to respond to an event, you add an &amp;lt;tt&amp;gt;on&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''eventName''&amp;lt;/tt&amp;gt; attribute to the element in question. The value of the attribute will be an ECMA Script statement, usually a function call. This function usually takes the reserved word &amp;lt;tt&amp;gt;evt&amp;lt;/tt&amp;gt; as one of its parameters. &amp;lt;tt&amp;gt;evt&amp;lt;/tt&amp;gt; has properties and methods that describe the event that has occurred. The three methods you will use most often are &amp;lt;tt&amp;gt;getTarget()&amp;lt;/tt&amp;gt;, which returns a reference to the graphic object that is responding to this event, and &amp;lt;tt&amp;gt;getClientX()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;getClientY()&amp;lt;/tt&amp;gt;, which return the ''x''- and ''y''- coordinates of the mouse when the event occurred. A value of (0,0) indicates the upper left corner of the SVG viewport. These functions return the position in the viewer window regardless of any zoom or pan that the user may have done.&lt;br /&gt;
&lt;br /&gt;
=== Changing Attributes of a Single Object ===&lt;br /&gt;
&lt;br /&gt;
The simplest type of event handling is where an event occurring on object ''X'' modifies some attribute of that object. Let's look at [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-18|Example 11-18]], which makes a circle respond to the &amp;lt;tt&amp;gt;mouseover&amp;lt;/tt&amp;gt; event by making the circle's radius larger. The circle will respond to the &amp;lt;tt&amp;gt;mouseout&amp;lt;/tt&amp;gt; event by making the radius smaller.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-18&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-18. Basic scripting -- changing a single object'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/ecmascript&amp;quot;&amp;gt;     '''[1]'''&lt;br /&gt;
 &amp;lt;![CDATA[     '''[2]'''&lt;br /&gt;
 function enlarge_circle(evt)     '''[3]'''&lt;br /&gt;
 {&lt;br /&gt;
     var circle = evt.getTarget();     '''[4]'''&lt;br /&gt;
 &lt;br /&gt;
     circle.setAttribute(&amp;quot;r&amp;quot;, 50);     '''[5]'''&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function shrink_circle(evt)     '''[6]'''&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    var circle = evt.getTarget();&lt;br /&gt;
&lt;br /&gt;
    circle.setAttribute(&amp;quot;r&amp;quot;, 25);&lt;br /&gt;
}&lt;br /&gt;
// ]]&amp;gt;     &amp;lt;/nowiki&amp;gt;'''[7]'''&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
 &amp;lt;circle cx=&amp;quot;150&amp;quot; cy=&amp;quot;100&amp;quot; r=&amp;quot;25&amp;quot; fill=&amp;quot;red&amp;quot;     '''[8]'''&lt;br /&gt;
     onmouseover=&amp;quot;enlarge_circle(evt)&amp;quot;     '''[9]'''&lt;br /&gt;
     onmouseout=&amp;quot;shrink_circle(evt)&amp;quot;/&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
 &amp;lt;text x=&amp;quot;150&amp;quot; y=&amp;quot;175&amp;quot; style=&amp;quot;text-anchor: middle;&amp;quot;&amp;gt;&lt;br /&gt;
     Mouse over the circle to change its size.&lt;br /&gt;
 &amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[1]'''&amp;lt;/tt&amp;gt; The beginning &amp;lt;tt&amp;gt;&amp;lt;script&amp;gt;&amp;lt;/tt&amp;gt; tag indicates that you are preparing to leave the world of SVG/XML and enter the ECMA Script environment. The &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute tells which scripting language you are using.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[2]'''&amp;lt;/tt&amp;gt; In XML, the less than sign introduces a tag, and the ampersand symbol is used for escaping characters (see [[SVG Essentials/The XML You Need for SVG|Appendix A]] in [[SVG Essentials/The XML You Need for SVG#Entity References|Section A.2.5]]). Since ECMA Script isn't XML, we want to turn off this special behavior. The &amp;lt;tt&amp;gt;&amp;lt;![CDATA[&amp;lt;/tt&amp;gt; tells XML to stop treating the less than and ampersand symbols as special; they become ordinary content, which is the way ECMA Script likes it. This completes our exit from the SVG/XML world and immerses us in the ECMA Script environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[3]'''&amp;lt;/tt&amp;gt; The first function, &amp;lt;tt&amp;gt;enlarge_circle&amp;lt;/tt&amp;gt;, takes one parameter; the event that triggered the call.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[4]'''&amp;lt;/tt&amp;gt; We use the &amp;lt;tt&amp;gt;evt.getTarget&amp;lt;/tt&amp;gt; to return a reference to the graphic object that triggered the event, and store it in variable &amp;lt;tt&amp;gt;circle&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[5]'''&amp;lt;/tt&amp;gt; To change an attribute of a graphic object, call the object's &amp;lt;tt&amp;gt;setAttribute&amp;lt;/tt&amp;gt; function with two parameters: the name of the attribute you wish to change, and its new value. &amp;lt;tt&amp;gt;setAttribute&amp;lt;/tt&amp;gt; is a void function; it returns no value. There is a corresponding &amp;lt;tt&amp;gt;getAttribute&amp;lt;/tt&amp;gt; function which takes as its parameter the name of the attribute; it returns a string representation of the attribute's current value. These functions are part of the DOM, or Document Object Model. The DOM is a standard API for accessing, modifying, and rearranging the elements in an XML document.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[6]'''&amp;lt;/tt&amp;gt; This function, patterned exactly like the previous one, will set the &amp;lt;tt&amp;gt;r&amp;lt;/tt&amp;gt; attribute of the event's target to 25.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[7]'''&amp;lt;/tt&amp;gt; The &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;]]&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; ends the &amp;lt;tt&amp;gt;&amp;lt;![CDATA[&amp;lt;/tt&amp;gt; on the second line of the script. It returns the less than and ampersand to their special XML status, just in time for &amp;lt;tt&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/tt&amp;gt; on the next line, which leaves ECMA Script and returns you to the SVG/XML world. The leading slashes on line 16 introduce an ECMA Script comment, ensuring that the remainder of the line is not interpreted as part of the script. (This is not necessary with version 2.0 Adobe plugin, but other XML applications may require the slashes.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[8]'''&amp;lt;/tt&amp;gt; Since we will be setting an attribute to change the color, we specify the fill color with a presentation attribute. We can't use &amp;lt;tt&amp;gt;style&amp;lt;/tt&amp;gt;, because its setting overrides the value of a presentation attribute.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[9]'''&amp;lt;/tt&amp;gt; Here is our bridge between the SVG world and the ECMA Script world. The &amp;lt;tt&amp;gt;onmouseover&amp;lt;/tt&amp;gt; event handler will call &amp;lt;tt&amp;gt;enlarge_circle&amp;lt;/tt&amp;gt;, and the &amp;lt;tt&amp;gt;onmouseout&amp;lt;/tt&amp;gt; event handler will call &amp;lt;tt&amp;gt;shrink_circle&amp;lt;/tt&amp;gt;. In this context, &amp;lt;tt&amp;gt;evt&amp;lt;/tt&amp;gt; is provided by the SVG viewer environment.&lt;br /&gt;
&lt;br /&gt;
=== Changing Attributes of Multiple Objects ===&lt;br /&gt;
&lt;br /&gt;
Sometimes you will want an event that occurs on object A to affect attributes of both object A and some other object B. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-19|Example 11-19]] shows possibly the world's crudest example of SVGcommerce. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-9|Figure 11-9]] shows a T-shirt whose size changes as the user clicks each labeled button. The currently selected size button is highlighted in light yellow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-9&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-9. Screenshots of different selections'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt245.png|Screenshots of different selections]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-19&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-19. Changing multiple objects in a script'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;svg width=&amp;quot;400&amp;quot; height=&amp;quot;250&amp;quot;  viewBox=&amp;quot;0 0 400 250&amp;quot;&lt;br /&gt;
     '''onload=&amp;quot;init(evt)&amp;quot;'''&amp;gt;     '''[1]'''&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/ecmascript&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;![CDATA[&lt;br /&gt;
 &lt;br /&gt;
 var scaleChoice = 1;     '''[2]'''&lt;br /&gt;
 var scaleFactor = new Array( 1.25, 1.5, 1.75 );&lt;br /&gt;
 &lt;br /&gt;
 function init( evt )&lt;br /&gt;
 {&lt;br /&gt;
     transformShirt();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function setScale( n )&lt;br /&gt;
 {&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;scale&amp;quot; + scaleChoice );      '''[3]'''&lt;br /&gt;
     obj.setAttribute( &amp;quot;fill&amp;quot;, &amp;quot;white&amp;quot; );&lt;br /&gt;
     scaleChoice = n;&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;scale&amp;quot; + scaleChoice );&lt;br /&gt;
     obj.setAttribute( &amp;quot;fill&amp;quot;, &amp;quot;#ffc&amp;quot; );&lt;br /&gt;
     transformShirt();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function transformShirt( )&lt;br /&gt;
 {&lt;br /&gt;
     var obj = svgDocument.getElementById( &amp;quot;shirt&amp;quot; );     '''[4]'''&amp;lt;nowiki&amp;gt;&lt;br /&gt;
    obj.setAttribute( &amp;quot;transform&amp;quot;,&lt;br /&gt;
        &amp;quot;scale(&amp;quot; + scaleFactor[scaleChoice] + &amp;quot;)&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
    obj.setAttribute( &amp;quot;stroke-width&amp;quot;,&lt;br /&gt;
        1 / scaleFactor[scaleChoice] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;defs&amp;gt;&lt;br /&gt;
    &amp;lt;path id=&amp;quot;shirt&amp;quot;      &amp;lt;/nowiki&amp;gt;'''[5]'''&lt;br /&gt;
         d=&amp;quot;M -6 -30, -32 -19, -25.5 -13, -22 -14, -22 30, 23 30,&lt;br /&gt;
             23 -14, 26.5 -13, 33 -19, 7 -30&lt;br /&gt;
             A 6.5 6 0 0 1 -6 -30&amp;quot;&lt;br /&gt;
         fill=&amp;quot;white&amp;quot; stroke=&amp;quot;black&amp;quot;/&amp;gt;     '''[6]'''&lt;br /&gt;
 &amp;lt;/defs&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;use xlink:href=&amp;quot;#shirt&amp;quot; x=&amp;quot;150&amp;quot; y=&amp;quot;150&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;g '''onclick=&amp;quot;setScale(0)&amp;quot;'''&amp;gt;     '''[7]'''&lt;br /&gt;
 &amp;lt;rect '''id=&amp;quot;scale0&amp;quot;''' x=&amp;quot;100&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;30&amp;quot; height=&amp;quot;30&amp;quot;&lt;br /&gt;
     fill=&amp;quot;white&amp;quot; stroke=&amp;quot;black&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;text x=&amp;quot;115&amp;quot; y=&amp;quot;30&amp;quot; text-anchor=&amp;quot;middle&amp;quot;&amp;gt;S&amp;lt;/text&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;g onclick=&amp;quot;setScale(1)&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;rect id=&amp;quot;scale1&amp;quot; x=&amp;quot;140&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;30&amp;quot; height=&amp;quot;30&amp;quot;&lt;br /&gt;
     fill=&amp;quot;#ffc&amp;quot; stroke=&amp;quot;black&amp;quot;/&amp;gt;      '''[8]'''&lt;br /&gt;
 &amp;lt;text x=&amp;quot;155&amp;quot; y=&amp;quot;30&amp;quot; text-anchor=&amp;quot;middle&amp;quot;&amp;gt;M&amp;lt;/text&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;g onclick=&amp;quot;setScale(2)&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;rect id=&amp;quot;scale2&amp;quot; x=&amp;quot;180&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;30&amp;quot; height=&amp;quot;30&amp;quot;&lt;br /&gt;
     fill=&amp;quot;white&amp;quot; stroke=&amp;quot;black&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;text x=&amp;quot;195&amp;quot; y=&amp;quot;30&amp;quot; text-anchor=&amp;quot;middle&amp;quot;&amp;gt;L&amp;lt;/text&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;/svg&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[1]'''&amp;lt;/tt&amp;gt; As soon as the document finishes loading, the &amp;lt;tt&amp;gt;load&amp;lt;/tt&amp;gt; event occurs, and the &amp;lt;tt&amp;gt;onload&amp;lt;/tt&amp;gt; handler will call the &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt; function, passing it the event information. Most scripts will use this event handler to make sure that all their variables are set up properly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[2]'''&amp;lt;/tt&amp;gt; This script works by keeping track of which button (S, M, or L) has been chosen, and indexing into the corresponding entry in the &amp;lt;tt&amp;gt;scaleFactor&amp;lt;/tt&amp;gt; array. The default is index number one, medium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[3]'''&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;svgDocument&amp;lt;/tt&amp;gt; is a reference to the entire SVG document, and we'll be using its properties and methods to access the parts of the document that we need. This entire script hinges on the use of the document's &amp;lt;tt&amp;gt;getElementById&amp;lt;/tt&amp;gt; function. &amp;lt;tt&amp;gt;getElementById&amp;lt;/tt&amp;gt; takes a string as its parameter, and returns the object which has that string as its &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;. The &amp;lt;tt&amp;gt;setScale&amp;lt;/tt&amp;gt; function finds the currently chosen button and turns its fill color to white. It then updates the current choice, and changes that button's fill color to light yellow. Finally, it updates the image of the shirt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[4]'''&amp;lt;/tt&amp;gt; In addition, the &amp;lt;tt&amp;gt;transformShirt&amp;lt;/tt&amp;gt; function calls on the document's &amp;lt;tt&amp;gt;getElementById&amp;lt;/tt&amp;gt; to access the graphic object with &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; of &amp;lt;tt&amp;gt;shirt&amp;lt;/tt&amp;gt;, and changes its &amp;lt;tt&amp;gt;transform&amp;lt;/tt&amp;gt; attribute to the proper scale. It also sets the &amp;lt;tt&amp;gt;stroke-width&amp;lt;/tt&amp;gt; to the reciprocal of the scaling factor so the stroke width of the shirt's border always equals one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[5]'''&amp;lt;/tt&amp;gt; Here's the shirt; it's centered around (0,0) so it will appear to expand around its center.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[6]'''&amp;lt;/tt&amp;gt; Since we're changing the attributes in the script, we have to use presentation attributes here instead of styles. (If we used styles, they would override any attribute settings.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[7]'''&amp;lt;/tt&amp;gt; Each of the buttons will call the &amp;lt;tt&amp;gt;setScale&amp;lt;/tt&amp;gt; function when clicked; the parameter gives the index for the scaling factor, and each button's &amp;lt;tt&amp;gt;&amp;lt;rect&amp;gt;&amp;lt;/tt&amp;gt; element is named with the corresponding number at the end.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[8]'''&amp;lt;/tt&amp;gt; The default button has a background set to light yellow when the document first loads.&lt;br /&gt;
&lt;br /&gt;
=== Dragging Objects ===&lt;br /&gt;
&lt;br /&gt;
Let us expand this example by adding &amp;quot;sliders&amp;quot; that can be dragged to set the color of the shirt, as shown in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-10|Figure 11-10]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-10&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-10. Screenshot of color sliders'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt246.png|Screenshot of color sliders]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We'll need a few more global variables in the script. The first of these, &amp;lt;tt&amp;gt;slideChoice&amp;lt;/tt&amp;gt;, tells which slider (0, 1, or 2) is currently being dragged; its initial value is -1, meaning that no slider is active. We'll also use an array called &amp;lt;tt&amp;gt;rgb&amp;lt;/tt&amp;gt; to hold the percent of red, green, and blue; the initial values are all 100, since the shirt is initially white.&lt;br /&gt;
&lt;br /&gt;
 var slideChoice = -1;&lt;br /&gt;
 var rgb = new Array( 100, 100, 100);&lt;br /&gt;
&lt;br /&gt;
We now draw the sliders themselves. The color bar and the slide indicator are drawn on a white background, and they are grouped together. The &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt; attribute goes on the indicator &amp;lt;tt&amp;gt;&amp;lt;line&amp;gt;&amp;lt;/tt&amp;gt; element, since its ''y''-coordinate will be changing. The event handlers will be attached to the enclosing &amp;lt;tt&amp;gt;&amp;lt;g&amp;gt;&amp;lt;/tt&amp;gt; element. The group will then capture the mouse events that happen on any of its child elements. (This is why we drew the white background; the mouse will still track even if you drag outside the colored bar.)&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;g onmousedown=&amp;quot;startColorDrag(0)&amp;quot;&lt;br /&gt;
     onmouseup=&amp;quot;endColorDrag()&amp;quot;&lt;br /&gt;
     onmousemove=&amp;quot;doColorDrag(evt,0)&amp;quot;&lt;br /&gt;
     transform=&amp;quot;translate( 230, 10 )&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;-10&amp;quot; y=&amp;quot;-5&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;110&amp;quot; style=&amp;quot;fill: white;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;5&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;10&amp;quot; height=&amp;quot;100&amp;quot; style=&amp;quot;fill: red;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;line id=&amp;quot;slide0&amp;quot; x1=&amp;quot;0&amp;quot; y1=&amp;quot;0&amp;quot; x2=&amp;quot;20&amp;quot; y2=&amp;quot;0&amp;quot;&lt;br /&gt;
         style=&amp;quot;stroke: gray; stroke-width: 2;&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;g onmousedown=&amp;quot;startColorDrag(1)&amp;quot;&lt;br /&gt;
     onmouseup=&amp;quot;endColorDrag()&amp;quot;&lt;br /&gt;
     onmousemove=&amp;quot;doColorDrag(evt,1)&amp;quot;&lt;br /&gt;
     transform=&amp;quot;translate( 280, 10 )&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;-10&amp;quot; y=&amp;quot;-5&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;110&amp;quot; style=&amp;quot;fill: white;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;5&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;10&amp;quot; height=&amp;quot;100&amp;quot; style=&amp;quot;fill: green;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;line id=&amp;quot;slide1&amp;quot; x1=&amp;quot;0&amp;quot; y1=&amp;quot;0&amp;quot; x2=&amp;quot;20&amp;quot; y2=&amp;quot;0&amp;quot;&lt;br /&gt;
         style=&amp;quot;stroke: gray; stroke-width: 2;&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;g onmousedown=&amp;quot;startColorDrag(2)&amp;quot;&lt;br /&gt;
     onmouseup=&amp;quot;endColorDrag()&amp;quot;&lt;br /&gt;
     onmousemove=&amp;quot;doColorDrag(evt,2)&amp;quot;&lt;br /&gt;
     transform=&amp;quot;translate( 330, 10 )&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;-10&amp;quot; y=&amp;quot;-5&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;110&amp;quot; style=&amp;quot;fill: white;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;5&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;10&amp;quot; height=&amp;quot;100&amp;quot; style=&amp;quot;fill: blue;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;line id=&amp;quot;slide2&amp;quot; x1=&amp;quot;0&amp;quot; y1=&amp;quot;0&amp;quot; x2=&amp;quot;20&amp;quot; y2=&amp;quot;0&amp;quot;&lt;br /&gt;
         style=&amp;quot;stroke: gray; stroke-width: 2;&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding functions are as follows:&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * Stop dragging the current slider (if any)&lt;br /&gt;
  * and set the current slider to the one specified.&lt;br /&gt;
  * (0 = red, 1 = green, 2 = blue)&lt;br /&gt;
  */&lt;br /&gt;
 function startColorDrag( which )&lt;br /&gt;
 {&lt;br /&gt;
     endColorDrag( );&lt;br /&gt;
     slideChoice = which;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * Set slider choice to -1, indicating that no&lt;br /&gt;
  * slider is begin dragged.&lt;br /&gt;
  */&lt;br /&gt;
 function endColorDrag( )&lt;br /&gt;
 {&lt;br /&gt;
    slideChoice = -1;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * Move the specified slider in response to the&lt;br /&gt;
  * mousemove event.&lt;br /&gt;
  */&lt;br /&gt;
 function doColorDrag( evt, which )&lt;br /&gt;
 {&lt;br /&gt;
     /*&lt;br /&gt;
      * If no slider is active, or the event is on a&lt;br /&gt;
      * slider other than the active one, do nothing&lt;br /&gt;
      */&lt;br /&gt;
     if (slideChoice &amp;lt; 0 || slideChoice != which)&lt;br /&gt;
     {&lt;br /&gt;
         return;&lt;br /&gt;
     }&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Get the slider indicator line object, and the&lt;br /&gt;
      * mouse position (relative to the top of the color bar)&lt;br /&gt;
      */&lt;br /&gt;
     var obj = evt.getTarget();&lt;br /&gt;
     var pos = evt.getClientY() - 10;&lt;br /&gt;
 &lt;br /&gt;
     /* Clamp values to range 0..100 */&lt;br /&gt;
     if (pos &amp;lt; 0) { pos = 0; }&lt;br /&gt;
     if (pos &amp;gt; 100) { pos = 100; }&lt;br /&gt;
     &lt;br /&gt;
     /* Move the slider line to the new mouse position */&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;slide&amp;quot; + slideChoice );&lt;br /&gt;
     obj.setAttribute(&amp;quot;y1&amp;quot;, pos );&lt;br /&gt;
     obj.setAttribute(&amp;quot;y2&amp;quot;, pos );&lt;br /&gt;
     &lt;br /&gt;
     /* Calculate the new color value for this slider */&lt;br /&gt;
     rgb[slideChoice] = 100-pos;&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Put together all the color values and&lt;br /&gt;
      * change the shirt's color accordingly.&lt;br /&gt;
      */&lt;br /&gt;
     var colorStr = &amp;quot;rgb(&amp;quot; + rgb[0] + &amp;quot;%,&amp;quot; +&lt;br /&gt;
         rgb[1] + &amp;quot;%,&amp;quot; + rgb[2] + &amp;quot;%)&amp;quot;;&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;shirt&amp;quot; );&lt;br /&gt;
     obj.setAttribute(&amp;quot;fill&amp;quot;, colorStr );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
There's only one minor point to take care of — the document will respond to an &amp;lt;tt&amp;gt;onmouseup&amp;lt;/tt&amp;gt; only if it occurs within the slider area. So, if you click the mouse on the red color bar, drag the mouse down to the shirt, then release the mouse button, the document will be unaware of it. When you then move the mouse over the red slider again, it will still follow the mouse. To solve this problem, we insert a transparent rectangle that completely covers the viewport, and have it respond to a mouseup event by calling &amp;lt;tt&amp;gt;stopColorDrag&amp;lt;/tt&amp;gt;. It will be the first, and therefore bottom-most object in the graphic. To make the rectangle as unobtrusive as possible, it will be set to &amp;lt;tt&amp;gt;style=&amp;quot;fill: none;&amp;quot;&amp;lt;/tt&amp;gt;. &amp;quot;But wait,&amp;quot; you interject. &amp;quot;A transparent area cannot respond to an event!&amp;quot; No, ordinarily it can't, but we can set the &amp;lt;tt&amp;gt;pointer-events&amp;lt;/tt&amp;gt; attribute to &amp;lt;tt&amp;gt;visible&amp;lt;/tt&amp;gt;, meaning that an object can respond to events as long as it is visible, no matter what its opacity.&amp;lt;ref&amp;gt;Other values for &amp;lt;tt&amp;gt;pointer-events&amp;lt;/tt&amp;gt; let you respond to an object's events in the filled areas only (&amp;lt;tt&amp;gt;fill&amp;lt;/tt&amp;gt;), outline areas only (&amp;lt;tt&amp;gt;stroke&amp;lt;/tt&amp;gt;), or the fill and outline together (&amp;lt;tt&amp;gt;painted&amp;lt;/tt&amp;gt;), whether visible or not. Corresponding attribute values of &amp;lt;tt&amp;gt;visibleFill&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;visibleStroke&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;visiblePainted&amp;lt;/tt&amp;gt; take the object's visibility into account as well.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;rect x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;400&amp;quot; height=&amp;quot;300&amp;quot; style=&amp;quot;fill: none;&amp;quot;&lt;br /&gt;
      onmouseup=&amp;quot;endColorDrag()&amp;quot;&lt;br /&gt;
      pointer-events=&amp;quot;visible&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Modifying Text ===&lt;br /&gt;
&lt;br /&gt;
Although the sliders do give us the interactivity we want, it's hard to judge the percentages by eye. We'd much prefer to show the percentages of red, green, and blue below each slider, as depicted in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-11|Figure 11-11]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-11&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-11. Screenshot of labeled color sliders'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt251.png|Screenshot of labeled color sliders]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here's the SVG for the text underneath the red slider; the ones under the blue and green slider have &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;s of &amp;lt;tt&amp;gt;pct1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pct2&amp;lt;/tt&amp;gt;. This element will go into a separate group from the color bar and slider line so that it does not also become clickable.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;text id=&amp;quot;pct0&amp;quot; x=&amp;quot;10&amp;quot; y=&amp;quot;120&amp;quot;&lt;br /&gt;
     style=&amp;quot;font-size: 9pt; text-anchor: middle;&amp;quot;&amp;gt;100%&amp;lt;/text&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The number we want to change as we drag the mouse is not an attribute; it's the child of the &amp;lt;tt&amp;gt;&amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt; element, so we can't use &amp;lt;tt&amp;gt;setAttribute&amp;lt;/tt&amp;gt; to modify the text. Instead, we have to create a new text node and insert it into the document tree in place of the old one. Here's the code that we add at the end of the &amp;lt;tt&amp;gt;doColorDrag&amp;lt;/tt&amp;gt; function. The first line retrieves the &amp;lt;tt&amp;gt;&amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt; element. (The &amp;lt;tt&amp;gt;obj&amp;lt;/tt&amp;gt; variable has already been declared, so we don't need to say &amp;lt;tt&amp;gt;var&amp;lt;/tt&amp;gt; again.) The second line asks the document to create a new text node whose content is the percentage of the currently chosen slider. This text node needs to be placed in its proper location within the document tree. That's what the third line does; it replaces the first child of the text element with the newly created node.&lt;br /&gt;
&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;pct&amp;quot; + slideChoice );&lt;br /&gt;
     var newText = svgDocument.createTextNode( rgb[slideChoice] + &amp;quot;%&amp;quot; );&lt;br /&gt;
     obj.replaceChild( newText, obj.getFirstChild() );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
You can do much more than simply modify the text in a document. You can remove elements, change their order, or even create new elements with attributes and add them to the document under script control. A list of the functions that manipulate the Document Object Model are listed in Appendix E of the World Wide Web Consortium's Document Object Model (DOM) Level 1 Specification at ''http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001''. A detailed explanation of what the functions do can be found in the ''DOM Reference'' chapter of ''XML in a Nutshell'', by Elliotte Rusty Harold and W. Scott Means. Although the examples in that book use Java rather than ECMA Script, the explanations apply to both.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interacting with an HTML Page ===&lt;br /&gt;
&lt;br /&gt;
It is possible to embed an SVG graphic in a web page using the &amp;lt;tt&amp;gt;&amp;lt;embed&amp;gt;&amp;lt;/tt&amp;gt; element. The relevant attributes are the &amp;lt;tt&amp;gt;src&amp;lt;/tt&amp;gt; for the graphic (a URL), the &amp;lt;tt&amp;gt;width&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;height&amp;lt;/tt&amp;gt; of the graphic, and the &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt; attribute, which will be &amp;lt;tt&amp;gt;image/svg+xml&amp;lt;/tt&amp;gt;. Once embedded, you can add code to the SVG script and the HTML page's script so they can communicate with one another.&lt;br /&gt;
&lt;br /&gt;
Our goal in this example is to embed the preceding SVG example into a web page. This web page will have a form that lets users type in the red, green, and blue percentages. The values they enter will be reflected in the sliders. If they adjust the sliders, the values in the form fields will be updated accordingly.&lt;br /&gt;
&lt;br /&gt;
Here is the HTML document, with references to the (as yet unwritten) &amp;lt;tt&amp;gt;updateSVG&amp;lt;/tt&amp;gt; function. This function will take the input field number and the value currently within the input field.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
 &amp;lt;head&amp;gt;&lt;br /&gt;
 &amp;lt;title&amp;gt;SVG and HTML&amp;lt;/title&amp;gt;&lt;br /&gt;
 &amp;lt;/head&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;body bgcolor=&amp;quot;white&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;amp;lt;h2&amp;gt;SVG and HTML&amp;amp;lt;/h2&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &amp;amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;embed src=&amp;quot;shirt_interact.svg&amp;quot;&lt;br /&gt;
     width=&amp;quot;400&amp;quot; height=&amp;quot;250&amp;quot;&lt;br /&gt;
     type=&amp;quot;image/svg+xml&amp;quot; /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;form name=&amp;quot;rgbForm&amp;quot;&amp;gt;&lt;br /&gt;
     Red: &amp;lt;input id=&amp;quot;fld0&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;5&amp;quot; value=&amp;quot;100&amp;quot;&lt;br /&gt;
             onchange=&amp;quot;updateSVG(0, this.value)&amp;quot; /&amp;gt;% &amp;amp;lt;br /&amp;gt; &lt;br /&gt;
     Green: &amp;lt;input id=&amp;quot;fld1&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;5&amp;quot; value=&amp;quot;100&amp;quot;&lt;br /&gt;
             onchange=&amp;quot;updateSVG(1, this.value)&amp;quot; /&amp;gt;% &amp;amp;lt;br /&amp;gt;&lt;br /&gt;
     Blue: &amp;lt;input id=&amp;quot;fld2&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;5&amp;quot; value=&amp;quot;100&amp;quot;&lt;br /&gt;
             onchange=&amp;quot;updateSVG(2, this.value)&amp;quot; /&amp;gt;%    &lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
 &amp;amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the script that goes into the head of the HTML document. Function &amp;lt;tt&amp;gt;updateSVG&amp;lt;/tt&amp;gt; checks to see that the input value is an integer (it will discard any decimal part), and, if so, calls &amp;lt;tt&amp;gt;setShirtColor&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;setShirtColor&amp;lt;/tt&amp;gt; is actually a reference to a function that exists in the SVG document, and it will be the SVG document's responsibility to connect the function to this HTML reference.&lt;br /&gt;
&lt;br /&gt;
Function &amp;lt;tt&amp;gt;updateHTMLField&amp;lt;/tt&amp;gt; will be called from the SVG document's script. It will receive a form field number and a percent value, which it will display in the appropriate form field.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script language=&amp;quot;Javascript&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;amp;lt;!--&lt;br /&gt;
 function updateSVG( which, amount )&lt;br /&gt;
 {&lt;br /&gt;
     amount = parseInt( amount );&lt;br /&gt;
     if (!isNaN(amount))&lt;br /&gt;
     {&lt;br /&gt;
         '''window.setShirtColor( which, amount );'''&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function updateHTMLField( which, percent )&lt;br /&gt;
 {&lt;br /&gt;
     document.rgbForm[ &amp;quot;fld&amp;quot; + which ].value = percent;&lt;br /&gt;
 }&lt;br /&gt;
 // --&amp;gt;&lt;br /&gt;
 &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let us now turn our attention to the SVG document. The parent of the document is the browser window in which it is embedded. We use the reserved word &amp;lt;tt&amp;gt;parent&amp;lt;/tt&amp;gt; in the &amp;lt;tt&amp;gt;init&amp;lt;/tt&amp;gt; function to connect the SVG document's &amp;lt;tt&amp;gt;svgSetShirtColor&amp;lt;/tt&amp;gt; function to the HTML page's &amp;lt;tt&amp;gt;setShirtColor&amp;lt;/tt&amp;gt; reference.&lt;br /&gt;
&lt;br /&gt;
 function init( evt )&lt;br /&gt;
 {&lt;br /&gt;
     '''parent.setShirtColor = svgSetShirtColor;'''&lt;br /&gt;
     svgDocument = evt.getTarget().getOwnerDocument();&lt;br /&gt;
     transformShirt();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Since there are now effectively two ways to set the color values, we'll make things more modular by rewriting &amp;lt;tt&amp;gt;doColorDrag&amp;lt;/tt&amp;gt; to call the new &amp;lt;tt&amp;gt;svgSetShirtColor&amp;lt;/tt&amp;gt; function:&lt;br /&gt;
&lt;br /&gt;
 function doColorDrag( evt, which )&lt;br /&gt;
 {&lt;br /&gt;
     /*&lt;br /&gt;
      * If no slider is active, or the event is on a&lt;br /&gt;
      * slider other than the active one, do nothing&lt;br /&gt;
      */&lt;br /&gt;
     if (slideChoice &amp;lt; 0 || slideChoice != which)&lt;br /&gt;
     {&lt;br /&gt;
         return;&lt;br /&gt;
     }&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Get the slider indicator line object, and the&lt;br /&gt;
      * mouse position (relative to the top of the color bar)&lt;br /&gt;
      */&lt;br /&gt;
     var obj = evt.getTarget();&lt;br /&gt;
     var pos = evt.getClientY() - 10;&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Since pos=0 is at the 100% point on the scale,&lt;br /&gt;
      * take 100-pos and send that to svgSetShirtColor&lt;br /&gt;
      * along with the slider number.&lt;br /&gt;
      */&lt;br /&gt;
     svgSetShirtColor( which, 100 - pos );&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Function &amp;lt;tt&amp;gt;svgSetShirtColor&amp;lt;/tt&amp;gt; will do what the remainder of &amp;lt;tt&amp;gt;doColorDrag&amp;lt;/tt&amp;gt; used to do, with two major differences. It uses the slider number that it is given as the first parameter, not the global &amp;lt;tt&amp;gt;sliderChoice&amp;lt;/tt&amp;gt; variable. The second parameter is now a percentage; in the original version it was the ''y''-position of the mouse. These are the sorts of changes you have to make when you decide to modularize simple code that was written for an ''ad-hoc'' example.&lt;br /&gt;
&lt;br /&gt;
 function svgSetShirtColor( which, percent )&lt;br /&gt;
 {&lt;br /&gt;
     var obj;&lt;br /&gt;
     var colorStr;&lt;br /&gt;
     var newText;&lt;br /&gt;
 &lt;br /&gt;
     /* Clamp values to range 0..100 */&lt;br /&gt;
     if (percent &amp;lt; 0) { percent = 0; }&lt;br /&gt;
     if (percent &amp;gt; 100) { percent = 100; }&lt;br /&gt;
 &lt;br /&gt;
     /* Move the slider line to the new mouse position */&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;slide&amp;quot; + which );&lt;br /&gt;
     '''obj.setAttribute(&amp;quot;y1&amp;quot;, 100-percent );'''&lt;br /&gt;
 '''    obj.setAttribute(&amp;quot;y2&amp;quot;, 100-percent );'''&lt;br /&gt;
 '''    rgb[which] = percent;'''&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Put together all the color values and&lt;br /&gt;
      * change the shirt's color accordingly.&lt;br /&gt;
      */&lt;br /&gt;
     colorStr = &amp;quot;rgb(&amp;quot; + rgb[0] + &amp;quot;%,&amp;quot; +&lt;br /&gt;
         rgb[1] + &amp;quot;%,&amp;quot; + rgb[2] + &amp;quot;%)&amp;quot;;&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;shirt&amp;quot; );&lt;br /&gt;
     obj.setAttribute(&amp;quot;fill&amp;quot;, colorStr );&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Change text to match slider position&lt;br /&gt;
      */&lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;pct&amp;quot; + which );&lt;br /&gt;
     newText = svgDocument.createTextNode( rgb[which] + &amp;quot;%&amp;quot; );&lt;br /&gt;
     obj.replaceChild( newText, obj.getFirstChild());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This code accomplishes the HTML to SVG communication. Our last step is to communicate from SVG back to HTML if the user decides to choose colors with the slider. Rather than continuously update the HTML fields, we have made the design decision to update the HTML when dragging stops. We add the boldface code to function &amp;lt;tt&amp;gt;endColorDrag&amp;lt;/tt&amp;gt;. The result is shown in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-12|Figure 11-12]]; the screenshot has been edited to eliminate unnecessary whitespace).&lt;br /&gt;
&lt;br /&gt;
 function endColorDrag( )&lt;br /&gt;
 {&lt;br /&gt;
      '''/*'''&lt;br /&gt;
 '''     * If a slider was being moved, send the slider number'''&lt;br /&gt;
 '''     * and its value back to the updateHTMLField function'''&lt;br /&gt;
 '''     * in the parent web browser window.'''&lt;br /&gt;
 '''     */'''&lt;br /&gt;
 '''    if (slideChoice &amp;gt;= 0)'''&lt;br /&gt;
 '''    {'''&lt;br /&gt;
 '''        parent.updateHTMLField( slideChoice, rgb[slideChoice] );'''&lt;br /&gt;
 '''    }'''&lt;br /&gt;
     &lt;br /&gt;
     /* In any case, nobody's being dragged now */&lt;br /&gt;
     slideChoice = -1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-12&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-12. Screenshot of HTML and SVG interaction'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt260.png|Screenshot of HTML and SVG interaction]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scripting and Animation Together ===&lt;br /&gt;
&lt;br /&gt;
Scripting and animation can work together. You can start an animation in response to an event, and you can use the beginning, end, or repetition of an animation to invoke a function. [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-20|Example 11-20]] shows a trapezoid and a button. When you click the button, a message saying &amp;quot;Animation in progress&amp;quot; appears, and the trapezoid rotates 360 degrees. When it finishes rotating, the message disappears. Relevant screenshots are shown in [[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-13|Figure 11-13]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-13&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-13. Screenshot of two stages of scripting with animation'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt261.png|Screenshot of two stages of scripting with animation]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;note&amp;quot;&amp;gt;&lt;br /&gt;
'''Note'''&lt;br /&gt;
&lt;br /&gt;
The numbered callouts in the example are in conceptual order, not text order. I've found it easier to design the SVG first and add the scripting later. One advantage of this method is that I can see if the base drawing looks good before I start making it react to events.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-20&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-20. Scripting and Animation Together'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/ecmascript&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;![CDATA[&lt;br /&gt;
 &lt;br /&gt;
 function init( evt )&lt;br /&gt;
 {&lt;br /&gt;
     /* initialization code goes here */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function setMessage( visStatus )      '''[1]'''&amp;lt;nowiki&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    var message = svgDocument.getElementById( &amp;quot;message&amp;quot; );&lt;br /&gt;
    message.setAttribute( &amp;quot;visibility&amp;quot;, visStatus );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;g id=&amp;quot;button&amp;quot;&amp;gt;     &amp;lt;/nowiki&amp;gt;'''[2]'''&lt;br /&gt;
     &amp;lt;rect x=&amp;quot;10&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;20&amp;quot; rx=&amp;quot;4&amp;quot; ry=&amp;quot;4&amp;quot;&lt;br /&gt;
         style=&amp;quot;fill: #ddd;&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;text x=&amp;quot;30&amp;quot; y=&amp;quot;25&amp;quot; style=&amp;quot;text-anchor: middle;&amp;quot;&amp;gt;Start&amp;lt;/text&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;text id=&amp;quot;message&amp;quot; x=&amp;quot;60&amp;quot; y=&amp;quot;25&amp;quot; visibility=&amp;quot;hidden&amp;quot;&amp;gt;     '''[3]'''&lt;br /&gt;
     Animation in progress.&lt;br /&gt;
 &amp;lt;/text&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;g transform=&amp;quot;translate(100, 60)&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;path d=&amp;quot;M-25 -15, 0 -15, 25 15, -25 15 Z&amp;quot;&lt;br /&gt;
         style=&amp;quot;stroke: gray; fill: #699;&amp;quot;&amp;gt;&lt;br /&gt;
         &lt;br /&gt;
         &amp;lt;animateTransform id=&amp;quot;trapezoid&amp;quot; attributeName=&amp;quot;transform&amp;quot;&lt;br /&gt;
             type=&amp;quot;rotate&amp;quot; from=&amp;quot;0&amp;quot; to=&amp;quot;360&amp;quot;&lt;br /&gt;
             begin=&amp;quot;button.click&amp;quot;     '''[4]'''&lt;br /&gt;
             dur=&amp;quot;6s&amp;quot;&lt;br /&gt;
             onbegin=&amp;quot;setMessage('visible')&amp;quot;      '''[5]'''&lt;br /&gt;
             onend=&amp;quot;setMessage('hidden')&amp;quot;/&amp;gt; &lt;br /&gt;
     &amp;lt;/path&amp;gt;&lt;br /&gt;
 &amp;lt;/g&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[1]'''&amp;lt;/tt&amp;gt; Here's the function, which takes the visibility status that was passed to it, and sets the message's &amp;lt;tt&amp;gt;visibility&amp;lt;/tt&amp;gt; property accordingly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[2]'''&amp;lt;/tt&amp;gt; The start button is a simple rounded rectangle with text. The entire group gets the &amp;lt;tt&amp;gt;id&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[3]'''&amp;lt;/tt&amp;gt; The message, initially hidden. Again, we use a presentation attribute here rather than a style, since we'll be modifying the attribute.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[4]'''&amp;lt;/tt&amp;gt; Instead of giving the begin time for the animation in terms of seconds, we begin whenever a &amp;lt;tt&amp;gt;click&amp;lt;/tt&amp;gt; event is detected on the &amp;lt;tt&amp;gt;button&amp;lt;/tt&amp;gt; object. Since we're waiting for the event, we use &amp;lt;tt&amp;gt;click&amp;lt;/tt&amp;gt; rather than the event handler attribute &amp;lt;tt&amp;gt;onclick&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;'''[5]'''&amp;lt;/tt&amp;gt; The next two lines ''are'' event handlers, so they begin with the prefix &amp;lt;tt&amp;gt;on&amp;lt;/tt&amp;gt;. When the animation begins (&amp;lt;tt&amp;gt;onbegin&amp;lt;/tt&amp;gt;), we call &amp;lt;tt&amp;gt;setMessage&amp;lt;/tt&amp;gt; with the argument &amp;lt;tt&amp;gt;'visible'&amp;lt;/tt&amp;gt;; when it ends (&amp;lt;tt&amp;gt;onend&amp;lt;/tt&amp;gt;) we call the same function with the argument &amp;lt;tt&amp;gt;'hidden'&amp;lt;/tt&amp;gt;.&amp;lt;ref&amp;gt;The event handler &amp;lt;tt&amp;gt;onrepeat&amp;lt;/tt&amp;gt; is invoked each time an animation repeats after the first iteration.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Animation via Scripting ===&lt;br /&gt;
&lt;br /&gt;
Because SMIL2 animation is integrated with SVG, your animations become part of the document structure. Since it's all XML, animated SVG documents remain easy for humans to read and for XML tools to process. The addition of scripting, as we showed in the preceding section, makes it possible to add some user interaction with an animation.&lt;br /&gt;
&lt;br /&gt;
While animation can handle most of the things you'll want to move, there are some things the animation elements can't do easily. For example, it's hard to change a &amp;lt;tt&amp;gt;&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt; dynamically. We're not talking about making an object move along a path (&amp;lt;tt&amp;gt;&amp;lt;animateMotion&amp;gt;&amp;lt;/tt&amp;gt;); we want the path itself to change over time. The path isn't a transformation, so &amp;lt;tt&amp;gt;&amp;lt;animateTransform&amp;gt;&amp;lt;/tt&amp;gt; won't work; in addition, it's not a simple numeric value, so we can't use &amp;lt;tt&amp;gt;&amp;lt;animate&amp;gt;&amp;lt;/tt&amp;gt;. We'll have to use scripting instead.&lt;br /&gt;
&lt;br /&gt;
[[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-21|Example 11-21]] uses scripting alone to repeatedly change the &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; attribute of the path over time. The key to doing animation via scripting is the &amp;lt;tt&amp;gt;setInterval&amp;lt;/tt&amp;gt; function. &amp;lt;tt&amp;gt;setInterval&amp;lt;/tt&amp;gt; sets an &amp;quot;alarm clock&amp;quot; to go off repeatedly at regular intervals. When the alarm goes off, the scripting engine performs the ECMA Script statements you want. The simplest form is:&lt;br /&gt;
&lt;br /&gt;
                ''timer_variable'' =&lt;br /&gt;
     setInterval( &amp;quot;''ECMA Script function''&amp;quot;,&lt;br /&gt;
         ''interval time in milliseconds'');&lt;br /&gt;
&lt;br /&gt;
This function returns a reference to the timer that it set. You should save that reference in a global variable so that other functions can access it. You call &amp;lt;tt&amp;gt;setInterval&amp;lt;/tt&amp;gt; once, and, the &amp;lt;tt&amp;gt;''ECMA Script function''&amp;lt;/tt&amp;gt; you've specified will be called every &amp;lt;tt&amp;gt;''interval''&amp;lt;/tt&amp;gt; milliseconds. The repetition will continue until you call &amp;lt;tt&amp;gt;clearInterval(''timer_variable'')&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-EX-21|Example 11-21]] shows a cubic Bézier curve. When the user clicks the start button, we'll move the control points every tenth of a second for five seconds (fifty movements in all). The control points will move towards each other in the ''x'' direction starting at five pixels per interval. They will move away from each other in the ''y'' direction at three-fourths of a pixel per interval. Note especially the boldfaced line and its commentary!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-EX-21&amp;quot;&amp;gt;&lt;br /&gt;
'''Example 11-21. Animating a path with scripting'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;svg width=&amp;quot;300&amp;quot; height=&amp;quot;200&amp;quot; viewBox=&amp;quot;0 0 300 200&amp;quot;&lt;br /&gt;
     onload=&amp;quot;init(evt)&amp;quot;&amp;gt; &lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/ecmascript&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;![CDATA[&lt;br /&gt;
 &lt;br /&gt;
 /* Starting coordinates for both control points */&lt;br /&gt;
 var cp1 = new Array( 100, 50 );&lt;br /&gt;
 var cp2 = new Array( 200, 200 );&lt;br /&gt;
 &lt;br /&gt;
 var moveLimit = 50;     // total number of moves to make&lt;br /&gt;
 var currentMove = 0;    // current number of moves&lt;br /&gt;
 &lt;br /&gt;
 var deltaX;             // X movement amount&lt;br /&gt;
 var deltaY;             // Y movement amount&lt;br /&gt;
 &lt;br /&gt;
 var delay = 100;        // one-tenth second&lt;br /&gt;
 &lt;br /&gt;
 var timer;              // store the alarm clock&lt;br /&gt;
 &lt;br /&gt;
 function init( evt )&lt;br /&gt;
 {&lt;br /&gt;
     /* do any global initialization here */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /*&lt;br /&gt;
  * Initialize movement; set control points back to their&lt;br /&gt;
  * starting positions, set the current number of moves&lt;br /&gt;
  * to zero, and set an interval timer to move the&lt;br /&gt;
  * control points every &amp;quot;delay&amp;quot; milliseconds.&lt;br /&gt;
  */&lt;br /&gt;
 function setupMove()&lt;br /&gt;
 {&lt;br /&gt;
     var i;&lt;br /&gt;
 &lt;br /&gt;
     currentMove = 0;&lt;br /&gt;
     deltaX = 5;         /* start X at five pixels per interval */&lt;br /&gt;
     deltaY = 0.75;      /* start Y at 3/4 pixels per interval */&lt;br /&gt;
     setGraphicInfo();&lt;br /&gt;
     timer = setInterval( &amp;quot;moveControlPoints()&amp;quot;, delay );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function setGraphicInfo()&lt;br /&gt;
 {  &lt;br /&gt;
     var obj;&lt;br /&gt;
     var pathString;&lt;br /&gt;
     &lt;br /&gt;
     /*&lt;br /&gt;
      * Construct a path that describes a cubic&lt;br /&gt;
      * Bezier curve using the current coordinates&lt;br /&gt;
      * for the control points.&lt;br /&gt;
      */&lt;br /&gt;
      pathString = &amp;quot;M 50 120 C &amp;quot; +&lt;br /&gt;
         (cp1[0] + currentMove * deltaX) + &amp;quot; &amp;quot; +&lt;br /&gt;
         (cp1[1] - currentMove * deltaY) + &amp;quot;, &amp;quot; +&lt;br /&gt;
         (cp2[0] - currentMove * deltaX)  + &amp;quot; &amp;quot; +&lt;br /&gt;
         (cp2[1] + currentMove * deltaY) + &amp;quot;, &amp;quot; +&lt;br /&gt;
         &amp;quot;250, 120&amp;quot;;&lt;br /&gt;
     &lt;br /&gt;
     obj = svgDocument.getElementById( &amp;quot;cubic&amp;quot; );&lt;br /&gt;
     obj.setAttribute( &amp;quot;d&amp;quot;, pathString );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function moveControlPoints()&lt;br /&gt;
 {&lt;br /&gt;
     currentMove++;      // we've done one more move&lt;br /&gt;
     setGraphicInfo();   // adjust the control points and path&lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
      * If we have finished moving, clear the timer, which&lt;br /&gt;
      * will stop the repeated wake-up calls.&lt;br /&gt;
      */&lt;br /&gt;
     if (currentMove &amp;gt;= moveLimit)&lt;br /&gt;
     {&lt;br /&gt;
        clearInterval( timer );&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function stopMovement()&lt;br /&gt;
 {&lt;br /&gt;
     clearInterval( timer );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 '''/*'''&lt;br /&gt;
 ''' * setInterval expects its first argument to be found in'''&lt;br /&gt;
 ''' * the main window. We oblige it by creating a reference'''&lt;br /&gt;
 ''' * to this script's moveControlPoints function as a'''&lt;br /&gt;
 ''' * window property'''&lt;br /&gt;
 ''' */'''&lt;br /&gt;
 '''window.moveControlPoints = moveControlPoints;'''&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ]]&amp;gt;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;g id=&amp;quot;button&amp;quot; onclick=&amp;quot;setupMove();&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;rect x=&amp;quot;10&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;20&amp;quot; rx=&amp;quot;4&amp;quot; ry=&amp;quot;4&amp;quot;&lt;br /&gt;
        style=&amp;quot;fill: #ddd;&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;text x=&amp;quot;30&amp;quot; y=&amp;quot;25&amp;quot; style=&amp;quot;text-anchor: middle;&amp;quot;&amp;gt;Start&amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;/g&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;g id=&amp;quot;button&amp;quot; onclick=&amp;quot;stopMovement()&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;rect x=&amp;quot;70&amp;quot; y=&amp;quot;10&amp;quot; width=&amp;quot;40&amp;quot; height=&amp;quot;20&amp;quot; rx=&amp;quot;4&amp;quot; ry=&amp;quot;4&amp;quot;&lt;br /&gt;
        style=&amp;quot;fill: #ddd;&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;text x=&amp;quot;90&amp;quot; y=&amp;quot;25&amp;quot; style=&amp;quot;text-anchor: middle;&amp;quot;&amp;gt;Stop&amp;lt;/text&amp;gt;&lt;br /&gt;
&amp;lt;/g&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;path id=&amp;quot;cubic&amp;quot; style=&amp;quot;stroke: blue; fill: none;&amp;quot;&lt;br /&gt;
    d=&amp;quot;M 50 120 C 100 50, 200 200, 250 120&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/svg&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[SVG Essentials/Animating and Scripting SVG#svgess-CHP-11-FIG-14|Figure 11-14]] shows the path in its initial and final states.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;svgess-CHP-11-FIG-14&amp;quot;&amp;gt;&lt;br /&gt;
'''Figure 11-14. Beginning and ending of scripted path change'''&lt;br /&gt;
&lt;br /&gt;
[[Image:SVG Essentials/I_11_tt263.png|Beginning and ending of scripted path change]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, the &amp;lt;tt&amp;gt;moveControlPoints&amp;lt;/tt&amp;gt; function didn't need any parameters. Let's say the function needed two parameters, &amp;lt;tt&amp;gt;pathColor&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pathStrokeWidth&amp;lt;/tt&amp;gt; To ensure that &amp;lt;tt&amp;gt;moveControlPoints&amp;lt;/tt&amp;gt; got those parameters every time it was called, we would add them at the end of our call to set up the interval timer:&lt;br /&gt;
&lt;br /&gt;
 timer = setInterval(&amp;quot;moveControlPoints()&amp;quot;, delay,&lt;br /&gt;
     pathColor, pathStrokeWidth );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;setInterval&amp;lt;/tt&amp;gt; &amp;lt;ref&amp;gt;Or its variant, &amp;lt;tt&amp;gt;setTimeout&amp;lt;/tt&amp;gt;, which sets the timer to go off exactly once. The generic model for calling this function is: &lt;br /&gt;
&lt;br /&gt;
                         ''timer_variable'' = setTimeout( &amp;quot;''action_function( parameters )''&amp;quot;, ''delay'' );&lt;br /&gt;
&lt;br /&gt;
 Use &amp;lt;tt&amp;gt;clearTimeout(&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;''timer_variable''&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;)&amp;lt;/tt&amp;gt; to cancel a pending timer event.&amp;lt;/ref&amp;gt; is the ''only'' safe way to script repeated actions with a delay interval. Using &amp;lt;tt&amp;gt;setInterval&amp;lt;/tt&amp;gt; is like leaving a message with a desk clerk at a hotel to give you a wake-up call every hour; between calls you are free to sleep or do other things. In scripting terms, this kind of code leaves the computer free to do other tasks between actions:&lt;br /&gt;
&lt;br /&gt;
 function startGoodAction()&lt;br /&gt;
 {&lt;br /&gt;
     timer = setInterval( &amp;quot;doGoodAction()&amp;quot;, delay );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 function doGoodAction()&lt;br /&gt;
 {&lt;br /&gt;
     obj.setAttribute( &amp;quot;x&amp;quot;, value );&lt;br /&gt;
     value = value + increment;&lt;br /&gt;
     repetitions = repetitions + 1;&lt;br /&gt;
     if ( repetitions == limit )&lt;br /&gt;
     {&lt;br /&gt;
         clearInterval( timer );&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Beginning programmers will often do something like this:&lt;br /&gt;
&lt;br /&gt;
 function doBadAction()&lt;br /&gt;
 {&lt;br /&gt;
     obj.setAttribute( &amp;quot;x&amp;quot;, value );&lt;br /&gt;
     value = value + increment; &lt;br /&gt;
     if ( repetitions != limit )&lt;br /&gt;
     {&lt;br /&gt;
         waitCount = 0;&lt;br /&gt;
         while (waitCount &amp;lt; waitLimit)&lt;br /&gt;
             waitCount++;&lt;br /&gt;
         doBadAction();&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This technique is akin to constantly looking at your watch and asking, &amp;quot;Is it time yet?&amp;quot; This gives you no time to sleep or do anything else. In an SVG script, it gives the computer little chance to attend to other tasks. Additionally, this uses a ''recursive'' style, which, if not carefully controlled, can consume your system resources faster than you can say &amp;quot;Error: stack overflow.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Though the preceding example was a simple one, this technique has great power. If you choose to use scripting to do animation, you will then have available all the interactivity features of scripting; you can make animation dependent on mouse position or complex conditions involving multiple variables. If you're doing simple animation, we recommend that you use SVG's animation elements.&lt;br /&gt;
== Notes ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 04 Mar 2008 22:37:00 GMT</pubDate>			<dc:creator>Docbook2Wiki</dc:creator>			<comments>http://commons.oreilly.com/wiki/index.php/Talk:SVG_Essentials/Animating_and_Scripting_SVG</comments>		</item>
	</channel>
</rss>