Re: SVG animateMotion specification clarification request

Hi Cameron,

The main problem with (MP * MR) * RT * AS is that container transforms are
affected by the motionPath's auto-rotation.  Hence if I do this:

<rect width="20" height="20" transform="translate(100, 100) scale(2,1)">
 <animateMotion path="M 0 0 c 0 150 150 150 150 0" begin="0" dur="3"
fill="freeze" rotate="auto"/>
 </rect>

then I get a very different motion path to if I do this:

<rect width="20" height="20" transform="translate(100, 100) scale(2,1)">
 <animateMotion path="M 0 0 c 0 150 150 150 150 0" begin="0" dur="3"
fill="freeze"/>
 </rect>

The translation of the container is modified by the rotation matrix in the
first case, but not the second.  So even thought the specified path is
identical in both cases, in the second case, I get a motion path that
consists of a bezier with the following control points: (0, 0), (150, 150),
(150, 150), (150, 0); whereas in the second the resulting path starts at
roughly (-100, 100), ends at roughly (250, -100), and is not symmetrical
across the Y axis.  This simply doesn't make sense, and that's even in the
complete absence of other animation primitives.  I'd be inclined to rule
this option out completely.

What that leaves is:

RT * (MP * MR) * AS (Opera's current behaviour)
RT * AS * (MP * MR) (The specified behaviour)

If as you suggest separating RT and AS is undesirable, then that would seem
to indicate leaving the specification as is.


> You can work around the ordering if it is a problem for your use by
> adding an extra group, and this is the same solution regardless of
> whether we choose motion animation before or after element transform.
>
> Erik made the argument on public-svg-wg that at least one SVG animation
> authoring tool likely (based on some content) assumes that the element’s
> transform is post-multiplied on to the motion transform.  I don’t see a
> particularly strong argument one way or the other in this thread.  I’m
> inclined then to go with this behaviour, i.e. (MP * MR) * RT * AS.
>

The counter-argument is that with WebKit's change there are now no viewers
that support (MP * MR) * RT * AS, and that in the absence of an extra
animation (the AS component), Opera, WebKit and Firefox all render correctly
right now if the RT * AS * (MP * MR) approach is taken.


> Any thoughts on going this way?
>

For what it's worth, I disagree with Olaf. Excluding animateMotion, there is
an invariant across all transform-modifying primitives in SVG that provides
a simple heuristic for determining the multiplication order of the
transforms.  Nesting implies an order (B nested within A -> A * B), and
textual order implies an order (B after A with the same parent implies A *
B).  This invariant is reasonably easy to understand and is quite intuitive
while authoring SVG, as it's very clear which order the transforms apply in.

Ideally, I think animateMotion should follow the same rules.  What this
means in concrete terms is that:

<rect width="20" height="20" transform="translate(100, 100) scale(2,1)">
 <animateMotion path="M 0 0 c 0 150 150 150 150 0" begin="0" dur="3"
fill="freeze" rotate="auto"/>
 <animateTransform attributeName="transform" type="scale" from="1 1"
to="1 2" begin="0" dur="3" additive="sum" fill="freeze"/>
</rect>

Leads to RT * (MP * MR) * AS

<rect width="20" height="20" transform="translate(100, 100) scale(2,1)">
 <animateTransform attributeName="transform" type="scale" from="1 1"
to="1 2" begin="0" dur="3" additive="sum" fill="freeze"/>
 <animateMotion path="M 0 0 c 0 150 150 150 150 0" begin="0" dur="3"
fill="freeze" rotate="auto"/>
</rect>

Leads to RT * AS * (MP * MR).

Olaf indicates that we should not use viewer behaviour to influence the
specification, but I don't think that this is the issue here.  The issue is
that the specification is itself already extremely complex and difficult to
understand, and that animateMotion currently seems to be a special case
which breaks an invariant that is otherwise maintained.  The fact that no
viewers implemented the correct (as specified) behaviour until I modified
the WebKit implementation in December last year, and the fact that even the
official test suite conflicts with the specified behaviour, are strong
indicators of a problem with the specification.

Allowing RT * (MP * MR) * AS to occur when the animateMotion occurs
textually before the animateTransform, and RT * AS * (MP * MR) to occur when
not will result in a clearer and more consistent *specification*, which will
*as a consequence* lead to more consistency in the implementations.

I don't see that there's a problem with animateMotion and animateTransform
being given equal status - both impact the transform by adding time-varying
terms into the CTM.  The current argument is simply about the order in which
those terms should appear - animation start times are irrelevant as the
underlying value is computed at render-time by collapsing the CTM.  Of
course I could be completely wrong and would love to see counter-examples
:-)

    -Shane


>
> --
> Cameron McCormack ≝ http://mcc.id.au/
>

Received on Monday, 28 March 2011 03:13:10 UTC