Easy Animations With the Animated Transitions

The JavaFX SDK offers some useful features that enable developers to create complex animated and transformational effects by using animation transitions available in the JavaFX API. Learn how to apply classes from the javafx.animation.transition package to build transitions easily.

Essentials of Animated Transitions

For a demonstration of animated transitions, examine the following application. It shows animated transitions built with the basic classes that reside in the javafx.animation.transition package. Click the images to start or pause the animation.

All the transition classes available in the javafx.animation.transition package, such as FadeTransition, RotateTransition, TranslateTransition, ScaleTransition, and PathTransition encapsulate a timeline that performs the specific action on the node. These classes provide handy schemes to implement transitional effects.

This package was introduced to lighten the work of developers who create animated transitions. Each class in the package provides a framework to perform the specific type of animation. Several transitions can be combined into parallel and sequential transitions. All you need is to set up the values for the instance variable that suits your application. The following animated transitions are supported:

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

The most common instance variables for all the previously mentioned transition types are the following.

Instance Variable Description Default Value
duration The length of this transition, in milliseconds. 400 ms
node The target node to which this transition is applied. null
interpolator The type of acceleration and deceleration at each transition cycle. Interpolator.EASEBOTH
autoReverse Defines whether this animation reverses direction on alternating cycles. false
repeatCount The number of cycles in this animation. 1.0
rate Defines the speed at which the animation is expected to be played. 1.0

Thus, you can program a particular animation scenario for a node by altering these variables. Use the play(), pause(), stop(), and playFromStart() functions inherited from the Timeline class to control the animation playback. The paused and running variables helpfully indicate the current state of the animation. Consider the following examples of using the typical animated transitions.

Fade Transition

This transition creates a fade effect animation that spans its duration. This effect is attained by updating the opacity variable of the node at regular intervals. It starts from the fromValue. If this variable is not specified, the node's opacity value is used. The animation stops at the toValue value, if provided. Otherwise, it uses the start opacity value plus the value defined by the byValue instance variable. The toValue takes precedence if both toValue and byValue are specified for the node.

Examine the following code fragment, which defines the fade transition.

Source Code
FadeTransition {
       duration: 3s
       toValue: 0.0
       repeatCount: Timeline.INDEFINITE 
       autoReverse: true
}

The code fragment creates a fade transition so that the opacity of the node changes from its default value, which is 1.0, to the value 0.0 within three seconds. The repeateCount is set to Timeline.INDEFINITE to build a nonstop animation. The enabled autoReverse variable makes this transition run back and forth.

You might want to program the same animation without using the FadeTransition class. In that case, you need to explicitly define the key frame that changes the node's opacity.

Source Code
var fadeTransition = Timeline {
    repeatCount: Timeline.INDEFINITE
    autoReverse: true
    keyFrames : [
        KeyFrame {
            time : 3s
            values : [
               node.opacity => 0.0 tween Interpolator.LINEAR
            ]
        }
    ]
    
};

Note that the use of the animated transitions classes reduces the amount of code and makes it less complex. Refer to Creating Animated Object for more information about key-frame animations.

Translate Transition

This transition creates movements or translate animations. A movement is created by updating the translateX and translateY variables of the node at regular intervals. The animation starts from the point defined by the fromX and fromY variables, if provided. Otherwise, the current node's translateX and translateY values are used. Again, as with the fade transition, you can use either absolute or relative values to specify the target point. The toX and toY variables define the coordinates of the stop point, while the byX and byY variables define the relative coordinate values that are added to the stat coordinate values. The (toX, toY) value takes precedence if both (toX, toY) and (byX, byY) values are specified.

The following code fragment defines the back-and-forth vertical movement that occurs within two seconds.

Source Code
TranslateTransition {
         duration: 2s
         byY: 100 
         repeatCount: Timeline.INDEFINITE
         autoReverse: true
}

The task of your application might differ from creating vertical, horizontal, or other types of linear translations. You might want to create objects that wander along an arbitrary path. In that case, you need to follow another approach. Creating Animated Objects explains how to create an object that travels along a nonlinear path by defining two KeyFrame objects.

Rotate Transition

This type of transition creates a rotation animation by updating the rotate variable of the node at regular intervals. The angle value is specified in degrees. It starts from the fromAngle if provided, otherwise the node's rotate value is used. The stop value is defined by the toAngle variable or the relative counterpart, byAngle. The toAngle takes precedence if both toAngle and byAngle are specified.

The following code example creates a transition that rotates the node nonstop by 360 degrees. The fromAngle value is not specified. Therefore, the transition starts from the angle of 0 degrees, the default value of the node's rotate variable.

Source Code
RotateTransition {
        duration: 3s
        byAngle: 360 
        repeatCount:Timeline.INDEFINITE
        interpolator: Interpolator.LINEAR
}

Note that this sample uses the linear interpolation instead of the default type EASEBOTH. The EASEBOTH type makes the transition slightly slow down at the start and at the end of the timeline cycle, while the arrow is supposed to be rotated gradually.

You might also experiment with the autoReverse variable. Set its value to true to enable clockwise and counterclockwise rotation on the altering cycles.

Recall from Enhance Your Application by Applying Transformations that a node can be rotated not only around its center. You can explicitly specify the pivot point around which the rotation occurs. If that's the case, you have to create a key-frame animation and bind the altering value to the angle parameter of the Transform.rotate function.

Scale Transition

This transition creates a scale animation by updating the scaleX and scaleY variables of the node at regular intervals. As with other transitions, you can use either absolute or relative values to build animation. The fromX and fromY values define the start-scaling values for this transition. It they are not specified, the current values of the node's scaleX and scaleY variables are used. The stop-scaling values are defined by the toX and toY variables, if provided. Otherwise, the byX and byY are taken into calculations. As mentioned previously, absolute values take precedence over the relative values, if both pairs are specified.

The following code fragment applies an altering scale transition to the node, thus, creating an effect of a pulsing heart.

Source Code
ScaleTransition {
           duration: 1s
           toX: 0.8 
           toY: 0.8
           repeatCount:Timeline.INDEFINITE 
           autoReverse: true
}

If the scenario of your application requires you to scale the object so that the transition is directed to an arbitrary point of the scene, you cannot use the ScaleTransition class. This class builds the animation that scales a node relative only to its center. To implement the specific scaling animation, you have to create a key-frame animation and bind the scaling values to the corresponding parameters of the Transform.scale function.

Path Transition

The path transition creates a translation along the path. The transition is achieved by updating the translateX and translateY variables of the node. However, unlike the translate transition, the path transition moves the object along the geometric path created by the AnimationPath#createFromPath function.

In your application, create the path variable as shown in the following code fragment.

Source Code
var path = Path {
        elements: [
            MoveTo { x: 50 y: 40 },
            ArcTo { x: 380  y: 40  radiusX: 350  radiusY: 80 sweepFlag: true}
        ]
}

This code produces the following path.

arbitrary path Figure 1: Arbitrary Path

You can also use the SVGPath class to create the required curve. The PathTransition object then uses this path to create the animation. Note that the path is not visualized, unless explicitly added to the scene of the application.

Source Code
PathTransition {
          duration: 5s
          path: AnimationPath.createFromPath(path)
          orientation: OrientationType.ORTHOGONAL_TO_TANGENT
          repeatCount: Timeline.INDEFINITE  
          autoReverse: true
}

The orientation instance variable specifies the upright orientation of the node along the path.

the orientation ortogonal to tangent Figure 2: Orthogonal Orientation

By default, the object does not change its orientation. The orientation value is OrientationType.NONE in this case. The OrientationType.ORTHOGONAL_TO_TANGENT value specifies that the object moves perpendicular to the path's tangent along the geometric path. The latter orientation type was applied to the code sample to produce an effect of a boat bobbing on waves.

The path transition is one of the most useful animated transitions available in the javafx.animated.transition package. It can save you hours of programming the key-frame animations. All you need is to construct the path you wish and define which of the orientation types better suits to your application.

Controlling the Timeline Cycle

In the code samples discussed in this article, you click the image to start, pause, and resume the animation. Study the following code fragment to see how the applications control the animation timeline cycle.

Source Code
ImageView {
           fitWidth: fitWidth
           preserveRatio: true
           image: image
           onMouseClicked: function( e: MouseEvent ):Void {
            if (not transition.running or transition.paused) {
             transition.play()
             } else {
             transition.pause()
             }
           }
    }

Use the running and paused Boolean instance variables to reveal the current state of the animation. Use them in the if expression and apply the play() or pause() functions accordingly. Study the source files of the code sample for more details about the usage of animated transitions.

Parallel and Sequential Transitions

You have learned how to add animated transitions to your application and how to control the animation timeline. Consider how the animation transitions mentioned in this article can be used to create more complex animation constructions. You can combine several transitions into groups by using the ParallelTransition and SequentialTransition classes. The ParallelTransition class enables starting all the transitions declared in its content variable in parallel. The SequentialTransition starts all the transitions one by one, in sequential order. Note that duration, repeatCount, and autoReverse instance variables have no effect on these classes and are defined separately for each transition declared in the content variable.

Another class you might need when creating custom transitions is the PauseTransition class. This type of transition executes a specific action at the end of the time interval defined by the duration instance variable. If the action function is not defined for this PauseTransition object, the application simply waits the specified time interval before proceeding to the next operation.

The following code fragment applied to the bubbles variable makes the bubbles go up and rotate at the same time. The transition occurs once.

Source Code
ParallelTransition {
                content: [
                    RotateTransition {
                           duration: 3s
                           byAngle: 360
                           interpolator: Interpolator.LINEAR
                    },
                    TranslateTransition {
                          duration: 3s
                          byY: -100
                    }
                ]
}

The following code fragment uses the SequentialTransition class to apply a complex animated transition to the balloons. They move up, stay there for 3 seconds, and then disappear.

Source Code
SequentialTransition{
               content:[
                   TranslateTransition {
                      duration: 2s
                      byY: -100
                   },
                   PauseTransition { duration: 3s },
                   FadeTransition {
                     duration: 1s
                     toValue: 0.0
                   }
               ]
}

Sequential and parallel transitions can be used in combination to create even more advanced visual effects. If a desired transformation cannot be implemented by a combination of any predefined animated transitions, override the rebuildKeyFrames() function of the Transition class to implement the key frames that suit the logic of your application.

Try It. Create a horizontal or vertical transition of the Text node so that the text fades in before the movement starts.

Related Links