- 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