Transition Control. Part 1.
One of the coolest things you can do with GDI+ is mess about
with images. Image transition suites are big business with some packages selling
for almost a thousand dollars. They are used in everything from screen-savers to
business presentations and videos but they all have pretty much the same goal,
to hide one image and show another one in a pleasing manner.
Graphics on a GDI+ system is a mixture of pleasure and pain.
Pleasure because you can do so much cool stuff with it, pain because without
hardware acceleration it can be slow. To get the right balance of graphics and
speed is not always easy. Many people who write transition code make the mistake
of trying to enforce a particular number of steps in their transitions in the
hope that more steps makes for a smoother display. Unfortunately this isn't the
case and a good transition system should know how to create an effect that
has accuracy of timing and the best available visual effect.
One of the easiest transitions to create is the fade. GDI+
provides great control over image alpha-blending and so successive overlays of
one image over another is easily accomplished. Alpha-blending is however a CPU
hog and so a smooth fade is difficult to obtain so, the first transition our
fledgling control will handle is a fade.
Determining the steps.
The transition control needs a reliable
time-base. For this I've used the System.Threading.Timer which doesn't rely on
the message loop for it's notifications. A good basic animation speed is 25
frames per second so 40 milliseconds is the basic rate that ticks come along.
This doesn't guarantee that the control will update 25 times per second. On a
top-end system it might but enforcing a specific number of steps is a bad idea
so the code only calculates the percentage of code that ought to be drawn at any
given moment and invalidates the control. This is also good event driven
application practice because no drawing is done in the tick event and only a few
simple calculations are performed to determine the current progress of the
transition.
The current percentage value for the
transition is calculated using the system timer. When the transition begins, the
current time is stored. Every time a tick comes along the expected percentage is
calculated according to the amount of time the transition is supposed to take
and the current elapsed time. In this way, an arbitrarily long or short
transition will use the same basic calculation.
This listing
shows how the timing system works.
Drawing the fade
The fade is drawn by the paint event
according to the current calculated percentage. The paint can take a variable
amount of time depending on the client size of the control, the size of the
images it is displaying and the raw power of the machine the code is running on.
More powerful machines will draw more steps in the transition up to the maximum
of 25 per second. Slower machines will draw fewer transition steps but will
complete the transition in the same time. This listing shows
the Paint event with the switch statement that will eventually draw all of
the supported transition types and the code for the fade. The code uses the
ImageAttributes class and a ColorMatrix to set the transparency of ImageB over
ImageA
Figure 1 shows the fade in progress.



Figure 1. Fade in progress.
The supported Transition Types
Over the next two articles the
capabilities of the control will be expanded to support the following
transitions:
-
Fade ImageB is superimposed
transparently on ImageA.
-
BarnDoor ImageB closes in from
two sides obscuring ImageA.
-
Slide ImageB slides in to cover
ImageA from left to right.
-
Spin ImageB expands from the
center to obscure ImageA.
-
Checker ImageB is cut into a
checkerboard so that each square expands to hide ImageA
-
Blinds ImageB is cut into
horizontal bands that expand to cover ImageA.
-
Iris ImageB expands from a
point in the center to cover ImageA.
-
Spiral ImageB builds up in
blocks that spiral out from the center to cover ImageA
Later, you'll see how to create the
BarnDoor, Slide, Spin and Checker effects. and June will cover Blinds, Iris and
Spiral.
The initial code and the test
application is in the code page.
You can find the Source Code files here.
Read on Part 2.
Return to the main index.