Animations and Effects

Morfik includes built-in support for browser-side image animation and transition effects through the SystemAnimations module. Included in the module are support for Fade, Move, Resize, Resize to Vertical Center, and Resize to Horizontal Center transitions. All these transitions can be combined to create a large variety of transition effects and animations.

Animation and Transition Basics

Animations and transitions may be applied to any Morfik control but most often used for images, specifically the Image control. To begin an animation, an object of class TAnimationEffects must first be created which requires a parameter that specifies for how many milliseconds the effect will last. After creating a TAnimationEffects class, new effects of type TAnimationEffect may be added using the the TAnimationEffects.AddEffect method. Finally the animation/transition can be invoked by calling the Animate method or the AnimateSequence methods.

The SystemControls module defines the TEffectType enumeration: etEaseIn (reveal the image) and etEaseOut (hide the image). Any effect created must specify one of these two types in it's creation. Also defined in this module is the TEffectTransition enumeration which contains the following options: etNone, etLinear, etElastic, etBounce, etBack, etQuad, etCubic, etQuart, etExponent, etSin and etSqrt. Both the SystemControls and SystemAnimations modules must be included in any module utilizing animations and effects. Note: SystemControls is automatically added to any Form module.

A Sample Fade Transition

The code below shows an example of creating and applying a fade transition effect to an Image1 control. The first line under ShowAnimation creates a new TAnimationEffects object with a duration of a quarter of a second. Next a new TAnimationEffect is created (Animation) where the first parameter is the handle of the Image control, the second parameter is a pointer to the built-in Fade transition (in the SystemAnimations module), the third parameter specifies that the effect will start slowly and then speed up to finish and the fourth parameter specifies that no special addition effect will be applied (since none of the enumerated options would impact the Fade transition).

The next two lines specify that the animation will begin with the image completely visible and end completely transparent. Setting the Opacity only effects the Fade transition.

Finally the Animate method is invoked to apply the Effects with the VisibleTrue method to be applied before the start of the animation, no method involked at the end of the transition and no method involked during the process.


Form1 = Class(Form)
  { … }
  Private
    { Private declarations }
    Effects   : TAnimationEffects;
    Animation : TAnimationEffect;
End;
 
Procedure Form1.VisibleTrue;
Begin
    Image1.DOMStyle.display := '';
End;
 
Procedure Form1.ShowAnimation;
Begin
    Effects   := TAnimationEffects.Create(250);
    Animation := Effects.AddEffect(Image1.DOMHandle, @FadeTransition, etEaseIn, etNone);
    Animation.StartOpacity := 0;
    Animation.EndOpacity   := 100;
    Animate(Effects, GetMethodPointer(Self, @VisibleTrue), nil, nil);
End;


Note: The etEaseIn effect is designed to start slowly and then speed up while the etEaseOut should start fast and slow down. Currently the EaseIn transition is not working correctly (it's functioning the opposite to the way it should) and this will be fixed in the first M3 update.

More Transition Effects

The code below demonstrates some samples of the other transition effects. In each sample EftType is one of the two TEffectTypes and AddedEffect is one of the 11 TEffectTransition types. Each sample demonstrates the different Animation properties that should be set for that type. Any of the transitions can be combined with any of the others to create new transition types. If Animations are combined they are applied simultaneously in the transition. See further below for a sample of a applying transitions sequentially.


    { Use the Move transition }
    Animation := Effects.AddEffect(Image1.DOMHandle, @MoveTransition, EftType, AddedEffect);
    Animation.StartTop     := Image1.Top + 100;
    Animation.EndTop       := Image1.Top;
    Animation.StartLeft    := Image1.Left;
    Animation.EndLeft      := Image1.Left;
 
    { Use the Resize transition }
    Animation := Effects.AddEffect(Image1.DOMHandle, @ResizeTransition, EftType, AddedEffect);
    Animation.StartHeight  := 0;
    Animation.StartWidth   := 0;
    Animation.EndHeight    := Image1.Height;
    Animation.EndWidth     := Image1.Width;
 
    { Use the Resize to Vertical Center transition }
    Animation := Effects.AddEffect(Image1.DOMHandle, @ResizeCenterHorzTransition, EftType, AddedEffect);
    Animation.StartWidth   := 0;
    Animation.EndWidth     := Image1.Width;
    Animation.StartLeft    := Image1.Left + Image1.Width div 2;
    Animation.EndLeft      := Image1.Left;
 
    { Use the Resize to Horizontal Center transition}
    Animation := Effects.AddEffect(Image1.DOMHandle, @ResizeCenterVertTransition, EftType, AddedEffect);
    Animation.StartHeight  := 0;
    Animation.EndHeight    := Image1.Height;
    Animation.StartTop     := Image1.Top + Image1.Height div 2;
    Animation.EndTop       := Image1.Top;


Sequential Transitions

Instead of applying transitions all at once, some small adjustments to the code will create an animation that is a sequential series of animations using the AnimateSequence method. The difference between the Animate and AnimateSequence methods is only that the first parameter of AnimateSequence is a Array type.

In the code below an array is created to hold the animations as they are created and will be played back in the order they are pushed on to the array. Also note that, although not displayed in the code below, multiple transitions can be added to each Effect and they would be played back simultaneously.

Procedure Form1.Shake;
Var
    Animations  : TArray;
Begin
    Animations  := TArray.Create;
 
    Effects   := TAnimationEffects.Create(60);
    Animation := Effects.AddEffect(Image1.DOMHandle, @MoveTransition, etEaseOut, etNone);
    Animation.StartLeft  := Image1.Left;
    Animation.EndLeft    := Image1.Left - 20;
    Animation.StartTop := Image1.Top;
    Animation.EndTop   := Image1.Top;
    Animations.push(Effects);
 
    Effects   := TAnimationEffects.Create(60);
    Animation := Effects.AddEffect(Image1.DOMHandle, @MoveTransition, etEaseIn, etNone);
    Animation.StartLeft  := Image1.Left;
    Animation.EndLeft    := Image1.Left - 40;
    Animation.StartTop := Image1.Top;
    Animation.EndTop   := Image1.Top;
    Animations.push(Effects);
 
    Effects   := TAnimationEffects.Create(60);
    Animation := Effects.AddEffect(Image1.DOMHandle, @MoveTransition, etEaseIn, etNone);
    Animation.StartLeft  := Image1.Left;
    Animation.EndLeft    := Image1.Left + 40;
    Animation.StartTop := Image1.Top;
    Animation.EndTop   := Image1.Top;
    Animations.push(Effects);
 
    { … }
 
    AnimateSequence(Animations, nil, nil, nil);
End;


A Sample Application is Available

The code snippets above are derived from a sample application demonstrating the animation and transition effects available from the Morfik Sample Projects page.


Related Topics


Back to top