W3C home > Mailing lists > Public > www-style@w3.org > April 2012

Re: [css3-transforms] Interpolation of relative transitions

From: louis-rémi Babé <lrbabe@gmail.com>
Date: Thu, 5 Apr 2012 01:14:03 +0200
Message-ID: <CALXxKfD4xiRHo6uCqjB0p=MFV2EKLksDXSyo5ptnAwawiOCYNQ@mail.gmail.com>
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 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:52 GMT