Enhance Your Application by Applying Transformations
- Skill Level Beginners
- Product JavaFX
- Key Features Node, Rotation, Scaling, Transformation, Shearing, Translations
- Last Updated November 2009
This article discusses the basic transformations available in JavaFX SDK, provides visual patterns, and explains how to use Node instance variables and classes from the javafx.scene.transform package to apply transformations to nodes.
Feature Overview
The starting point for almost all JavaFX applications is defining nodes and placing them on the graphical scene. After this task is accomplished, you can apply transformations to the objects as well as visual effects, clipping, or animation.
A transformation is the shifting of a graphical object so that its coordinates change according to specific rules. The following types of transformations are supported in JavaFX SDK:
- Translation
- Rotation
- Scaling
- Shearing
These transformations can be applied to either a stand-alone node, to the groups of nodes, or to the layout containers. Now consider the following application, which shows what types of transformations can be applied to the ImageView object. Refer to the description at the bottom of the scene while switching between transformations. Select Remove Transformations to restore the initial state of the image.
The following section shows which specific variables and classes you might need to perform the transformations you have just experimented with.
Understanding the API
The JavaFX API offers various classes, instance variables, and functions to transform the object.
Node Instance Variables |
javafx.scene.transform Classes and Functions
|
|---|---|
A quick glance at the Node class reveals that it has all the necessary instance variables to perform simple transformations.
However, you might also notice another instance variable of the Node class - transforms []. This instance variable is a sequence that can encapsulate either one or several objects that define transformations.
transforms: [Rotate(20, 10, 10), Scale(0.5, 2.0)]
Alternatively, you can specify the transformation object in the sequence by using the corresponding functions of the Transform class.
transforms: [Transform.rotate(20, 10, 10), Transform.scale(0.5, 2.0)]
Therefore, you can create multiple transformations and enable as many instance variables as you want.
rotate: 45 scaleX: 1.5 transforms: Rotate(angle: 20, pivotX: 10, pivotY: 10)
Refer to the API Specification for more information about instance variables, classes, and functions you can use to build transformations. The following sections examine particular transformations in detail.
Translation
This transformation shifts the node along either the x or y axis relative to its initial position. The initial position is defined by x and y coordinates of the node. In the example that is used in this article, the ImageView object is drawn at the point (x=100, y=100). The example then translates the node with a shift of 30 along the x axis and 30 along the y axis so that the new location of the object is in the point (x=130, y=130).
Figure 1: Translated Image
This transformation can be implemented by one of the following code fragments applied to the ImageView object.
javafx.scene.Node
|
javafx.scene.transform.Translate
|
javafx.scene.transform.Transform
|
|---|---|---|
ImageView {
image: image
x: 100
y: 100
translateX: 30
translateY: 30
}
|
ImageView {
image: image
x: 100
y: 100
transforms:
Translate{x: 30 y: 30}
}
|
ImageView {
image: image
x: 100
y: 100
transforms:
Transform.translate(30, 30)
}
|
A reasonable question you might ask is why are all these classes, instance variables, and a function needed to simply move the object to another point.
For a simple application you can use x and y variables of the Node to position a shape, a text element, or an image in the specified point of the scene. However, for a complex application that performs animations or combines animation with extensive visual effects, you must distinguish between original coordinates of the object and its translated coordinates. The original coordinates are supposed to be intact, while translating coordinates are supposed to be changed in animation timelines.
Rotation
This type of transformation causes the node to appear rotated around the specified pivot point of the scene. The rotate instance variable of the node is used to rotate the image on the particular angle around its center. In other words, the pivot point coincides with the center of the rectangular bounds of the image, and its coordinates are calculated automatically by the system.
Figure 2: Image Rotated Around Its Center
This is the simplest way to rotate the node. The following code fragment accomplishes this task:
ImageView {
image: image
x: 100
y: 100
rotate: 45
}
You can use the javafx.scene.transform.Rotate class or the rotate function of the Transform class to perform exactly the same rotation. Specify the coordinates of the pivot point to achieve the same effect. See the following code fragments.
javafx.scene.transform.Rotate
|
javafx.scene.transform.Transform
|
|---|---|
ImageView {
image: image
x: 100
y: 100
transforms:
Rotate {
angle: 45
pivotX: 140 pivotY: 135
}
}
|
ImageView {
image: image
x: 100
y: 100
transforms:
Transform.rotate(45, 140, 135)
}
|
The rotate function of the Transform class has the following syntax:
rotate(angle: Number, pivotX: Number, pivotY: Number)
Typically, you will use these coding patterns to rotate the node around the point different from its center. Explore this functionality in action with the Rotate Around the Pivot Point option.
Figure 3: Image Rotated Around Pivot Point
This transformation can be implemented by applying one of the following code fragments.
javafx.scene.transform.Rotate
|
javafx.scene.transform.Transform
|
|---|---|
ImageView {
image: image
x: 100
y: 100
transforms:
Rotate {
angle: 45
pivotX: 180 pivotY: 180
}
}
|
ImageView {
image: image
x: 100
y: 100
transforms:
Transform.rotate(45, 180, 180)
}
|
Note that the pivot point, as well as the angle defines the destination point the image is moved to. Thoroughly calculate values when specifying the pivot point. Otherwise, the image might appear where it is not intended to be.
Figure 4: Image Rotated Around Pivot Point
Scaling
Scaling causes a node to either appear larger or smaller depending on the scaling factor. Scaling alters the node so that its dimension along the axis is multiplied by the scale factor. As with rotation transformations, scaling transformations are applied about a pivot point. This pivot point is considered the point around which scaling occurs. The scaleX and scaleY instance variables of the Node class enable scaling relative to the center of the object. Again, when scaling with the scaleX and scaleY instance variables, the pivot point coincides with the center of the image, and its coordinates are calculated automatically by the system.
Figure 5: Image Scaled Relative to Its Center
The yellow arrows show the directions along which the scaling was performed. The following code fragment implements this transformation.
ImageView {
image: image
x: 100
y: 100
scaleX: 1.5
scaleY: 1.5
}
The scaleX and scaleY instance variables are of the Number type. You can specify both the increasing factor and the reducing factor. The default value for both variables is 1.0—no scaling is applied. The same scaling effect can be achieved by using the Scale class and the scale function of the Transform class, as shown next.
javafx.scene.transform.Scale |
javafx.scene.transform.Transform |
|---|---|
ImageView {
image: image
x: 100
y: 100
transforms: Scale{
x: 1.5 y: 1.5
pivotX: 140 pivotY: 135
}
}
|
ImageView {
image: image
x: 100
y: 100
transforms:
Transform.scale(1.5, 1.5, 140, 135)
}
|
The scale function of the Transform class has the following syntax:
scale(x: Number, y: Number, pivotX: Number, pivotY: Number)
In a real-world application you explicitly define the coordinates of the pivot point when you need to scale the object so that its transformation is directed to the particular point of the scene. The following screen capture shows the image reduced twice. The transformation id directed to the point (x=180, y=180).
Figure 6: The Image Reduced Twice Relative to Pivot Point
The yellow arrows show the direction along which the scaling was performed. You can implement this transformation the following ways.
javafx.scene.transform.Scale |
javafx.scene.transform.Transform |
|---|---|
ImageView {
image: image
x: 100
y: 100
transforms: Scale{
x: 0.5 y: 0.5
pivotX: 180 pivotY: 180
}
}
|
ImageView {
image: image
x: 100
y: 100
transforms:
Transform.scale(0.5, 0.5, 180, 180)
}
|
Shearing
A shearing transformation rotates one axis so that the x and y axes are no longer perpendicular. The coordinates of the node are shifted by the specified multipliers. There is no corresponding Node instance variable such as rotate or scale. You need to use either the javafx.scene.transform.Shear class or the shear function of the javafx.transform.Transform class. Consider the following code fragment.
ImageView {
image: image
x: 100
y: 100
transforms: Transform.shear(0.5, 0)
}
This fragment defines the x multiplier as 0.5, and the y multiplier as 0.0. Examine the following figure to learn how these multiplying factors are applied.
Figure 7: Image With Applied Shearing Transformation
The yellow arrow shows the direction along which the image was shifted. A new x coordinate for the object is calculated as follows:
x = 100 + 0.5*100 = 150
The y coordinate remains the same, because the y variable is 0. To calculate the horizontal offset that defines the image skew, the JavaFX Runtime multiplies the image height by the x factor.
offset = 0.5*72 = 36
Both x and y factors are of the Number type. No shearing is applied by default.
Multiple Transformations
As you have already learned from the previous sections, the transforms instance variable is a sequence. You can use it to construct multiple transformations by specifying an ordered chain of transforms. For example, you can rotate the object, scale it, and then apply a shearing transformation to it.
ImageView {
image: image
x: 100 y: 100
transforms: [
Transform.rotate(190, 180, 180),
Transform.scale(0.5, 0.5, 100, 100),
Transform.shear(0.5, 0)]
]
}
The transformations are applied to the node one by one, in the order that they appear in the transforms sequence.
|
|
First step: the image is rotated 190 degrees around the pivot point with coordinates (180, 180). |
|
|
Second step: the rotated image is reduced twice relative to the pivot point (100, 100). |
|
|
The final step. The rotated and scaled image is skewed by applying shearing transformation. |
When considering multiple transformations with mixed use of Node instance variables, note the order in which JavaFX Runtime applies transformations to the node:
- Sets the coordinates of geometric shapes, if any
- Applies transformations defined in the
transformsinstance variable - Performs scaling defined in the
scaleXandscaleYinstance variables - Rotates the node by using the
rotateinstance variable - Moves the node to the point defined by the
translateXandtranslateYinstance variables
For example, suppose that you set the translateX and translateY instance variables for the multiple transformation sample discussed in this section .The translation will be enabled last, after all the transformations declared in the transforms sequence are applied. You can change the translation priority relative to rotation or scaling by using the translate function of the Transform class instead of the Node instance variables. Experiment with the different approaches and identify the one most appropriate for the application you are developing.
In JavaFX applications transformations are often used in combination with animation. The typical use case is altering the angle of the node that is rotated within a timeline, or changing the translating coordinates of the object to create movements. Refer to Creating Animated Objects for more information.
Try It. Apply multiple transformations to the image by constructing the sequence of transformations, then create a timeline to alter one of the transformation variables.
Related Links
- API: JavaFX 1.2 API
- Tutorial: Quick JavaFX GUI Overview
- Tutorial: Presenting UI Objects in a Graphical Scene
- Tutorial: Creating Animated Objects
- Technical article: Animation Basics for JavaFX Beginners
We welcome your participation in our community. Please keep your comments civil and on point. You may optionally provide your email address to be notified of repliesyour information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.
Alla Redko
Technical Writer, Sun Microsystems