- From: Shane Stephens <shans@google.com>
- Date: Mon, 28 Mar 2011 14:12:33 +1100
- To: Shane Stephens <shans@google.com>, www-svg@w3.org
- Cc: Cameron McCormack <cam@mcc.id.au>
- Message-ID: <BANLkTinSDCtdxJyP3-S4Aqn=7K5CwbJiSw@mail.gmail.com>
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