Showing posts with label SVG. Show all posts
Showing posts with label SVG. Show all posts

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 <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






Using Google's App Engine to serve SVG files

I've been tinkering with SVG Animation support in HTML5 lately and since I don't like to maintain web servers myself I needed somewhere convenient to host my Javascript and SVG creations. My friend Jeff Bailey suggested that I check out Google's App Engine.

While App Engine may be a bit overkill for serving static content, recent additions to SVG allow animation elements. What appears to be a static SVG file may in-fact have embedded Javascript and SVG Animation elements.

App Engine has proven to be a great environment to work with but in order for it to properly serve SVG files such that a browser can display the images rather than the XML data the server needs to export the proper MIME type information for SVG files. This is accomplished by telling the App Engine server how to serve the SVG files.

App Engine supports both Java and Python servers. I use the Python server and the server configuration files are in YAML. The following YAML fragment is added to the project's app.yaml configuration file to support SVG MIME types:
handlers:
- url: /(.*\.svg)
static_files: static/\1
upload: static/(.*\.svg)
mime_type: image/svg+xml

The following is a little tech demo I've made using App Engine:











Note: SVG Animation support is still in development by most browsers. The ones I've tested are Chrome, Opera, and Firefox. The level of conformance for each of these browsers vary. This demo works best on Chrome 11.0.696.16 beta. The spacing of the train-cars is a little off in Opera. I'm not sure which browser is the most spec conformant.

The following app.yaml file is complete example that is used for the rsasandbox project:
application: rsasandbox
version: 1
runtime: python
api_version: 1

handlers:
- url: /(.*\.(html|png|jpg|gif))
static_files: static/\1
upload: static/(.*\.(html|gif|png|jpg))

- url: /(.*\.svg)
static_files: static/\1
upload: static/(.*\.svg)
mime_type: image/svg+xml

- url: /(.*\.xml)
static_files: static/\1
upload: static/(.*\.xml)