Animation API

The primary classes in the Animation API are Animator and Animation. To use the primary classes, you will also work with the AnimationKeyframeSequence class and the AnimatedScalar class or AnimatedVector class. All of these classes are in the net.rim.device.api.animation package.

You create and control animations using the Animator class. You invoke one of its addAnimation() methods, which returns an Animation object. The target of your animation must implement the Animatable interface. In most cases, you can use either AnimatedScalar or AnimatedVector to represent the animatable properties of the object that you want to animate. If you can't use these classes to represent the properties, there are also classes in the net.rim.device.api.math package that implement Animatable. If none of the predefined classes work for your application, you can build a custom animatable object by creating a class that implements Animatable.

Class diagram of the Animation API

Class or interface

Description

Animator

This class represents the root node of the set of animations that you want to manage. You can invoke one of its addAnimation() methods to create an animation. You can invoke begin() and end() to start and stop the animation that you create.

Animation

This class represents an animation and lets you manage the animation.

Animatable

This interface describes the set of methods that you have to implement to create your own Animatable object.

AnimatedScalar

This class implements a predefined, animatable scalar property.

AnimatedVector

This class implements a predefined, animatable vector property.

AnimationKeyframeSequence

This class represents a sequence of key frames and lets you specify reference points in an animation sequence. The animation framework interpolates between the reference points that you specify.

AnimationGroup

This class represents a group of animations and lets you control these animations as a group instead of individually.

AnimationTrigger

This class represents an object that you can add to an animation and later use to trigger the animation to start or stop.

AnimationValue

This class provides a wrapper for the value of an animatable property that is being animated.

AbstractAnimation

This class defines the basic functionality for animations and animation groups.

Code sample: Creating and starting a basic animation

The following code sample doesn't create a complete animation. It illustrates the key steps that are required to set up a simple animation of a vector animatable object.

To enhance the code sample to make it a working animation, you would have to do the following:
  • add code to draw an object on the screen at the location that is specified by the position variable
  • set up a listener for the animation engine to invoke each time it updates the position of the object
  • in response to each call, draw your object on the screen at the current position
 
Animator animator = new Animator(25);
AnimatedVector position = new AnimatedVector( new float[] { 0.0f, 0.0f }, 0 ); 
Animation animation = animator.addAnimationTo(
 position,
 AnimatedVector.ANIMATION_PROPERTY_VECTOR, 
 new float[] { 100.0f, 100.0f }, 
 0,
 Animation.EASINGCURVE_LINEAR, 1000L);

animation.setRepeatCount(1.0f);
animation.begin(1000L);

Key frames

Animations are created by presenting a series of images quickly enough that the human eye doesn't sense an abrupt transition between the images. If the differences between adjacent images in the series are kept small enough, someone viewing the animation sees it as a smooth, changing scene instead of a series of images.

Each static image in an animation is called a frame. The term frame originated from film technology. A strip of film is partitioned into a series of images that are separated from each other by thin, unused portions of film called frame lines. Together, the unused portions of the film and the edges of the film appear like a picture frame around each individual image.

One method of creating an animation is to create each of the frames that you want to present individually. This method is called keyframing. Keyframing gives the animator precise control over the animation, but it is very labor-intensive. Another method is to create only some of the most important frames. The frames that you choose to create are called key frames and are pivotal or complex members of the series of images.

In classical animation, a senior animator might create the key frames and junior animators would fill in the in-between frames. In computer animation, the animator can specify the key frames and the computer can use interpolating algorithms to generate the in-between frames. The interpolation process is called tweening.

With the Animation API, you specify the key frames using the KeyframeSequence class and the animation framework uses interpolation to calculate the values of the animatable properties of the animation between the key frames.

Easing curves

Easing curves are functions that specify the speed of an animation. You can use them to make animations look more realistic without requiring you to do physics calculations. For example, when you animate a dropping ball, you want the ball to speed up as it drops. An easing curve that eases in creates that effect.

The domain of an easing function is the completed fraction of the total duration of the animation. The range is the completed fraction of the total animating that is required. If e(t) is an easing function and the position of an animatable object changes from p1 to p2 over a time period of d milliseconds, then at an intermediate time, t, the object is at position p = p2 - p1*e(t) + p1.

Easing curve plots help you visualize the effect of an easing curve on an animation. The following plot uses a normalized domain of [0,1] to represent the entire duration of the animation and displays an EASINGCURVE_BOUNCE_IN easing curve.

There are several terms that are used to classify easing curves.

Term Definition
Ease in The animation accelerates.
Ease out The animation decelerates.
Ease in-out The first half of the animation accelerates and the second half decelerates.
Ease out-in The first half of the animation decelerates and the second half accelerates.

The Animation API supports nearly 50 easing curves. If none of these curves work for your application, you can specify a custom easing curve using cubic Bézier splines.

Predefined classes that implement the Animatable interface

Animatable class

Description

net.rim.device.api.animation

AnimatedScalar

defines a scalar value

AnimatedVector

defines a vector value

net.rim.device.api.math

Vector2f

defines a 2-element vector of floating point numbers

Vector3f

defines a 3-element vector of floating point numbers

Vector4f

defines a 4-element vector of floating point numbers

Color3f

defines a color made up of red, green, and blue components

Color4f

defines a color made up of red, green, blue, and alpha components

Quaternion4f

defines a 4-element quaternion that represents the orientation of an object in space

Transform2D

defines a 2-D transformation

Transform3D

defines a 3-D transformation

Create a custom class that implements the Animatable interface

  1. Import the required classes and interfaces.
    import net.rim.device.api.animation.*;
  2. Create a class that implements the Animatable interface.
    public class PositionSizeAnimatable implements Animatable
  3. Create integer constants to represent each of the properties of the class and create an integer array to store the number of components in each property. Declare variables to hold the data for all of the components of the class.
    public  static final int   ANIMATION_PROPERTY_XY = 0;
    public  static final int   ANIMATION_PROPERTY_WIDTH = 1;
    public  static final int   ANIMATION_PROPERTY_HEIGHT = 2;
    public  static final int   ANIMATION_PROPERTY_COUNT = 3;
    private static final int[] ANIMATION_PROPERTY_COMPONENT_COUNTS = { 2, 1, 1 };
          
    public float x, y, width, height;
    
  4. Create a constructor that accepts and sets values of all of the components of the animatable properties.
    public MyAnimatable(float x, float y, float height, float width) 
    {
       this.x = x; 
       this.y = y;
       this.width = width;
       this.height = height;
    }
    
  5. Implement getAnimationValue(). The AnimationValue class is used by the animation framework to encapsulate the values of animatable objects it is animating. Invoke setFloat() to store the component values of this particular animatable object in value.
    public void getAnimationValue(int property, AnimationValue value)
    {
       switch(property) 
       {
          case ANIMATION_PROPERTY_XY:
             value.setFloat(0, this.x);
             value.setFloat(1, this.y);    
             break;
                 
          case ANIMATION_PROPERTY_WIDTH:
             value.setFloat(0, this.width);
             break;
                  
          case ANIMATION_PROPERTY_HEIGHT:
             value.setFloat(0, this.height);
             break;
        }
     }
    
  6. Implement setAnimationValue(). Invoke getFloat() to retrieve the updated component values for this animatable object from value.
    public void setAnimationValue(int property, AnimationValue value)
    {
    	switch(property) 
    	{
    	   case ANIMATION_PROPERTY_XY:
    	      this.x = value.getFloat(0);
    	      this.y = value.getFloat(1);
    	      break;
    	   case ANIMATION_PROPERTY_WIDTH:
    	      this.width = value.getFloat(0);
    	      break;
    	   case ANIMATION_PROPERTY_HEIGHT:
    	      this.height = value.getFloat(0);
    	      break;
    	 }
    }         
    
  7. Implement getAnimationPropertyComponentCount(). In the following code sample, a check is performed to make sure that the integer property parameter is valid, and then the count that is stored in the ANIMATION_PROPERTY_COMPONENT_COUNTS array is returned.
    public int getAnimationPropertyComponentCount(int property)
    {
        if (property >= 0 && property < ANIMATION_PROPERTY_COUNT)
            return ANIMATION_PROPERTY_COMPONENT_COUNTS[property];
        return 0;
    }
     }

Code sample

import net.rim.device.api.animation.*;
 
 public class MyAnimatable implements Animatable
 {
      public static final int ANIMATION_PROPERTY_XY = 0;
      public static final int ANIMATION_PROPERTY_WIDTH = 1;
      public static final int ANIMATION_PROPERTY_HEIGHT = 2;
      public static final int ANIMATION_PROPERTY_COUNT = 3;
      private static final int[] ANIMATION_PROPERTY_COMPONENT_COUNTS = { 2, 1, 1 };
      
      public float x, y, width, height;
      
      public MyAnimatable(float x, float y, float height, float width) 
      {
          this.x = x;
          this.y = y;
          this.width = width;
          this.height = height;
      }
      
      public void getAnimationValue(int property, AnimationValue value)
      {
          switch(property) 
          {
              case ANIMATION_PROPERTY_XY:
                  value.setFloat(0, this.x);
                  value.setFloat(1, this.y);
                  break;
             case ANIMATION_PROPERTY_WIDTH:
                  value.setFloat(0, this.width);
                  break;
              case ANIMATION_PROPERTY_HEIGHT:
                  value.setFloat(0, this.height);
                  break;
          }
      }
      
      public void setAnimationValue(int property, AnimationValue value)
      {
          switch(property) 
          {
              case ANIMATION_PROPERTY_XY:
                  this.x = value.getFloat(0);
                  this.y = value.getFloat(1);
                  break;
              case ANIMATION_PROPERTY_WIDTH:
                  this.width = value.getFloat(0);
                  break;
              case ANIMATION_PROPERTY_HEIGHT:
                  this.height = value.getFloat(0);
                  break;
          }
      }

      public int getAnimationPropertyComponentCount(int property)
      {
          if (property >= 0 && property < ANIMATION_PROPERTY_COUNT)
              return ANIMATION_PROPERTY_COMPONENT_COUNTS[property];
          return 0;
      }
 }
Previous topic: Animation

Was this information helpful? Send us your comments.