Animating html with dart's universal tween engine

Last time I posted about how to animate svg's using dart's universal tween engine. So how about some html animation this time to create a progress bar.

Check out last post's to see how to setup a new web project in the engine. These are the names of my files:

  • index.html
  • progress_bar.dart

Put the following in your html file:

<!DOCTYPE html>  
<html>  
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bootstrap's progress bar animation</title>
    <style type="text/css">
      .progress-bar{
        background-color: #5cb85c;
        float: left;
        height: 20px;
        border-radius: 8px;
        border: 2px solid #2c882c;
      }
      .progress{
        background-color: #f5f5f5;
        height: 24px;
        width:  550px;
        border-radius: 8px;
        overflow: hidden;
        box-shadow: inset 0 1px 4px rgba(0,0,0,.1);
      }
    </style>
  </head>
  <body style="padding: 50px;">   
    <div class="progress">
      <div class="progress-bar" style="width: 60%;">
      </div>
    </div>
    <script type="application/dart" src="progress_bar.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>  

Basically we just added 2 divs with some styling. Notice that the attribute style="60%" in the .progress-bar is needed for dart to find it.

Let's go onto the interesting stuff. Open progress_bar.dart.
Start by getting everything ready:

import 'dart:html';  
import 'package:tweenengine/tweenengine.dart';

TweenManager _manager = new TweenManager();  
num lastUpdate = 0;  
RegExp percent = new RegExp("%");

void main(){  
}

void update(num delta){  
  num deltaTime = (delta - lastUpdate) / 1000;
  lastUpdate = delta;
  _manager.update(deltaTime);
  window.animationFrame.then(update);
}

We just created some variables we will be working with, and added the mandatory main() method. The update method is just a copy&paste from last time's example, which we will be using to update our animation.

First, create your accessor and register it in the engine:

class StyleAccessor implements TweenAccessor<CssStyleDeclaration>{  
  static const int Width = 1;

  int getValues(CssStyleDeclaration target, int tweenType, List<num> returnValues){
    if ( tweenType != Width) return 0;

    //strip the % from the style
    num numericValue = num.parse( target.width.replaceAll( percent, "") );
    returnValues[0] = numericValue;

    return 1;
  }

  void setValues(CssStyleDeclaration target, int tweenType, List<num> newValues){
    if (tweenType != Width) return;

    target.width = newValues[0].toString() + "%";
  } 
}

void main(){  
  Tween.registerAccessor(CssStyleDeclaration, new StyleAccessor());
}

Pay attention to the comments in the getValues method above, dart's CssStyleDeclaration class provides you the width as a String. That's why we declared a RegExp at the very beginning, we take the width string, and convert it to a number. Since we are just creating a short example here, we know the only character that needs escaping is the percet symbol.
In the setValues() method, we just place back the value as a string, and we give it back its percent symbol.

That's it! we are all set.

Animating the progress bar

We need to get our target ( the div with progress-bar class) so we can interpolate on it. That's piece of cake with dart:

void main(){  
    ...
    DivElement bar = querySelector(".progress-bar");
    var target = bar.style;
}

Tween.from is handy

Last time, we used the Tween.to() method to create our tweens withing a timeline, what that kind of tweening does is take the current value of our target object and interpolate it all the way to the targetValues that we set.
This time I want to show you the Tween.from(), which works the opposite way, it will take our targetValues as the initial values and interpolate them all the way to the current values.

In your main method, add this:

void main(){  
      //Animate fully from 0 to current value (60%), in 3 seconds
      Tween.from(target, 1, 3)
        ..delay = 2
        ..targetValues = 0
        ..easing = TweenEquations.easeOutExpo
        ..start(_manager);

    window.animationFrame.then(update);
}

First we are creating a tween with the following behavior

  • Take the target, animate from 0 (targetValues) to currentValue
  • Wait 2 seconds before tweening (delay). We are using a delay so we can appreaciate the full animation.
  • Use an OutExpo easing

We are done! Run it and you should see an animated progress bar (No image this time since the 3 gif recorders I tried were not recording properly, seems to me as a win8 problem)

comments powered by Disqus