xaguzman / tween-engine-dart

This is a dart port of the original java Universal Tween Engine created by Aurelien Ribbon
Apache License 2.0
33 stars 4 forks source link

Can you add support for keyframe interpolation and animation of SVG images? #8

Closed Emasoft closed 10 years ago

Emasoft commented 10 years ago

A quick way to make amazing SVG animations is to tween between different frames. Can you implement a function that takes a certain number of SVG images and produce an animation interpolating between them? Of course the interpolation would only work on SVG elements existing in all frames with the same id.

For example: keyframe 1:

<svg viewBox="0 0 500 400" preserveAspectRatio="xMinYMin meet" width="100%" height="100%">
  <rect id="my_animated_box" x="100" y="100" rx="20" ry="20" width="150" height="150"
  style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg>

keyframe 2:

<svg viewBox="0 0 500 400" preserveAspectRatio="xMinYMin meet" width="100%" height="100%">
  <rect id="my_animated_box" x="50" y="100" rx="20" ry="20" width="250" height="150"
  style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg>

keyframe 3:

<svg viewBox="0 0 500 400" preserveAspectRatio="xMinYMin meet" width="100%" height="100%">
  <rect id="id="my_animated_box"" x="50" y="0" rx="20" ry="20" width="450" height="350"
  style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg>

Those would be inline or in many files numbered with the FRAME NUMBER: mybox_kf0001.svg mybox_kf0025.svg mybox_kf0135.svg

SvgAnimationSequence box_animation_sequence = SvgAnimationSequence.createSequence(1.5);  //create an animation sequence with a duration of 1.5 seconds.

box_animation_sequence.addSvgKeyFrame("mybox_kf001.svg", 0001); //start frame
box_animation_sequence.addSvgKeyFrame("mybox_kf002.svg", 0025); //frame 25
box_animation_sequence.addSvgKeyFrame("mybox_kf003.svg", 0135); //frame 135

Timeline.createSvgSequence()
      ..push(Tween.svgSequenceSet(box_animation_sequence))..startFrame(0001)
      ..beginSvgAnim()
        ..push(Tween.svgSequenceTo(box_animation_sequence))..endFrame(0135)
      ..end()
      ..start(_tweenManager)
}

For each element in the SVG sequence it should interpolate all the elements one by one.

SVG frames can also be added as SvgSvgElement:

SvgSvgElement svg_box = querySelector('#svgbox_keyframe4');
box_animation_sequence.addSvgKeyFrame(svg_box, 0171); 

The SvgSvgElement class is handy for accessing svg elements:

svg_box .getElementById('my_animated_box').attributes['style'] = 'display:none';

It would be sufficient to iterate on all svg elements and svg groups of each svg image pair (with matching IDs) and to tween all the values that changes from frame to frame.

Svg elements with non matching IDs would NOT be animated, but just faded out or faded-in (i.e. if an element "plum_cake" exists in kframe 0001 but not in kframe 0025, then it will be applied a transparency tween to "plum_cake" from alpha 1.0 to alpha 0.0. The opposite for elements missing from kframe 0001 and appearing in kframe 0025).

In this way one can create some keyframes in Inkscape, and getting them automatically interpolated and animated by the tween-engine.

From something simple as a boucing ball:

keys

to something more complex as a running horse:

onion_skin-3

No matter the complexity you would only need the same code. Just load the frames and set the duration/easing and you are done.

Please add this option.

xaguzman commented 10 years ago

I will look into this, however, I think there's no need to add that. Adding this would add a dependency on dart:html which I would like to aviod.

However, I see no reason why this wouldn't be solved with a simple (not really that simple) TweenAccessor

Emasoft commented 10 years ago

I'm not sure that using TweenAccessor would be enough. How? Can you try to implement it as an example? In that way we'll test if a TweenAccessor is really enough to do it.

xaguzman commented 10 years ago

I am going to try. The only problem with trying to go through all of the attributes is that the tween engine creates non-growable arrays for interpolating. You have to call Tween.combinedAttributesLimit = ; to set the maximum number of attributes you are going to be tweening over.

I am not familiar with the dart svg api, but your specific example should be easy enough by adding a simple RectangleAccessor.

I will try to come up with a demo.

xaguzman commented 10 years ago

I just created a working example, will post about it later.

This would however, require too many accessors to have a fully featured svg animator. I am not willing to add this directly to the engine, however, maybe we can create a different library for it which uses the tween engine under the hood?

Emasoft commented 10 years ago

I will work on it if you want. I'll open a new project on github. But I would need your help. I'm sure that such library would came in handy for every html5 page using SVG animated icons or buttons. Even if you need to tween a 2 frame transition animation from an SVG button state "UP" to a button state "DOWN".

xaguzman commented 10 years ago

Sure, let's do that. I posted an example here

Emasoft commented 10 years ago

Here the two SVG needed to animate a press button: BUTTON UP: http://codepen.io/Emasoft/pen/cgdoL BUTTON DOWN: http://codepen.io/Emasoft/pen/FECti

Emasoft commented 10 years ago

I've read the article thanks. I've also corrected the code in your Gist. I've created a new Gist with the working code: https://gist.github.com/Emasoft/9098155ddef394d054ff

xaguzman commented 10 years ago

Oh my, I missed up on the "keyframes" didn't I? Thanks for fixing that


Xavier Guzman

https://plus.google.com/u/0/+XavierGuzmanMX/posts/p/pub http://www.linkedin.com/profile/view?id=44608085 https://www.facebook.com/xavguz

On Thu, Aug 7, 2014 at 8:16 PM, Emasoft notifications@github.com wrote:

I've read the article thanks. I've also corrected the code in your Gist. I've created a new Gist with the code: https://gist.github.com/Emasoft/9098155ddef394d054ff

— Reply to this email directly or view it on GitHub https://github.com/xaguzman/tween-engine-dart/issues/8#issuecomment-51553116 .