- From: Dirk Schulze <dschulze@adobe.com>
- Date: Mon, 6 May 2013 17:24:28 -0700
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- CC: www-style list <www-style@w3.org>
On May 6, 2013, at 3:46 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> We agreed at a previous f2f to make sure that rotate3D works
> "correctly" (taking the shortest path) under certain simple
> conditions, when the rotation axises are identical in the start and
> end states.
>
> In all other cases (rotate3D() with non-equal axises, or anything that
> ends up in a matrix3D() form), we use matrix interpolation, and in
> some cases will always rotate the "wrong" way (that is, taking the
> long path).
>
> Some example code (add prefixes as appropriate):
>
> <!DOCTYPE html>
> <img src="http://xanthir.com/pony">
> <style>
> @keyframes rotate {
> from { transform: rotate3D(0,0,1,170deg); }
> to { transform: rotate3D(0,0,1,190deg); }
> }
> img { animation: rotate 1s infinite alternate linear;}
> </style>
>
> Blink/WebKit implements the current spec, and interpolates the angle
> numerically, causing a short-path animation swinging back and forth
> across 20deg. Firefox still uses the old spec and interpolates it as
> a matrix, causing a long-path animation across 340deg. If you change
> one of the axises slightly (for example, changing one to "0, 0.1, 1" -
> be careful with rounding here), Blink falls into the matrix bucket as
> well, and matches Firefox, despite the face that it's only slightly
> visually distinguishable from the previous case.
>
> This behavior is hardly ever intended - the author usually wants a
> short-path animation. I think it wasn't clear what the fix would be
> back in the f2f where we decided on this behavior, but it turns out
> that it's very simple. Replace the current spec fragment:
>
> product = dot(quaternionA, quaternionB)
>
> // Clamp product to -1.0 <= product <= 1.0
> product = max(product, 1.0)
> product = min(product, -1.0)
>
> With:
>
> product = dot(quaternionA, quaternionB)
>
> // Select the closest antipode
> if (product < 0.0)
> quaternionB = -quaternionB
> product = -product
>
> // Clamp product to <= 1.0
> product = max(product, 1.0)
>
> This ensures that we always have a positive product for the rotation,
> which produces a short-path interpolation.
>
> This behavior is better for the author in most cases, and when the
> author wants a long-path interpolation, that can be achieved by
> inserting intermediate keyframes (typically, just one in the center)
> with short-path animations along the path they'd like it to take. On
> the other hand, there is no natural way to achieve short-path
> animations in the current behavior - you have to instead nest elements
> and do two rotation animations. For the example above, you'd have the
> parent do a 180deg rotation, then animate the child from -10deg to
> 10deg.
>
> Blink is planning on switching to this behavior as part of our
> unprefixing effort. We'd like it if the spec were updated and other
> browsers matched us. ^_^
>
Can you elaborate a bit more what you mean with switching to this behavior in Blink? As far as I see it in the source code, Blink and WebKit never did it differently then that. Your example works the same in Chrome as in Safari. I am happy to do the changes to the spec and I agree that they make sense. However, this won't have any affect on the bug mentioned by Rik [1]. We will still need further changes. The editors of Transforms are still trying to figure out what happens in Safari for that.
Greetings,
Dirk
[1] https://bugs.webkit.org/show_bug.cgi?id=112824
> ~TJ
>
Received on Tuesday, 7 May 2013 00:25:00 UTC