FireMonkey Animation Effects
Go Up to FireMonkey Applications Guide
Animations modify property values over time. They can be started automatically or manually, both with an optional delay. After the animation has run its course over the defined time period, it can stop, start over, or do the same but in reverse.
Kinds of Animation
The provided subclasses of TAnimation fall into three categories:
- Interpolations from a start value to an end value:
- TFloatAnimation changes any numeric property like position (X, Y, and Z axes must be done separately), rotation, and opacity.
- TRectAnimation changes the location of the four edges of a TBounds property.
- TColorAnimation changes any string or integer property that contains a color, including those of type TAlphaColor (which is actually a Cardinal number), by modifying the red, green, blue, and alpha values of the color.
- TGradientAnimation changes a gradient (type TGradient) by modifying the colors of each point that defines the gradient.
- TBitmapAnimation transitions from a starting bitmap image to another by drawing the final image (type TBitmap) with increasing opacity, causing it to fade into view.
- Interpolating through a series of values, not just two: from the first to the second, from the second to the third, and so on:
- Stepping through a list without interpolation:
- TBitmapListAnimation works like a timed slideshow, with all images combined horizontally into a single bitmap. With a fast frame rate (short duration and/or many images), it looks like a movie.
Animations attach as children of the object being animated, just like any other subcomponent. Then the PropertyName property is set to a dotted property path, as used with System.TypInfo functions like GetPropInfo; for example, "Opacity" and "Position.Y".
In the Object Inspector, commonly animated properties are indicated with a film strip icon. Choosing to create an animation from the property value's drop-down menu will automatically set the PropertyName. Animation objects added from the Component Palette must set the PropertyName manually.
TFmxObject provides a few convenience methods to create numeric and color animations from code, with the PropertyName and ending value as the required arguments. These animations always start immediately from the current value, are non-looping, and free themselves when finished. The numeric animations can also start with a delay or wait on the main thread until finished.
Starting and Stopping
If an animation's Enabled flag is set to True in the Form Designer, it will automatically Start after loading. Setting it to True in code will also Start the animation; setting it to False will Stop it. Conversely, calling Start and Stop will set Enabled to match.
In TFloatAnimation, StartFromCurrent will automatically overwrite the StartValue with the current property value when the animation is started (either by calling Start or if it is Enabled). There is no point setting StartValue if StartFromCurrent is True.
Note: This is especially relevant when manually looping or reusing animation objects. If the previous run used StartFromCurrent, and the next run uses a StartValue, then StartFromCurrent must be set to False.
To stop the animation:
- Setting Pause to True will allow the animation to resume from that point, by setting it back to False.
- Calling Stop will skip to the end of the animation. The property is set to the final value (StopValue if Inverse is False, StartValue if Inverse is True), and OnFinish fires.
- StopAtCurrent does not set the property to the final value, but still fires OnFinish.
In addition to automatically starting with Enabled and manually calling Start and Stop, animations can be triggered from property changes. Triggers don't work with every arbitrary property, but only with particular properties that are checked during the component's internal event processing. All built-in triggers check boolean properties, and by convention the names of these properties start with "Is". TControl and TControl3D provide four triggers for every control and shape:
Other built-in triggers include:
- IsPressed (TCustomButton, TRadioButton, TCheckBox)
- IsChecked (TRadioButton, TCheckBox, TMenuItem)
- IsSelected (TMenuItem, TTabItem, TListBoxItem, TTreeViewItem)
- IsExpanded (TTreeViewItem, TExpander)
- IsActive (TCustomForm)
Note: A slightly different set of triggers is provided for other non-animation image effects.
Animations can be set to Start when any of these properties change as the result of code or user action. When the trigger condition no longer holds, the animation will Stop. Trigger conditions are limited to equality checks, and if the trigger contains more than one condition, they must all evaluate to true for the trigger to fire. A trigger is expressed as a string containing one or more trigger conditions, separated by semicolons. Each trigger condition consists of the property name, an equal sign, and the trigger value. All the built-in triggers are boolean, so their value must be either "true" or "false". For example:
Trigger conditions are stored in two properties, Trigger and TriggerInverse. As their names suggest, the former will simply Start the animation as defined, while the latter will set the animation's Inverse flag first. Because of the way animations run in reverse, and the way animations will immediately "stop at the finish" when the condition no longer holds, instead of a single animation with opposite trigger conditions, sometimes two separate animations defined as opposites are required, each with one of the opposite triggers.
Inverting and Looping
Inverse works by "running time backwards"; it does not flip the start and stop values. Therefore, with both Inverse and StartFromCurrent True, the property will first jump to StopValue, and then animate back to the value at the time the animation started: in effect, "stop at current" (like the boolean StartAtCurrent, not the procedure StopAtCurrent).
Custom animation components can be created by subclassing TAnimation and implementing ProcessAnimation.