Sunday, April 24, 2011

Embedding SVG images that use Javascript in Blogger/Blogspot Posts

In Blogger posts if you want to embed SVG images that make use of JavaScript (for animation control) you need to use the html <embed> tag since <object> and <img> don't allow scripting. You'll have to edit the HTML directly to use the <embed> tag as in the following example:
<embed src="http://rsasandbox.appspot.com/embed.svg" type="image/svg+xml" width="230" height="230"/>
The following embedded SVG example uses the <animateMotion> SVG element with repeatCount="indefinite" so that the animation continues indefinitely.  The animation is paused and restarted by calling JavaScript functions as a result of SVG element onclick event processing, e.g., onclick='Pause(evt)' and onclick='Play(evt)'.

http://rsasandbox.appspot.com/embed.svg

Saturday, April 23, 2011

SVG Animation and The SVG DOM beginElement() Method

This example attempts to restart the animation using the SVG DOM beginElement() method. It keeps the bubble going back and forth along a zig-zag path.  It restarts the animation once the bubble has returned to the start position by using beginElement ( ) upon the original <animateMotion>.  The following SVG code is just the XML necessary to show the beginElement ( ) method call.

http://rsasandbox.appspot.com/beginElement-ex.svg










Note: If the example animation does not restart after one complete circuit it means that your browser (like Chrome) doesn't yet support the SVG DOM beginElement ( ) method.  The animation should restart properly in the Opera browser.
<script type="text/javascript" >
<![CDATA[
      function BeginAgain(bubble) {
          var bub = SVGDocument.getElementById(bubble);
          bub.beginElement();
      }
]]>
</script>
...
<animateMotion  id="bubble1am1" ...  >
...
<animateMotion  id="bubble2am1"
     begin="bubble1am1.end"
     ...
     onend="BeginAgain('bubble1am1')" >

SVG <animateMotion> "fill" Attribute Conformance

I've been tinkering with SVG AnimateMotion fill attribute conformance in various HTML5 capable browsers to try to figure out what is supposed to be the normative behavior.

The SVG Animation specification for the "fill" attribute indicates that the possible values for the attribute are fill = "freeze" | "remove".

freeze

The animation effect F(t) is defined to freeze the effect value at the last value of the active duration. The animation effect is "frozen" for the remainder of the document duration (or until the animation is restarted
remove

The animation effect is removed (no longer applied) when the active duration of the animation is over. After the active end of the animation, the animation no longer affects the target (unless the animation is restarted.
The specification defines fill="remove" as the default.

The following SVG Animation fragment demonstrates the use of "fill".

<use xlink:href="#engine_v2"
  id="engine1"
  visibility="visible"
  centered="no"
  x="-19.5"
  y="-7.5">
        <animateMotion
          id="engine1am1"
          dur="4s"
          keyPoints=".07; .92"
          keyTimes="0; 1"
          rotate="auto"
          repeatCount="1"
          calcMode="linear"
          restart="whenNotActive"
          fill="freeze" >
                <mpath xlink:href="#simple-track-path1" />
        </animateMotion>
        <animateMotion
          id="engine1am2"
          begin="engine1am1.end"
          dur="4s"
          keyPoints=".92; .07"
          keyTimes="0; 1"
          rotate="auto"
          repeatCount="1"
          calcMode="linear"
          restart="always"
          fill="freeze" >
                <mpath xlink:href="#simple-track-path1" />
        </animateMotion>
</use>

The following live SVG Animation example demonstrates the use of fill="none" (i.e., the default), fill="freeze", and fill="remove". In the animation a train car travels a path in one direction and then travels the path in the reverse direction using two consecutive AnimateMotion elements.


http://rsasandbox.appspot.com/anim6.svg
Note: You will only see this SVG image animated if your browser supports SVG Animation, even then your mileage may vary as the animation may have run and completed before it displays.  Click on the image to view it








The fill attribute for the first AnimateMotion element doesn't seem to matter when there are two consecutive AnimateMotion elements.  Only the second fill attribute matters and it determines the image state following the completion of the animation.

The Chrome browser, as of version 11.0.696.16 beta, finishes the animation in the following way:
Screenshot of Chrome

The Opera browser, as of version 11.01, finishes the animation in the following way:
Screenshot of Opera
Based on the reading of the specification I believe that Opera is performing correctly in this instance.

Unfortunately the behavior of the fill attribute changes when there aren't two consecutive elements of the same type.  The following example shows an animateTransform following an animateMotion as demonstrated by the following SVG example:

http://rsasandbox.appspot.com/anim7.svg

In this example the train car is supposed to travel along the path, turns around 180 degrees, and then travel back along the path.
This example only works under the Opera browser where the fill attribute is used with the animateTransform element, e.g., <animateTransform fill="freeze">.  This seems to be the correct behavior.  When fill="remove" the orientation of the train car returns to the original orientation, i.e., not rotated, after the animateTransform element rotates it.  With fill="freeze" the train car retains the rotate orientation.
Screenshot of Opera
Under the Chrome browser the train disappears following the <animateTransform fill="freeze"> element.  I believe this is a bug in the Chrome browser.  It seems to behave as expected in the <animateTransform fill="remove"> example.
Screenshot of Chrome