<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article
  PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<article lang="">
   <para/><sect1><title>Introduction</title>
   <para/>
   <para>The maturation of web browsers has reached the point where it is easy to use native vector graphics without any third party plugins and installs. SVG is supported in all major modern browsers except for IE, which supports VML, a slightly-limited precursor to SVG. Despite maturity of SVG in web browsers there are still gaps in support. Raphaël JavaScript Library (<ulink url="http://raphaeljs.com/">http://raphaeljs.com</ulink>) is a small JavaScript library that uses SVG as a base. Raphaël equalizes the differences between browsers and emulates the features and benefits of SVG in Internet Explorer with VML. Raphaël enables front-end developers to use vector graphics in a cross-browser compatible way with only a single source to maintain.</para>
   <para/>
   <para>Raphaël can be used to create rich interactive graphics, creating vector elements that are native to the browser and the DOM. Native DOM elements are exposed to JavaScript, allowing for them to be used in the same manner as any other HTML element. Raphaël can attach JavaScript handlers, events, animations, and other features native to JavaScript to SVG/VML elements created in Raphaël. Raphaël works in IE6+, FF3+, Safari 3+, and Opera 9.5+.</para>
   <para/>
   <para>jQuery (<ulink url="http://www.jquery.com/">http://www.jquery.com</ulink>), a popular JavaScript framework used to simplify HTML document traversing, event handling, animating, and Ajax interactions for rapid web development, can be used on top of Raphaël for additional interactivity and management of SVG in the browser.</para>
   <para/>
   <para>This paper will demonstrate how Raphaël works, how it can be used in all browsers, why the world needs another JavaScript or SVG library, limitations of both Raphaël and SVG in the browser, comparisons with existing SVG browser solutions, and a demo of the Raphaël API and its capabilities.</para>
   <para/></sect1><sect1><title>Special Acknowledgments</title>
   <para/>
   <para>All of the work in this paper and the accompanying presentation could not have been achieved without the hard-work and prescient work of Dmitry Baranovskiy, the author of the Raphaël JavaScript Library. His website is: <ulink url="http://dmitry.baranovskiy.com/">http://dmitry.baranovskiy.com</ulink>. He can be reached at his e-mail address: <ulink url="mailto:dmitry@baranovskiy.com">dmitry@baranovskiy.com</ulink>.</para>
   <para/></sect1><sect1><title>Raphaël Examples</title>
   <para/><sect2><title>Hello World - Code</title>
   <para/>
   <para>This example illustrates how to use the Raphaël library with the jQuery library. jQuery is not required to use Raphaël, but using the DOM manipulation and selector engine (known as Sizzle) saves a lot of effort for very little cost. This example is located online at: http://raphaeljs.com/text-rotation.html.</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/></sect2><sect2><title>Hello World - Output</title>
   <para/>
   <para>The output of this code would result in the following:</para>
   <para>
      <inlinegraphic fileref="embedded:graphics1" width="3.8472inch" depth="0.8472inch"/>And as you move your mouse, the words would rotate at different intervals relative to each other:</para>
   <para>
      <inlinegraphic fileref="embedded:graphics2" width="4.0138inch" depth="3.2083inch"/>The equivalent SVG to create the basis for this effect would be, not including the rotation based on mouse position:</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <para>Additionally, the equivalent VML is created:</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/></sect2><sect2><title>Hello World - Analyzing the JavaScript Code</title>
   <para/>
   <para>Decomposing this code, we can see how Raphaël transforms this JavaScript code into SVG/VML.</para>
   <para/>
   <para>1) Declare the Raphaël Canvas:</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist></sect2><sect2><title/>
   <orderedlist>
      <listitem>
         <para>Declare variables and find DOM nodes:</para>
      </listitem>
   </orderedlist>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <orderedlist>
      <listitem>
         <para>Raphaël allows for vector objects to be placed into JSON/JavaScript data structures and modified through loops:</para>
      </listitem>
   </orderedlist>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <orderedlist>
      <listitem>
         <para>Detect the mouse movement and then rotate each text vector node. jQuery is used here in place of awful cross-browser mouse movement detection:</para>
      </listitem>
   </orderedlist>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/></sect2><sect2><title>Hello World - Observations</title>
   <para/>
   <para>Notice that Raphaël takes data from existing HTML on the page and uses it in generating SVG/VML. This DOM interaction is one of the main benefits in using Raphaël, as it can be used both during initialization and execution. Here, the text node is rotated based on JavaScript’s detection of mouse behavior. Additionally, the text node is populated based on existing data. Raphaêl is as much of the DOM as any other element.</para>
   <para/></sect2><sect2><title>Layered Shape - Code</title>
   <para/>
   <para>In Raphaël, complicated layered shapes can be easily created in just a few lines of code. And like everything produceable in Raphaël, it is cross-browser without modifications.</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <informaltable frame="all">
      <tgroup cols="2">
         <thead>
            <row>
               <entry>
                  <title>Firefox 3.5</title>
               </entry>
               <entry>
                  <title>Internet Explorer 8</title>
               </entry>
            </row>
         </thead><tbody><row>
            <entry>
               <para>
                  <inlinegraphic fileref="embedded:graphics3" width="3.0925inch" depth="3.4965inch"/>
               </para>
            </entry>
            <entry>
               <para>
                  <inlinegraphic fileref="embedded:graphics4" width="3.1161inch" depth="3.498inch"/>
               </para>
            </entry>
         </row></tbody></tgroup>
   </informaltable></sect2><sect2><title>Firefox 3.5</title></sect2><sect2><title>Internet Explorer 8</title>
   <para/></sect2><sect2><title>Layered Shape - Decomposition</title>
   <para/>
   <para>The shadow:</para>
   <para>
      <inlinegraphic fileref="embedded:graphics5" width="4.8472inch" depth="4.75inch"/>
   </para>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <para>The sphere:</para>
   <para>
      <inlinegraphic fileref="embedded:graphics6" width="4.6945inch" depth="5.25inch"/>
   </para>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <para>The sphere’s reflection:</para>
   <para>
      <inlinegraphic fileref="embedded:graphics7" width="4.0417inch" depth="4.5972inch"/>
   </para>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <para/></sect2></sect1><sect1><title>Raphaël API</title>
   <para/>
   <para>The document, available online at <ulink url="http://raphaeljs.com/reference.html">http://raphaeljs.com/reference.html</ulink>, provides explanations for these native objects, object methods, properties, and attributes.</para><sect2><title/></sect2><sect2><title>Native Methods and Objects</title>
   <para/>
   <informaltable frame="all">
      <tgroup cols="4">
         <colspec colnum="1" colname="c1"/>
         <colspec colnum="2" colname="c2"/>
         <colspec colnum="3" colname="c3"/>
         <colspec colnum="4" colname="c4"/>
         <thead>
            <row>
               <entry>
                  <title>Vector Objects</title>
               </entry>
               <entry>
                  <title>Object Methods</title>
               </entry>
               <entry>
                  <title>Object Properties</title>
               </entry>
               <entry>
                  <title>Object Attributes</title>
               </entry>
            </row>
         </thead><tbody><row>
            <entry>
               <para>circle</para>
               <para>ellipse</para>
               <para>image</para>
               <para>path</para>
               <para>rect</para>
               <para>text</para>
            </entry>
            <entry>
               <para>animate</para>
               <para>attr</para>
               <para>getBBox</para>
               <para>hide</para>
               <para>insertAfter</para>
               <para>insertBefore</para>
               <para>remove</para>
               <para>rotate</para>
               <para>scale</para>
               <para>show</para>
               <para>stop</para>
               <para>toBack</para>
               <para>toFront</para>
               <para>translate</para>
            </entry>
            <entry>
               <para>fill</para>
               <para>fill-opacity</para>
               <para>font</para>
               <para>font-family</para>
               <para>font-size</para>
               <para>gradient</para>
               <para>opacity</para>
               <para>rotation</para>
               <para>scale</para>
               <para>stroke</para>
               <para>stroke-dasharray</para>
               <para>stroke-linecap</para>
               <para>stroke-linejoin</para>
               <para>stroke-miterlimit</para>
               <para>stroke-opacity</para>
               <para>stroke-width</para>
               <para>translation</para>
            </entry>
            <entry>
               <para>cx</para>
               <para>cy</para>
               <para>height</para>
               <para>path</para>
               <para>r</para>
               <para>rx</para>
               <para>ry</para>
               <para>src</para>
               <para>width</para>
               <para>x</para>
               <para>y</para>
               <para/>
            </entry>
         </row></tbody></tgroup>
   </informaltable></sect2><sect2><title>Vector Objects</title></sect2><sect2><title>Object Methods</title></sect2><sect2><title>Object Properties</title></sect2><sect2><title>Object Attributes</title>
   <para/></sect2><sect2><title>Extensibility</title>
   <para/>
   <para>Raphaël can be extended to allow for plug-ins to use the highest-order functions in both the Raphaël canvas and in Raphaël elements themselves. From the documentation:</para>
   <para/><sect3><title>Adding your own methods to canvas</title>
   <para/>
   <para>You can add your own method to the canvas. For example if you want to draw pie chart, you can create your own pie chart function and ship it as a Raphaël plugin. To do this you need to extend Raphael.fn object. Please note that you can create your own namespaces inside fn object. Methods will be run in context of canvas anyway. You should alter fn object before Raphaël instance was created, otherwise it will take no effect.</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/></sect3><sect3><title>Adding your own methods to elements</title>
   <para/>
   <para>You can add your own method to elements. This is useful when you want to hack default functionality or want to wrap some common transformation or attributes in one method. In difference to canvas methods, you can redefine element method at any time.</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/>
   <para/></sect3></sect2><sect2><title>JavaScript Interaction with jQuery</title>
   <para/>
   <para>When Raphaël is used in conjunction with jQuery, all Raphaël objects can be transparently passed to jQuery for jQuery objects. These JQuery objects can be used just as any other DOM element that is handled by jQuery, including, but not limited to, animations, styling, timers, event handling, arbitrary data stores, and event and mouse bindings. </para>
   <para/>
   <para>While none of these JavaScript methods are specific to jQuery and can all be written in pure JavaScript, the simple fact that jQuery smoothes out many of the differences between different browsers means that you can continue to write cross-browser code in JavaScript with minimal effort necessary to account for one browser over another. </para>
   <para/></sect2></sect1><sect1><title>Considerations &amp; Lessons</title>
   <para/><sect2><title>Performance</title>
   <para/>
   <para>Of the few differences between different browsers exposed in the Raphaël API, the largest difference by far is that of performance. SVG runs with speed and perceived smoothness in all browsers that support it. All modern browsers that currently support SVG are also, in fact, putting in a great amount of effort into developing SVG as their implementations correspond to the SVG spec, as well as speed improvements that are found with modern rendering engines which precompute and prefetch objects and interactions with aplomb.</para>
   <para/>
   <para>However, Internet Explorer, which only supports VML, renders vector elements in a fraction of the speed. Additionally, Internet Explorer 8 actually increases the delay in interacting with VML elements through JavaScript. Any loops in JavaScript that interact with elements have a slightly noticeable delay, and as the number of elements increase, performance degrades much quicker in Internet Explorer than it does in SVG-capable browsers. </para>
   <para/>
   <para>This difference in rendering speed and interaction delays is attributable only to Internet Explorer’s implementation of VML. A comparable implementation of SVG in Internet Explorer would be expected to perform on a level consistent with all other modern browsers.</para>
   <para/></sect2><sect2><title>Accessibility</title>
   <para/>
   <para>Raphaël, as a JavaScript framework, produces SVG and VML on the client-side. When developers talk about accessibility, they often mean one of two terms. The first is accessibility in terms of search engine optimization (SEO) and marketing (SEM). The second is in terms of usability and reach for those using non-standard forms of browsing.</para>
   <para/>
   <para>While Raphaël interprets JavaScript commands into cross-browser vector commands, it is only able to do so after the page is rendered. This means that concerns about Search Engines being able to access the data that is “locked up” in the JavaScript code are the same as concerns about Flash. Google has stated its dedication to unlocking content from Flash<footnote>
         <para> <ulink url="http://searchengineland.com/google-now-crawling-and-indexing-flash-content-14299">http://searchengineland.com/google-now-crawling-and-indexing-flash-content-14299</ulink> 
         </para>
      </footnote> and if Raphaël becomes a widely enough used technology, there is no reason to believe that Google will not be able to parse the resulting SVG/VML from interpreted Raphaël JavaScript code.</para>
   <para/>
   <para>As for accessibility with screen readers, Raphaël produces markup that is inserted directly into the DOM, which means that the markup produced from interpreting Raphaël’s JavaScript commands are no different than any other markup that is directly embedded in the page, such as HTML or raw SVG. Screen readers will be able to take advantage of the fact that Raphaël makes use of the DOM in a way that Flash cannot.</para>
   <para/>
   <para>Additionally, if Raphaël is interacting with data that is on the page, such as in a chart or graph, a screen reader will still be able to take advantage of the raw data, in the case of JavaScript being disabled, or the screen reader using the data that is on the page regardless of presentation due to SVG markup.</para>
   <para/></sect2><sect2><title>API Changes</title>
   <para/>
   <para>With an unfinished feature set, Raphaël has had to change the API a few times over the course of releasing a version 1.0. A number of methods have been removed or merged into other methods. While this is an unfortunate side-effect of optimizing code reuse, Dmitry explains his rationale on his personal blog:</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist></sect2><sect2><title/></sect2><sect2><title>Caching</title>
   <para/>
   <para>JavaScript memoization has been implemented in Raphaël to achieve a drastic speed-up in the reuse of functions, esp. in loops and cycles. Memoization is a method used to increase speed of slow functions by caching the arguments and results. The expense of memoization is a marginal use of additional memory at the benefit of a gain in speed in reused functions.</para>
   <para/>
   <para>The limitations of this method of caching are quite evident. Only scalar values and arrays can be used as arguments in memoized JavaScript functions. Objects can not be passed in due to browser security limitations and prohibitions. However, this guarantees idempotency in the function, as the arguments can be dereferenced and stored for cache lookups. </para>
   <para/></sect2><sect2><title>Limitations</title>
   <para/>
   <para>Due to the DOM based nature of SVG and VML, the number of elements that can be drawn or interact is limited based on a browser basis. Canvas and Flash, due to their thicker wall between the browser and the canvas, allow for many more elements. Additionally, more elements, in SVG and the DOM, means worse performance, whereas Canvas and Flash do not degrade under such circumstances.</para>
   <para/>
   <para>Secondly, Raphaël only produces SVG and VML after page load. The consequences of this are two-fold: (a) there are no SEO benefits for markup that is not on the page at load time, and (b) there is a slight delay for any SVG/VML to appear on the page, since Raphaël waits until it is run, which must be either after the element in the DOM that will serve as the Raphaël canvas has loaded, or during the document.ready() event.</para>
   <para/></sect2><sect2><title>Alternatives to Raphaël</title>
   <para/>
   <para>There are a few existing solutions to the problem of creating interactivity and animated vector graphics. One solution, Adobe Flash, sits closer to the extreme of not allowing the browser to have any control, while SVG is a solution that gives full control to the browser, where some browsers go so far as to display the same code in a slightly-different manner than the next browser. Additionally, using JavaScript on the &lt;canvas&gt; tag, or using JavaScript directly on the DOM, allows for interaction between elements on the page, but elements in a canvas are sand-boxed inside the canvas, whereas SVG elements are native to the DOM. </para>
   <para/>
   <para>SVGWeb, an open-source project that is hosted by Google, is a library that converts SVG into a Flash-based canvas on browsers that do not support SVG. The performance of Flash can be noticeably faster, and SVGWeb creates Flash-based canvases that perform similarly to the native SVG implementation. However, SVGWeb suffers from the same constraints as Raphaël with regards to lack of SEO benefits. Additionally, SVGWeb locks the shapes and content behind Flash, which degrades accessibility, and also makes JavaScript interaction not possible. However, JavaScript interactions with elements is not supported, as SVGWeb uses a Flash sandbox in IE (and on other browsers when deliberately set), which prevents the ability to interact with vector elements in JavaScript.</para>
   <para/>
   <para>SMIL, a W3C standard for defining timing, animations, layout, and multimedia embeds, is only well-supported on Firefox, Safari, and Opera. Raphaël’s goal of being entirely cross-browser precludes the use of SMIL for animations. But SMIL is only one of a handful of browser-native ways of animating vector elements of SVG. Instead, Raphaël relies on JavaScript to produce timers and animations, which also offers better user interface capabilities than SMIL. CSS Animation support also works on Raphaël elements, but is only supported by Safari 4.</para>
   <para/>
   <para>Canvas is not a direct competitor to SVG. Canvas is not vector-based but rather bitmap-based. Canvas is more of a complimentary technology to SVG, being used to support graphics that are more prevalent in games and graphs, rather than the vectorized shapes of SVG. However, Canvas is less object-oriented than SVG, due to the drawing nature of Canvas. SVG’s elements can be “stored” on the page, better suited to interacting with their data, whereas Canvas paints on to the page, not inherently keeping track of shapes and objects. A recent blog comment on the difference between SVG and Canvas illustrates a common difficulty with Canvas<footnote>
         <para> http://neilobremski.wordpress.com/2009/04/30/svg-vs-canvas#comment-89 </para>
      </footnote>:</para>
   <para/>
   <orderedlist>
      <listitem/>
   </orderedlist>
   <para/></sect2></sect1><sect1><title>Dojo, which has support for many of the same drawing tools provided by Raphaël does not allow for support with other client-side libraries such as jQuery or mootools. Raphaël allows for the ability to drop in another JavaScript library and have it seamlessly work with Raphaël objects. </title></sect1><sect1><title/></sect1><sect1><title>Real World Examples</title>
   <para/>
   <para>Raphaël is currently being used in a number of places on the web. Two notable examples:</para>
   <para/><sect2><title>The Washington Post / EVRI</title>
   <para/>
   <para>At the bottom of every article page is an EVRI widget which shows topics extracted from the article and the connections between different topics. See this article for an example: <ulink url="http://www.washingtonpost.com/wp-dyn/content/article/2005/11/29/AR2005112901464.html">http://www.washingtonpost.com/wp-dyn/content/article/2005/11/29/AR2005112901464.html</ulink>. </para>
   <para/>
   <para>
      <inlinegraphic fileref="embedded:graphics8" width="4.028inch" depth="4.139inch"/>
   </para></sect2><sect2><title>Daylife</title>
   <para/>
   <para>Daylife, a news aggregator with articles, photos, and quotes on many major topics in the news, uses Raphaël on all topic pages. See the Barack Obama topic page on Daylife for an example: <ulink url="http://beta.daylife.com/topic/Barack_Obama">http://beta.daylife.com/topic/Barack_Obama</ulink>. </para></sect2></sect1><sect1><title>
      <inlinegraphic fileref="embedded:graphics9" width="4.272inch" depth="5.4717inch"/>Summary</title>
   <para/>
   <para>Similar to jQuery, an open source JavaScript library that simplifies the interaction between HTML and JavaScript, Raphaël simplifies the creation of cross-browser vector graphics and the necessary interaction between the SVG/VML objects and HTML.</para>
   <para/></sect1><para/>
</article>
