Omnis Technical Note TNXM0004 July 2014

Animating Objects using the Transform Component

For Omnis Studio 6.1
By Gary Ashford

What is the Transform Component?
By placing a transform component on your window class you can add simple but effective 2-dimensional transform effects to your desktop applications.
The transform component can dynamically scale, translate and resize any number of object attributes from their current state to another state using a series of incremental steps.

The typical application of the transform object is in modifying the $top, $left, $width and $height properties of window objects but the transform object can modify any window attribute that accepts a numeric value for example, $fontsize (of text objects) and $val (of certain external components).

How Does it Work?
The transform component works in conjunction with Omnis methods which define how each 'state' will look. State methods are created inside the transform class and normally consist of one or more Do...$assign() statements.

Consider the following example where a transform control (trfm1) contains two state methods; '$state1' and '$state2' designed to move a jpeg object across the screen. The trfm1.$state1 method contains:

  Do $cwind.$objs.jpeg1.$left.$assign(20)

and the trfm1.$state2 method contains:

  Do $cwind.$objs.jpeg1.$left.$assign(200)

Calling Do $cwind.$objs.trfm1.$state1() or $state2() will cause the jpeg object to flip across the screen as would be expected. If instead, the transform object's $transform() method is called, this will cause the jpeg to move across the screen in a series of steps as dictated by the transform object's animation settings:

  Do $cwind.$objs.trfm1.$transform('$state2')

By default, the transform object uses a $numsteps value of 20 and a $animdelay value of 20ms between each frame. So in this example, the jpeg would take approximately 0.4 seconds to move across the screen by 180 pixels, moving 9 pixels in each frame.

In reality, a transform state method can contain many Do...$assign() statements. You can also use Calculate...as statements although the transform component will attempt to convert these into Do...$assign() statements during compilation. The transform control will calculate a new value for each assignment statement for each frame. You can delay or 'stagger' animation of various window attributes using special 'wait' statements. These are placed into the state method as comments, for example:

  Do $cwind.$objs.button1.$left.$assign(100)
;     wait 5
Do $cwind.$objs.button2.$left.$assign(130)
;     wait 5
Do $cwind.$objs.button3.$left.$assign(160)
;     wait 5
Do $cwind.$objs.button4.$left.$assign(190)

When the transform control compiles this method it will add a 5 frame delay each time it encounters a wait statement. In this example, 15 frames will have elapsed before button4 starts to move and button1 will finish moving first followed by buttons 2, 3 and 4.

Non-assignment statements inside transform state methods will be ignored by
$transform(). Also, non-numeric attributes such as character and datetime values cannot be transformed.

Sinusoidal & decaying
sinusoidal convergence

It is also possible to add a 'convergence effect' to the animation. Convergence augments the animation step size towards the end of the animation. The transform component supports kConvergeSine- which creates a graduated/sinusoidal effect, and kConvergeOvershoot which modulates the step size using a decaying sinusoid, creating an overshoot or bounce effect.

There can be multiple transform objects on any window class, each with its own $animdelay, $numsteps and $convergence effect.

Using Events
The transform control supports two event codes which can be used to perform additional processing. kTransformBegin occurs whenever $transform() is called to inform the control that animation is about to start. This allows the control to hide certain window attributes for example.
kTransformComplete
occurs when a compiled transform list has executed to completion. Using the kTransformComplete event, it is possible to invoke further transforms thus creating an animation chain that moves through several states. Care should be taken to avoid unwanted recursion however!

If performance is an issue, consider minimizing the number of statements that
$transform() will need to process in each frame.

Example Libraries
Several examples demonstrating the transform component are available. Please note that the libraries and the transform external component are only available for use with Studio 6.1 and later.


comptest.zip

 

Contains several examples including a slide-in tool-tip, group box animation, progress bar/slider follower, playing card demo and text animation.

 

Contains a library, SQLite database and images that demonstrate a simple slideshow. The slideshow contains three elements that slide in and out from different directions.

Contains a library and images that demonstrate a rotating carousel. It uses events to trigger a single transform object with two method states.