Introduction
Can we make our WinForms application was animated, like WPF? Yep, of course we can!
The component
Animator
allows you to
animate any controls on your WinForms.
How it works
Animator creates a temporary control
DoubleBitmap
over the target control.
DoubleBitmap
contains two images. First image is snapshot of background of the form, exclude target control. Second image contains snapshot of target control.
Then animator periodically transforms top image of
DoubleBitmap
. As result – we get animated fake of target control.
Each transformation has some dependence on the current time. And
Animator
changes time and call transformation for new animation frame.
The
Animator
supports two kinds of transforms - linear transforms (scaling, shifting, rotating) and non-linear transforms (distortions, skews, etc). Also it can change transparency of animated bitmap.
Linear transformations are performed using matrix transformations of GDI+.
Example of the transformation Rotate:
Collapse | Copy Code
public static void DoRotate(TransfromNeededEventArg e, Animation animation)
{
var rect = e.ClientRectangle;
var center = new PointF(rect.Width / 2, rect.Height / 2);
e.Matrix.Translate(center.X, center.Y);
if (e.CurrentTime > animation.RotateLimit)
e.Matrix.Rotate(360 * (e.CurrentTime - animation.RotateLimit) * animation.RotateCoeff);
e.Matrix.Translate(-center.X, -center.Y);
}
Nonlinear transformations are little harder. First, it creates an array of pixels. And then there is a conversion each pixel in cycle. The
Animator
can change coordinates of the pixel, it's color and transparency. Below is an example of the transformation:
Collapse | Copy Code
public static void DoBlind(NonLinearTransfromNeededEventArg e, Animation animation)
{
if (animation.BlindCoeff == PointF.Empty)
return;
var pixels = e.Pixels;
var sx = e.ClientRectangle.Width;
var sy = e.ClientRectangle.Height;
var s = e.Stride;
var kx = animation.BlindCoeff.X;
var ky = animation.BlindCoeff.Y;
var a = (int)((sx * kx + sy * ky) * (1 - e.CurrentTime));
for (int x = 0; x < sx; x++)
for (int y = 0; y < sy; y++)
{
int i = y * s + x * bytesPerPixel;
if (x * kx + y * ky >= a)
pixels[i + 3] = (byte)0;
}
}
The
Animator
creates
DoubleBitmap
with correct z-order. So, if some controls were under target control, then they will be under
DoubleBitmap
control. Similarly – controls above target control:
How to use
Simplest way to use
Animator
: dragging the
Animator
component onto your form.
To start animation – call method
Animator.Show(targetControl)
from your code.
Take to attention: the target control must be hidden (visible==false) before calling Show method. Otherwise animation will not take effect.
Similarly, you can hide the control using the method
Animator.Hide(targetControl)
.
The
Animator
allows you to make animated changing of your visible control. Before updating you need to call
Animator.BeginUpdate(targetControl)
, then update your control, and finally to call
Animator.EndUpdate(targetControl)
. For example:
Collapse | Copy Code
animator.BeginUpdateSync(dataGridView1, true);
dataGridView1[col, row].Value = newValue;
animator.EndUpdate(dataGridView1);
As result – the control will change its view with animation.
Animator
has several built-in types of animation. It's
Rotate
,
Scale
,
Leaf
,
Mosaic
,
Particles
,
Blind
, etc. You can set built-in animation by property
AnimationType
.
In addition,
Animator
allows you to fine-tune the animation, as well as create custom animation.
For adjusting you can use property
DefaultAnimation
. Below described all properties of
Animation
class:
- PointF
SlideCoeff
- Set (1,0) or (0,1) to slider effect.
- float
RotateCoeff
- Adjusts rotation angle.
- float
RotateLimit
- Parameter defines time of end of rotation
- PointF
ScaleCoeff
- Adjusts horizontal and vertical scaling
- float
LeafCoeff
- Set 1 to "leaf" effect
- PointF
MosaicCoeff
- Adjusts deviation of mosaic
- int
MosaicSize
- Mosaic square size (in pixels)
- PointF
MosaicShift
- Shift of mosaic squares.
- PointF
BlindCoeff
- Set (1,0) or (0,1) to "blind" effect.
- float
TransparencyCoeff
- Set 1 if you want to make transparency of animation.
- float
TimeCoeff
- Time coefficient
- Padding
Padding
- Expands bounds of DoubleBitmap (it is useful for "wide" animations, like Rotate)
- bool
AnimateOnlyDifferences
- Allows to animate only differences between start view of control and finish view (only for AnimationMode.Update). By default True
.
To create custom animation, you need to handle events
TransfromNeeded
and/or
NonLinearTransfromNeeded
. The example see in demo application.
Animator
has a good set of techniques to control the animation. Each method is asynchronous and synchronous versions. Asynchronous methods starts animation and returns immediately. Synchronous methods starts animation and wait while animation will be completed.
In addition the
Animator
supports queue of animated controls. You can use methods
AddToQueue()
and
ClearQueue()
for it.
Also, the
Animator
has methods to wait for all outstanding animations and methods to wait for the particular animation.
Moreover, the
Animator
has events
AnimationCompleted
and
AllAnimationsCompleted
that are invoked after any/all animation was completed.
Extended controls
The library contains extended TabControl. It is usual TabControl, but its tabs are animated:
The TabControlEx conatins property
Animation
, where you can adjust animation of tabs.
Demo app
You can use the demo app for that would evaluate the possibilities of Animator:
Decoration sample (BottomMirror mode):
Restrictions
The Animator does not work with OLE-based controls (WebBrowser, RichTextBox). These controls do not paint itself when window is not visible. So we can not to grab bitmap from it.
History
19 Feb 2013 - First release.
20 Feb 2013 -
TabControlEx
was added,
ClipRectangle
is available for Update mode.
22 Feb 2013 - Performance was increased. Some bugs was fixed. Decoration sample was added
.