- From: louis-rémi Babé <lrbabe@gmail.com>
- Date: Thu, 5 Apr 2012 01:14:03 +0200
- To: www-style@w3.org
2012/4/4 Tab Atkins Jr. <jackalmage@gmail.com>: > On Wed, Apr 4, 2012 at 8:15 AM, louis-rémi Babé <lrbabe@gmail.com> wrote: >> Hi, >> >> It is really convenient for a web author to be able to trigger a transition >> of a style property relative to its current state. For example, to animate >> an (absolutely positioned) element with a 200px transition to the right, one >> can do: >> >> elem.style.transition = "all ease 1s"; >> elem.style.left = parseFloat( window.getComputedStyle( elem ).left ) + 200 + >> "px"; >> >> Now imagine I want to rotate an element by 300° clockwise, relative to its >> current transform: >> >> elem.style.transition = "all ease 1s"; >> var cs = window.getComputedStyle( elem ).transform; >> elem.style.transform = ( cs != "none" ? cs : " " ) + " rotate(300deg)"; >> >> According to the draft of the interpolation algorithm[1], if the current >> transform of the element is "none", it will be animated as expected. >> Otherwise the web author has no way to predict if the element will be >> animated clockwise or not, as illustrated in this jsfiddle : >> http://jsfiddle.net/rhukk/6/ >> If the web author tries to rotate an element by 360° relative to its current >> transform, no animation could happen at all. > > For the benefit of those reading along, this happens because the > "from" and "to" states are non-matching animation lists (the "to" > state has an extra rotate() transform at the end), so each state is > instead just mashed together into a single matrix3d() transform, > broken apart into a list of matrix3d()s that handle just the > translation/rotation/etc aspect, and then numerically interpolated. > This causes rotations, in particular, to no longer reliably > interpolate based on the relative angles; you can't easily predict > whether the matrix-based interpolation will produce a CW or CCW > rotation (which is obvious in an angle-based rotation), and you can't > rotate more than 360deg, because the "extra turns" get wiped out in > the transition to a matrix. > > >> There's however a simple way to make those transitions happen as expected : >> it is easy to detect that the 'from' transform is a single function of same >> type and same value as the first function of the 'to' transform. This >> function can be "removed" from both function lists while they're being >> interpolated, and applied on each step of the transition before the list of >> interpolated functions. >> For example, if the 'from' is 'matrix(1,0,0,1,0,0)' and the 'to' is >> 'matrix(1,0,0,1,0,0) rotate(360deg)' then the function lists would be >> interpolated as if 'from' was 'none' and 'to' was 'rotate(360deg)', but at >> each step of the transition, the transform of the element should be >> 'matrix(1,0,0,1,0,0) rotate(<interpolated value for this step>)'. >> >> Would it be possible to add such a condition to the current #animation >> section of the transform draft? > > So your proposal is that, whenever the "from" and "to" lists don't > match, first remove the common prefix of transforms they share (if > any) before running through the list again (and if removing the common > prefix removes the entirety of one state, treat it as 'none')? > > This seems reasonable to me. It has a better chance of achieving the > intended effect in common cases such as the one you bring up, and will > fall into the "just mash it all together" failure-case somewhat less > often. It also shouldn't be too expensive of an operation. > > Even if we make this change in level 4 (since we're trying to get > level 3 wrapped up so we can drop prefixes), it should be okay, since > it should generally be a strict enhancement in behavior. Thank you for the additional context + summary, I'm glad you find it reasonable and acceptable. > I wonder if we could take this a bit further - rather than just > removing identical prefixes (where both the functions and arguments > match), we could find the prefix that just has functions matching, > with potentially different arguments. Then we can interpolate that > common prefix normally, and run the rest of the two states back > through the list again as you describe, either matching the remainder > up with identity transforms or mashing the remainder up into a matrix. > > ~TJ I cannot see any practical use case for this generalization at the moment, but I can't see any reason to oppose to it either. Lr PS: sorry about the double email TJ
Received on Wednesday, 4 April 2012 23:14:52 UTC