23 December 2014
Tutorial: Controlling Composer scene transitions
Corona’s Composer scene management library is quite powerful in giving you the ability to move multiple scenes on and off screen. As part of the core library, Composer supports numerous scene transitions including:
- fade — the current scene fades out and then the next scene fades in.
- zoomOutIn — the current scene shrinks to nothing, then the new scene emerges from nothingness to fill the screen.
- zoomOutInFade — like zoomOutIn, but including fade as well.
- zoomInOut — the scene starts larger than the screen, shrinks to fit, and then zooms out when closing.
- zoomInOutFade — like zoomInOut, but including fade as well.
- flip — the scene scales to width of 0 and then back out, providing a flip effect.
- flipFadeOutIn — flip and fade combination.
- zoomOutInRotate — like zoomOutIn, but also with 360 degrees rotation.
- zoomOutInFadeRotate — like zoomOutIn, but also with fade and 360 degrees rotation.
- zoomInOutRotate — like zoomInOut, but also with 360 degrees rotation.
- zoomInOutFadeRotate — like zoomOutIn, but also with fade and 360 degrees rotation.
- fromRight — slides the new scene from the right side (over the existing scene).
- fromLeft — slides the new scene from the left side (over the existing scene).
- fromTop — slides the new scene from the top (over the existing scene).
- fromBottom — slides the new scene from the bottom (over the existing scene).
- slideLeft — like fromRight, but the new scene pushes the current scene off to the left.
- slideRight — like fromLeft, but the new scene pushes the current scene off to the right.
- slideUp — like fromBottom, but the new scene pushes the current scene off the top.
- slideDown — like fromTop, but the new scene pushes the current scene off the bottom.
- crossFade — the current scene fades out while the new scene fades in.
These transitions cover many of the usage cases that you’ll need, but there are times when you may desire slightly different behavior. For example, let’s say you want to rotate the scene three times instead of just once, or you want the new scene to fade in while moving over top of the current scene. Essentially, if you envision some scene transition that doesn’t exist in the list above, keep reading because this tutorial will show you how to achieve it.
Introducing the “effectsList” table
When you require()
the Composer library, there’s a publicly-accessible table which you gain access to. This is known as the effectsList
table. Within this table, each defined effect has two subtables: from
and to
, and within these, several attributes to control the transition behavior.
Before you continue, it will be helpful to get a table printing function from this tutorial, including the print_r()
function. Then, assuming that both the Composer library and utility.lua
is included in your project, code the following:
1 2 |
utility.print_r( composer.effectList ) |
In the Terminal/console, you can examine the output and see how each effect is managed. Let’s look at the simplest case, fade
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
["fade"] = { ["from"] = { alphaStart = 1.0, alphaEnd = 0 }, ["to"] = { alphaStart = 0, alphaEnd = 1.0 } }, |
In this case, the transition is named fade
(the first key in the table). It has two child tables, from
and to
. Both of these tables have two child parameters: alphaStart
and alphaEnd
. Effectively, the Composer library will take the alphaStart
value and set the scene’s alpha property to that, then tell transition.to() to change the alpha to the alphaEnd
value.
A more complex example is zoomOutInFadeRotate
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
["zoomOutInFadeRotate"] = { ["from"] = { xEnd = displayW*0.5, yEnd = displayH*0.5, xScaleEnd = 0.001, yScaleEnd = 0.001, rotationStart = 0, rotationEnd = -360, alphaStart = 1.0, alphaEnd = 0 }, ["to"] = { xScaleStart = 0.001, yScaleStart = 0.001, xScaleEnd = 1.0, yScaleEnd = 1.0, xStart = displayW*0.5, yStart = displayH*0.5, xEnd = 0, yEnd = 0, rotationStart = -360, rotationEnd = 0, alphaStart = 0, alphaEnd = 1.0 }, hideOnOut = true }, |
In this case, xScale
, yScale
, x
, y
, rotation
and alpha
all have Start
and End
values set, just like alpha
in the first example.
Customizing transitions
If you want to change these values, you can do so at any time before you call composer.gotoScene() or composer.showOverlay() by simply providing the proper table with new values. For instance, if you want to rotate the scene three times using zoomOutInFadeRotate
, simply set the rotation values to -1080
(3
×-360
):
1 2 3 |
composer.effectList.zoomOutInFadeRotate.from.rotationEnd = -1080 composer.effectList.zoomOutInFadeRotate.to.rotationStart = -1080 |
Keep in mind that these values will stay in effect until they are explicitly reset, the app is restarted, or you un-require()
the Composer library.
For future reference, the attributes which can be set/changed on the from
and to
tables of a scene transition effect include:
xStart
,xEnd
yStart
,yEnd
alphaStart
,alphaEnd
xScaleStart
,xScaleEnd
yScaleStart
,yScaleEnd
rotationStart
,rotationEnd
transition
In addition, there are a few attributes which can be set on the entire transition:
hideOnOut
— hides the previous scene upon completion (for scenes which might still be on top due to their animation).concurrent
— specifies that theto
andfrom
transitions happen at the same time.sceneAbove
— puts the new scene on top of the previous scene.
For example, the only difference between fade
and crossFade
is that the crossFade
transition is that concurrent
is set to true
.
Adjusting transition easing
Another thing you might want to adjust is the easing on a particular transition, or add easing to a scene transition effect which doesn’t have one. Easing allows transitions to behave distinctly based on several preset options (see the Corona easing library for details on the various easing algorithms).
For instance, if you want to apply easing on the fade
scene transition, code these lines:
1 2 |
composer.effectList.fade.from.transition = easing.outQuad composer.effectList.fade.to.transition = easing.outQuad |
Creating new scene transitions
In a similar manner to editing existing scene transition effects, you can create your own as well. For example, you can make a transition similar to the one seen in iOS 7 where the original scene and the new scene transition at different speeds, providing for a more interesting animation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
composer.effectList["iosSlideLeft"] = { sceneAbove = true, concurrent = true, to = { xStart = display.contentWidth, yStart = 0, xEnd = 0, yEnd = 0, transition = easing.outQuad }, from = { xStart = 0, yStart = 0, xEnd = -display.contentWidth * 0.3, yEnd = 0, transition = easing.outQuad } } composer.effectList["iosSlideRight"] = { sceneAbove = false, concurrent = true, to = { xStart = -display.contentWidth * 0.3, yStart = 0, xEnd = 0, yEnd = 0, transition = easing.outQuad }, from = { xStart = 0, yStart = 0, xEnd = display.contentWidth, yEnd = 0, transition = easing.outQuad } } |
Conclusion
By editing and adding to the accessible effectsList
table, you can change how Composer behaves when transitioning scenes. However, be careful with the values that you specify, as incorrect values may cause your scenes to move only partially off screen, complete upside-down, and so forth. Still, with a little experimentation — none of which will permanently corrupt the Composer library — there is virtually no limit to the interesting scene transition effects you can achieve.
Vasya Uillison
Posted at 23:27h, 23 DecemberCool! Very useful tutorial!
JCH_APPLE
Posted at 00:07h, 24 DecemberSanta Claus does exist :
Thank you Rob, and Merry Xmas to everybody
Simon Fearby
Posted at 19:04h, 02 JanuarySample Project
Rob Miracle
Posted at 20:10h, 02 JanuaryGrab the sample code from CoronaSDK/SampleCode/Interface/Composer
Drop the above code in your main.lua and play around.
Rob
Space Wolf
Posted at 12:49h, 11 MarchJust what I needed, thanks!