The New MFC Animation API

Introduction

Microsoft Visual Studio 2010 Service Pack 1 includes a number of enhancements and new features for MFC developers. One of those changes is an animation API to make it easy for you to create animations in MFC applications. This article will briefly introduce this animation API.

The main parts of this new API are:

  • Animation transitions
  • Animation values
  • Animation controllers

Animation Transitions

The animation API uses transitions to animate values. The API comes with a number of predefined transitions:

  • CAccelerateDecelerateTransition: The animated value speeds up and then slows down again.
  • CConstantTransition: The animated value will be kept at its initial value during the whole transition.
  • CCubicTransition: The animated value will reach the target value with a specified velocity.
  • CDiscreteTransition: The animated value will jump from the initial value directly to the target value after a specified delay.
  • CInstantaneousTransition: The animated value immediately jumps to the target value. The duration is always zero.
  • CLinearTransition: The animated value will go linearly from its initial value to its target value over a specified duration.
  • CLinearTransitionFromSpeed: Is similar to CLinearTransition, but instead of specifying a duration, you have to specify a speed with which the animated value has to go from the initial value to the target value. The duration of the transition is calculated automatically based on the specified speed.
  • CSmoothStopTransition: The animated value will go from its initial value to its target value, but the transition will slow down towards the target value to reach the target with a velocity of zero.
  • CParabolicTransitionFromAcceleration: The animated value will reach its target value with a specified velocity and acceleration.
  • CReversalTransition: The transition direction will be changed smoothly over a specified duration. The final value of the animated value will be the same as the initial value.
  • CSinusoidalTransitionFromRange: The animated value will fluctuate between a specified minimum and maximum during the duration of the transition.
  • CSinusoidalTransitionFromVelocity: The animated value will oscillate around the initial value during the duration of the transition.

Most of the above predefined animation transitions are pretty straightforward to use. All of them require at least the duration of the transition and most of them require a target value. For example, the CAccelerateDecelerateTransition transition has the following constructor:

  CAccelerateDecelerateTransition(UI_ANIMATION_SECONDS duration,
  	DOUBLE finalValue,
  	DOUBLE accelerationRatio = 0.3,
  	DOUBLE decelerationRatio = 0.3)

The first parameter is the duration of the transition. It is the time that it will take to go from the start value to the target value. The second parameter is this target value. The next parameters are specific algorithmic parameters which have default values in this case.

CConstantTransition is special. It will keep the animation value at its initial value during the whole transition, so its constructor is simply as follows:

  CConstantTransition(UI_ANIMATION_SECONDS duration)

There is also a CCustomTransition that you can use if none of the above transitions deliver what you are looking for. It’s a bit more complicated to use. You will have to derive your own class from CCustomInterpolator and implement the InterpolateValue method and possibly a few others.

The next section will discuss animation values and will give examples on how to actually use the above animation transitions.
Note that you need to initialize COM before the Windows Animation API will work. You can do this by adding the following line in your InitInstance method:

  CoInitialize(0);

  And the following line in your ExitInstance method:
  CoUninitialize();

  Instead of using CoInitialize and CoUnitialize, you can simply use the following block in your InitInstance method:
  if (!AfxOleInit())
  {
  	AfxMessageBox(_T("AfxOleInit failed"));
  	return FALSE;
  }

Animation Values

The new API works by animating values. There are several classes that encapsulate specific values and which can be animated with certain transitions. The different animation value classes are as follows:

  • CAnimationValue: Animates a single value. This could be used to animate a transparency of an object or a rotation of an object.
  • CAnimationPoint: Animates a point. A point contains and X and Y coordinates. Both coordinates can be animated separately.
  • CAnimationSize: Animates a size. A size contains a width and height, both can be animated separately.
  • CAnimationColor: Animates a color. A color contains an RGB value. Each color component can be animated separately.
  • CAnimationRect: Animates a rectangle. A rectangle contains a left, top, right and bottom value and all of them can be animated separately.

Creating an animation value is pretty straightforward. Just create an instance of the animation value object you want, initialize it, add animation transitions to it and specify its parameters like the target value. For example, to define a color animation value, first define it as follows:

  CAnimationColor m_animClr1;

Then the following line will initialize the start color to red:

  m_animClr1 = RGB(255,0,0);

And finally assign transitions to each color component:

  m_animClr1.AddTransition(new CLinearTransition(2, 0),
  	new CLinearTransition(1, 255),
  	new CLinearTransition(0.5, 128));

The above line adds 3 transitions:

  • The red color component will go from 255 (=start value) to 0 over a period of 2 seconds.
  • The green color component will go from 0 (=start value) to 255 over a period of 1 seconds.
  • The blue color component will go from 0 (=start value) to 128 over a period of 0.5 seconds.

Similarly, a rectangle animation could be defined as follows:

  CAnimationRect m_animRect;
  m_animRect = CRect(0, 0, 100 ,100);
  m_animRect.AddTransition(new CAccelerateDecelerateTransition(2, 100),
  	new CAccelerateDecelerateTransition(2, 100),
  	new CAccelerateDecelerateTransition(2, 400),
  	new CAccelerateDecelerateTransition(2, 200));

This animation starts with a rectangle with upper-left coordinate (0, 0) and lower-right coordinate (100, 100). The transitions will animate this rectangle to an upper-left coordinate (100, 100) and a lower-right coordinate (400, 200) over a period of 2 seconds using an acceleration-deceleration transition.

Inside your WM_PAINT handler, you will use the animated values from your animation variables to do your drawing. For example:

  int x1, y1, x2, y2;
  m_animRect.GetLeft().GetValue(x1);
  m_animRect.GetTop().GetValue(y1);
  m_animRect.GetRight().GetValue(x2);
  m_animRect.GetBottom().GetValue(y2);
  COLORREF clr;
  m_animClr1.GetValue(clr);
  pDC->FillSolidRect(x1, y1, x2-x1, y2-y1, clr);

The above code is first querying the animated rectangle about its current animated coordinates and the animated color variable about its current color value. After that it simply draws a rectangle with those coordinates and color.

Working with the other animation value classes is pretty similar.

More by Author

Must Read