Storyboard makes it simple to add life and movement to your application.
The Engine supports user defined animations using the animation action, gra.animate
. This action starts executing an animation immediately, monitors the animation, and applies the specified changes as they have been defined by the user in Designer.
An animation is a named block of operations that will perform changes on Storyboard data values at a predetermined frame rate. The individual data changes that occur within an animation are referred to as animation steps.
An animation step contains the following information:
- key
-
The key is a reference to the data object that is going to be changed over the course of the animation. In general, keys are numeric items such as x or y position, width, height or transparency (alpha) values. However, it is possible with 0 duration animation steps to apply a change to any variable at a point in the animation. This includes text or images.
- offset
-
This is the time in milliseconds from the time that the animation was started that this particular change will start to occur.
- duration
-
This is the time in milliseconds over which the change will occur. This value may be 0 for changes that are not numeric (i.e. text or image values) or if the animation step is defined to occur at the start or end of the animation block.
- rate
-
For non-zero duration animation steps, this is the change curve that will be applied to the numeric value from its start value to the end value. Example rates include linear, ease in (easein), ease out (easeout), ease in out (easeinout) or bounce.
- starting value
-
This represents the starting value of the animation. The starting value can be either a specific value or variable reference, or it can be specified as the current value of the animation key at the time that the animation starts. Using the current value is good for animations that need to work generically to achieve some end value.
- end value
-
This represents the end value of the animation. The end value can be either a specific value or variable reference or it can be specified as an offset from the starting value rather than as an absolute value. Using an offset (or delta) in an animation makes it easy to perform incremental animations on objects.
Animation steps are all synchronized within an animation block so that their data changes will occur in a synchronized manner. While it is possible to specify arbitrary time offsets and duration, these values will be mapped onto the nearest synchronized frame slot. The frame slots are dictated by the frame rate of the animation block.
Animation instances can be labelled with a string id
which is an identifier used to provide exclusive execution. It is possible for many animations to run concurrently, however if two animations have the same id
value, then only the last one invoked will actually run. For example, if you have an animation to shrink and grow a control, then you only want one of either the shrink or grow operations to occur at one time. This can be achieved by having the shrink and grow animation actions share the same identifier.
Animations may be stopped at any time by using the animation stop action, gra.animate.stop
.
Animations can also be created in the more traditional method of setting a timer and operating on data on every timer firing. By manipulating data in the timer callback, clients can cause any number of custom behaviors to occur, as the data changes on variables will automatically be reflected through to the user interface as would be done at any other time.
The timer callback allows non-traditional data change rates to be applied, as well as flip-book style animations where a sequence of images is pre-defined and changed on each timer iteration. This could be achieved through a series of 0 duration animations as of Storyboard 3.0.
Animations are frequently used during screen transitions. A screen transition is a way to move from the visible screen to a new screen which may or may not have common layers. By default, screen transitions can be invoked by using one of the following actions:
- gra.screen
-
Transition to a new screen immediately
- gra.screen.fade
-
Fade the new screen into the current screen over time
- gra.screen.path
-
Slide the new screen in and the old screen out over time, from one of the following directions
-
Left
-
Right
-
Top
-
Bottom
-
- gra.screen.scale
-
Grow the new screen over the current screen
All transition actions, which are time-based, take similar arguments that control the duration of the transition, the rate at which the transitions will occur, the orientation of the transition, and the number of frames that should be used. Using these arguments, the designer can control the user experience (e.g., duration and effects) as well as the overhead incurred on the system (frequency of frame updates).
During a screen transition, four events will be generated to notify the system of the current state. These events are:
- gre.screenshow.pre
-
This event is generated for the new screen being shown. The event will be generated before the transition starts. This event gives the user a chance to change data via the gra.datachange action or Lua before their transition content is updated.
- gre.screenhide.pre
-
This event is generated for the previous screen being hidden. The event will be generated before the transition starts.
- gre.screenshow.post
-
This event is generated for the new screen being shown. The event will be generated after the transition has completed.
- gre.screenhide.post
-
This event is generated for the previous screen being hidden. The event will be generated after the transition has completed.
The following illustrates the sequence of events:
The transitions are written such that if graphics hardware layer support is are available, then these layers, assuming they are available for use, will be leveraged to lower the processing overhead for the system during the transition period. Experience has demonstrated that it is possible to achieve smooth transitions at almost no CPU cost when the hardware capabilities can be properly leveraged.