Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Emasoft opened this issue Aug 7, 2014 · 9 comments

Comments

@Emasoft
Copy link

Emasoft commented Aug 7, 2014

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.

  • Tween from keyframe 1 to keyframe 25. Duration: total x (kframe_delta/last_kframe_n) so 1.5s x (25/135) = 0.28 sec
  • Tween from keyframe 25 to keyframe 0135 : Duration: total x (kframe_delta/last_kframe_n) so 1.5s x ((135-25)/135) = 1.22 sec
  • ..and so on for all the other keyframes svg files.

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
Copy link
Owner

xaguzman commented Aug 7, 2014

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
Copy link
Author

Emasoft commented Aug 7, 2014

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
Copy link
Owner

xaguzman commented Aug 7, 2014

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
Copy link
Owner

xaguzman commented Aug 7, 2014

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
Copy link
Author

Emasoft commented Aug 7, 2014

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
Copy link
Owner

xaguzman commented Aug 7, 2014

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

@Emasoft
Copy link
Author

Emasoft commented Aug 7, 2014

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
Copy link
Author

Emasoft commented Aug 8, 2014

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
Copy link
Owner

xaguzman commented Aug 8, 2014

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
#8 (comment)
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants