Title: Make animated labels in C#
This example shows how to make animated labels that slowly move into position to make an interesting "movie credit" effect. Note that the example's result is better than the result giving by the GIF on the right. The GIF is a bit jerky because it uses only 20 frames instead of the 200 used by the program.
The program displays all of its text in labels and moves the labels as necessary. When it starts, the program uses the following code to record some information about the labels.
// The Label controls we will animate and their properties.
private List<Label> AnimateLabels = new List<Label>();
private List<int> AnimateStartXs = new List<int>();
private List<int> AnimateStartYs = new List<int>();
private List<float> AnimateDxs = new List<float>();
private List<float> AnimateDys = new List<float>();
private List<float> AnimateXs = new List<float>();
private List<float> AnimateYs = new List<float>();
private List<int> AnimateTotalTicks = new List<int>();
private List<int> AnimateTicksToGo = new List<int>();
// Make lists of the controls to move.
private void Form1_Load(object sender, EventArgs e)
{
// Move down 20 pixels in 1 second.
StoreAnimationInfo(lblTitle1, 0, 20, 500);
// Move right 40 pixels in 2 seconds.
StoreAnimationInfo(lblTitle2, 40, 0, 1000);
// Move left 40 pixels in 2 seconds.
StoreAnimationInfo(lblTitle3, -40, 0, 1000);
// Move up 20 pixels in 1 second.
StoreAnimationInfo(lblTitle4, 0, -20, 500);
}
// Store information to move a label.
private void StoreAnimationInfo(
Label lbl, float dx, float dy, float milliseconds)
{
// Calculate the number of times the Timer will tick.
int ticks = (int)(milliseconds / tmrMoveLabels.Interval);
// Add the values.
AnimateLabels.Add(lbl);
AnimateStartXs.Add((int)(lbl.Location.X - dx));
AnimateStartYs.Add((int)(lbl.Location.Y - dy));
AnimateDxs.Add(dx / ticks);
AnimateDys.Add(dy / ticks);
AnimateTotalTicks.Add(ticks);
}
The program stores several pieces of information about the animated labels:
- The labels themselves
- The labels' starting positions
- The distances (AnimateDxs and AnimateDys) that the labels should move at each tick
- The labels' current X and Y positions during animation (AnimateXs and AnimateYs)
- The total number of ticks each label must move
- The number of ticks remaining for a label to move in this animation
When you click the Animate button, the program executes the following code to prepare the animated labels.
// Move the labels to the start positions and start animating them.
private void btnAnimate_Click(object sender, EventArgs e)
{
btnAnimate.Enabled = false;
AnimateTicksToGo = new List<int>();
AnimateXs = new List<float>();
AnimateYs = new List<float>();
for (int i = 0; i < AnimateLabels.Count; i++)
{
AnimateXs.Add(AnimateStartXs[i]);
AnimateYs.Add(AnimateStartYs[i]);
AnimateLabels[i].Location =
new Point((int)AnimateXs[i], (int)AnimateYs[i]);
AnimateLabels[i].Visible = true;
AnimateTicksToGo.Add(AnimateTotalTicks[i]);
}
tmrMoveLabels.Enabled = true;
}
This code moves the labels to their start positions and resets the labels' AnimateTicksToGo values. It then enables the tmrMoveLabels timer. The following code shows that timer's Tick event handler.
// Move the labels.
private void tmrMoveLabels_Tick(object sender, EventArgs e)
{
bool done_moving = true;
DateTime now = DateTime.Now;
for (int i = 0; i < AnimateLabels.Count; i++)
{
if (AnimateTicksToGo[i]-- > 0)
{
done_moving = false;
AnimateXs[i] += AnimateDxs[i];
AnimateYs[i] += AnimateDys[i];
AnimateLabels[i].Location =
new Point((int)AnimateXs[i], (int)AnimateYs[i]);
}
}
// If all labels are done moving, disable the Timer.
if (done_moving)
{
tmrMoveLabels.Enabled = false;
tmrHideLabels.Enabled = true;
}
}
The Tick event handler examines each animated label's AnimateTicksToGo value. If a value is greater than zero (i.e. this Label needs to move again), the code adds the Dx and Dy value for that Label to its location. The code then decrements the AnimateTicksToGo value. (That's what the post decrement operator "--" after the variable means: the code examines it first and then decrements the value.)
After examining all of the labels, if none of the labels moved, the code disables the tmrMoveLabels timer and enables the tmrHideLabels timer. The new timer waits for 1 second and then hides the labels.
Download the example to experiment with it and to see additional details.
|