W3C home > Mailing lists > Public > public-fx@w3.org > April to June 2013

Re: Transform animation order

From: Brian Birtles <bbirtles@mozilla.com>
Date: Thu, 06 Jun 2013 09:11:58 +0900
Message-ID: <51AFD3CE.1060706@mozilla.com>
To: public-fx@w3.org
CC: Kari Pihkala <kari.pihkala@gmail.com>
Hi Kari!

Thank you for your very helpful message! Yes, you are right, the 
prioritisation model used by SVG can be problematic, particularly with 
regards to non-commutative addition.

Currently, the workaround is to split up the transforms into different 
groups like so:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 150">
   <g transform="translate(50,30) rotate(0) translate(-15,-15)">
     <animateTransform id="t0" dur="1" attributeName="transform" 
type="translate" keyTimes="0;1" values="50,30;50,30"/>
     <animateTransform id="t1" begin="1" dur="2" 
attributeName="transform" type="translate" keyTimes="0;1" 
values="50,30;250,30" repeatDur="indefinite"/>
     <rect width="30" height="30" fill="red">
       <animateTransform id="t2" dur="2" attributeName="transform" 
type="rotate" keyTimes="0;1" values="0;360" repeatDur="indefinite" 
additive="sum"/>
       <animateTransform id="t3" dur="2" attributeName="transform" 
type="translate" keyTimes="0;1" values="-15,-15;-15,-15" fill="freeze" 
additive="sum"/>
     </rect>
   </g>
</svg>


With Web Animations we have attempted to address these limitations in 
the following ways:

* Separating start time from delay -- this allows you to control when 
the animation actually begins independently of its prioritisation.
* Timing groups -- the priority is established per outermost group (i.e. 
player) start time and then within a group, priority is based on tree 
order. This likewise allows further control over priority.

(Note that the animation priority section of the specification was 
significantly revised just a couple of days ago so if you haven't looked 
at it recently I would encourage you to check it again.)

How this will be mapped onto SVG is yet to determined.


One possibility is to expose delay as a separate attribute. Doing so 
would mean your use case could be realised as follows:

<svg>
   <rect width="30" height="30" fill="red" transform="translate(50,30) 
rotate(0) translate(-15,-15)">
     <animateTransform id="t0" dur="1" attributeName="transform" 
type="translate" keyTimes="0;1" values="50,30;50,30"/>
     <animateTransform id="t1" delay="1" dur="2" 
attributeName="transform" type="translate" keyTimes="0;1" 
values="50,30;250,30" repeatDur="indefinite"/>
     <animateTransform id="t2" dur="2" attributeName="transform" 
type="rotate" keyTimes="0;1" values="0;360" repeatDur="indefinite" 
additive="sum"/>
     <animateTransform id="t3" dur="2" attributeName="transform" 
type="translate" keyTimes="0;1" values="-15,-15;-15,-15" fill="freeze" 
additive="sum"/>
   </rect>
</svg>

(I've omitted the begin="0" attributes since that is the default value.)


Another possibility is to map 'begin' to start time on an outermost 
animation element and to start delay on a nested animation element 
(child of a group). In that case, your use case may look like:

<svg>
   <rect width="30" height="30" fill="red" transform="translate(50,30) 
rotate(0) translate(-15,-15)">
     <par>
       <animateTransform id="t0" dur="1" attributeName="transform" 
type="translate" keyTimes="0;1" values="50,30;50,30"/>
       <animateTransform id="t1" begin="1" dur="2" 
attributeName="transform" type="translate" keyTimes="0;1" 
values="50,30;250,30" repeatDur="indefinite"/>
       <animateTransform id="t2" dur="2" attributeName="transform" 
type="rotate" keyTimes="0;1" values="0;360" repeatDur="indefinite" 
additive="sum"/>
       <animateTransform id="t3" dur="2" attributeName="transform" 
type="translate" keyTimes="0;1" values="-15,-15;-15,-15" fill="freeze" 
additive="sum"/>
     </par>
   </rect>
</svg>

Both options have complications and there are likely other options still 
to be considered. My next task after we finish preparing to publish FPWD 
will to be to start work on the SVG integration. For now, however, I 
think the Web Animations model can address this use case. What do you think?

Best regards,

Brian


(2013/06/05 19:58), Kari Pihkala wrote:
> Hi!
>
> I'm creating SVG animations and I'm facing problems with transform
> animations and the underlying animation model. This might interest you
> as you are developing the next version.
>
> I want to have a rectangle that spins and after a while it also starts
> moving to the right. The spinning will repeat forever and once the
> rectangle is on the right edge of the viewbox, it jumps to the left and
> repeats moving.
>
> The problem is that the animateTransform elements need to be applied in
> order t1, t2, t3 to apply the transforms correctly. However, the real
> order is t2, t3, t1 because t1 begins later than t2 and t3. See the SVG
> below for the elements.
>
> The t0 element is there just to translate the rectangle while it is not
> moving and to exclude that static part from repeating. The document does
> not animate correctly because of the problem, except if you change t1 to
> start at 0, but then the static period t0 is missed. Another way is to
> include the static period t0 in t1 using keyTimes/values, but then the
> static period is repeated, which is not desired.
>
> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 300 150">
>    <rect width="30" height="30" fill="red" transform="translate(50,30)
> rotate(0) translate(-15,-15)">
>      <animateTransform id="t0" begin="0" dur="1"
> attributeName="transform" type="translate" keyTimes="0;1"
> values="50,30;50,30"/>
>      <animateTransform id="t1" begin="1" dur="2"
> attributeName="transform" type="translate" keyTimes="0;1"
> values="50,30;250,30" repeatDur="indefinite"/>
>      <animateTransform id="t2" begin="0" dur="2"
> attributeName="transform" type="rotate" keyTimes="0;1" values="0;360"
> repeatDur="indefinite" additive="sum"/>
>      <animateTransform id="t3" begin="0" dur="2"
> attributeName="transform" type="translate" keyTimes="0;1"
> values="-15,-15;-15,-15" fill="freeze" additive="sum"/>
>    </rect>
> </svg>
>
> The main point is that there is no way to control the transform order if
> the animations don't start at the same time. The above is just one
> example, there are also other examples and it happens with scaling and
> skewing, too.
>
> I have tried to think how to solve this using the model that the new Web
> Animation spec provides, but it seems that the only way will be the
> custom effect scripting. The priority property could be used to control
> the order of the custom effect scripts, or one custom effect script
> could animate all transforms.
>
> Is there any other way to keep the transform order while their begin
> times differ? It is a bit messy to start writing scripts to achieve
> this. Or perhaps I am missing something..?
>
> Cheers,
> Kari
>
Received on Thursday, 6 June 2013 00:12:25 UTC

This archive was generated by hypermail 2.3.1 : Thursday, 6 June 2013 00:12:26 UTC