How to use Cascades built-in animations

Nowadays, there’s a lot of mobile app developers and your apps need to stand out to catch the user’s attention. Most users like to interact with the app, and animations can bring this interaction to another level, not only letting the user touch a component on the screen and have a reaction, but also having this component to move, scale, fade or rotate to create a real sense of interaction and fluidity.

Hopefully, Cascades makes it easy to use animations with only a few lines of code.

 

IMPLICIT AND EXPLICIT ANIMATIONS

Cascades support 2 types of animations, implicit and explicit animations. Implicit animations doesn’t need any coding and can be used on 2 types of properties :

  • Properties that determine how a control looks, such as rotation, translation, and opacity
  • Properties that determine the layout of a control in a container, such as preferred width and preferred height

So if you set the opacity of a Button to 0, it will fade out gradually instead of becoming invisible right away. Cascades takes care of the animation, you don’t have to write any line of code for this fade out animation.

Here’s some sample code to test implicit animations :

import bb.cascades 1.0

Page {
    
    content: Button {
        
        text: "Click me"
        
        onClicked: {
            
            translationX += 20
            
            opacity -= 0.2
            
            if (opacity == 0)
                
                opacity = 1
        
        }
    
    }

}

EXPLICIT ANIMATIONS : FADE, ROTATE, TRANSLATE, SCALE

If you want to have more control on the animation used, then you’ll want to look into explicit animations, where you can set from and to values, duration, easing curve, a delay before the animation start or number of repeat for your animation. Let’s take a fade transition, we want a Button to fade slowly from 1.0 to 0.0 and make it repeat forever :

import bb.cascades 1.0

Page {
    
    content: Container {
        
        Button {
            
            text: "Click me"
            
            animations: [
                
                FadeTransition {
                    
                    id: fadeTransition
                    
                    duration: 3000
                    
                    fromOpacity: 1.0
                    
                    toOpacity: 0.0
                    
                    repeatCount: AnimationRepeatCount.Forever
                
                }
            
            ]
            
            onClicked: {
                
                fadeTransition.play()
            
            }
        
        }
    
    }

}

So we have a better control of the animation with an explicit animation. There are 4 types of animations that can be controlled with explicit animation :

  • Fade transition
  • Rotate transition
  • Translate transition
  • Scale transition

 

GROUP ANIMATIONS

It’s even possible to group animations together and make them perform one after the other or all at the same time. Those are called SequentialAnimation and ParallelAnimation. Let’s try both to see the difference.

import bb.cascades 1.0

Page {
    content: Container {
        Button {
            text: "Click me"
            
            animations: [
                ParallelAnimation {
                    id: parallelAnimation
                    
                    animations: [
                        TranslateTransition {
                            toX: 400
                            duration: 2000
                        },
                        RotateTransition {
                            toAngleZ: 180
                            duration: 2000
                        }
                    ]
                }
            ]
            
            onClicked: {
                parallelAnimation.play();
            }
        }
        Button {
            text: "Click me"
            
            animations: [
                SequentialAnimation {
                    id: sequentialAnimation
                    
                    animations: [
                        TranslateTransition {
                            toX: 400
                            duration: 2000
                        },
                        RotateTransition {
                            toAngleZ: 180
                            duration: 2000
                        }
                    ]
                }
            ]
            
            onClicked: {
                sequentialAnimation.play();
            }
        }
    }
}

For now, all the animations used were a little bit useless, but they showed possibilities. For a real life example, let’s say we have a freemium app and we want to invite the user to upgrade to Pro version, we can do it like this :

import bb.cascades 1.0

Page {
    property int deviceWidth: 1440 // Set it to your screen width
    property int deviceHeight: 1440 // Set it to your screen height
    content: Container {
        layout: DockLayout {}
        horizontalAlignment: HorizontalAlignment.Fill
        verticalAlignment: VerticalAlignment.Fill
        Container {
            id: mainAppContainer
            Label {
                text: "This is your main app"
            }
            Container {
                topPadding: 30
                Button {
                    text: "Random action that prompt user to upgrade"
                    onClicked: upgradeContainer.visible = true
                }
            }
        }
        Container {
            id: upgradeContainer
            background: Color.Black
            horizontalAlignment: HorizontalAlignment.Fill
            verticalAlignment: VerticalAlignment.Fill
            opacity: 0.7
            visible: false
            onVisibleChanged: {
                if (visible) {
                    upgradeButton.translationX = deviceWidth // Make it out of sight
                    upgradeButton.translationY = deviceHeight // Make it out of sight
                    noThanksButton.translationX = deviceWidth // Make it out of sight
                    noThanksButton.translationY = deviceHeight // Make it out of sight
                    
                    upgradeButtonAnimation.play()
                    noThanksButtonAnimation.play()
                } 
            }
            Button {
                id: upgradeButton
                text: "Upgrade"
                preferredWidth: 300
                preferredHeight: 30
                onClicked: upgradeContainer.visible = false
                animations: [
                    ParallelAnimation {
                        id: upgradeButtonAnimation
                        RotateTransition {
                            fromAngleZ: 160
                            toAngleZ: 0
                            duration: 1500
                            easingCurve: StockCurve.ElasticOut
                        }
                        TranslateTransition {
                            fromX: deviceWidth * 0.75
                            fromY: deviceHeight
                            toX: (deviceWidth / 2) - (upgradeButton.preferredWidth / 2)
                            toY: (deviceHeight / 2) - (upgradeButton.preferredHeight / 2)
                            duration: 1500
                            easingCurve: StockCurve.ElasticOut 
                        }
                    }
                ]
            }
            Button {
                id: noThanksButton
                text: "No Thanks"
                preferredWidth: 300
                preferredHeight: 30
                onClicked: upgradeContainer.visible = false
                animations: [
                    ParallelAnimation {
                        id: noThanksButtonAnimation
                        delay: 4000 // Setting a delay will make this button appear later
                        RotateTransition {
                            fromAngleZ: 160
                            toAngleZ: 0
                            duration: 1500
                            easingCurve: StockCurve.ElasticOut
                        }
                        TranslateTransition {
                            fromX: deviceWidth * 0.75
                            fromY: deviceHeight
                            toX: (deviceWidth / 2) - (noThanksButton.preferredWidth / 2)
                            toY: (deviceHeight / 2) - (noThanksButton.preferredHeight / 2) + upgradeButton.preferredHeight
                            duration: 1500
                            easingCurve: StockCurve.ElasticOut
                        }
                    }
                ]
            }
        }
    }
}

What’s happening here is when a certain action is performed by the user, it shows a semi-transparent black screen (opacity 0.7) and then 2 buttons comes from out of sight to the middle of the screen, an ‘Upgrade’ button and a ‘No Thanks’ button. User have to click either one to continue to use the app.

Animations can be a lot of fun in Cascades, it’s powerful, simple to code and look nice. It allows your app to stand out from the crowd, so go ahead, and play with it!

Reference : https://developer.blackberry.com/native/documentation/cascades/ui/animations/index.html

Roger Leblanc About Roger Leblanc
BlackBerry Enterprise Developer Group manager in Montreal, Cascades Sample Code BBM Channel manager and BlackBerry developer support forum contributor, I like to help new devs who wants to learn Cascades. I publish a lot of sample code on GitHub.

About Roger Leblanc

BlackBerry Enterprise Developer Group manager in Montreal, Cascades Sample Code BBM Channel manager and BlackBerry developer support forum contributor, I like to help new devs who wants to learn Cascades. I publish a lot of sample code on GitHub.