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






No comments:

Post a Comment