Skip to content

Commit b8975a1

Browse files
committed
Improve tutorial and fix review comments.
1 parent c6cd777 commit b8975a1

File tree

3 files changed

+100
-53
lines changed

3 files changed

+100
-53
lines changed
Loading
Loading

app/pages/learn/01_tutorial/07_rich_client_apps/02_introduction-javafx-animation.md

Lines changed: 100 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,24 @@ layout: learn/tutorial.html
1010
subheader_select: tutorials
1111
main_css_id: learn
1212
description: "Learn to create advanced JavaFX animations"
13-
last_update: 2024-05-17
13+
last_update: 2024-05-22
1414
---
1515

1616
The [javafx.animation](javafxdoc:AnimationPackageSummary) package offers a simple framework for creating animations and transitions in a JavaFX application.
17-
It operates on the principle of [WritableValue\<T\>](javafxdoc:WritableValue) which are used across JavaFX.
17+
It operates on the principle of [`WritableValue\<T\>`](javafxdoc:WritableValue), which is used across JavaFX. `WritableValue<T>` is an interface that wraps a value that can be read and set.
18+
It is commonly used for storing properties in JavaFX UI elements, like `width` or `height` in the [`Rectangle`](javafxdoc:Rectangle) shape.
1819
It additionally provides a variety of built-in transitions for common effects, support for parallel and sequential transitions, and the ability to handle events upon animation completion.
19-
I will go through all types of animations, starting with `Animation` and its subclasses `Transition` and `Timeline`, before representing a lower level animation with `AnimationTimer`.
20+
The article goes through all types of animations, starting with `Animation` and its subclasses `Transition` and `Timeline`, before representing a lower level animation with `AnimationTimer`.
2021
While `Transition` provides a simpler and more user-friendly way to create animations, `Timeline` offers greater flexibility and is suitable for more complex animations.
2122
In contrast, `AnimationTimer` is designed for frame-by-frame updates and does not make use of `WritableValue<T>`.
2223

23-
## WritableValue
24-
`WritableValue<T>` is an interface that wraps a value that can be read and set. It is commonly used for storing properties in JavaFX UI elements, like
25-
`width` or `height` in the [Rectangle](javafxdoc:Rectangle) shape.
26-
2724
## Animation
2825

29-
The [Animation](javafxdoc:Animation) abstract class provides the core functionality for `Transition` and `Timeline` animations.
26+
The abstract class [`Animation`](javafxdoc:Animation) provides the core functionality for `Transition` and `Timeline` animations and can't be implemented directly.
3027

3128
An `Animation` consists of multiple properties:
3229
- The `targetFramerate` is the maximum framerate (frames per second) at which this `Animation` will run.
33-
- The `currentTime` is the current point in time in the `Animation` as a [Duration](javafx:Duration).
30+
- The `currentTime` is the current point in time in the `Animation` as a [`Duration`](javafx:Duration).
3431
- The `rate` defines the direction and speed at which the `Animation` is expected to be played. It supports both positive and negative numbers.
3532
- The `cycleCount` defines the number of cycles of this `Animation`. It can't be changed while running and must be positive.
3633
- The `cycleDuration` is the `Duration` of one cycle of this `Animation`. It is the time it takes to play from start to end of the `Animation` **at the default rate of 1.0**.
@@ -41,14 +38,14 @@ An `Animation` consists of multiple properties:
4138
- The `status` represents the current state of the `Animation`, possible states are `PAUSED`, `RUNNING` and `STOPPED`.
4239

4340
Additionally, it provides several useful methods, like `play()`, `playFrom(String cuePoint)`, `pause()`, `stop()` and more to control the animations flow.
44-
A quick look into the JavaDocs provides a great overview of its functionalities.
41+
A quick look into [its documentation](javafxdoc:Animation) provides a great overview of its functionalities.
4542

4643
## Transition
47-
The [Transition](javafxdoc:Transition) abstract class serves as the foundational class for all transitions, presenting a common form of `Animation`.
48-
JavaFX provides a variety of built-in transitions for common [Node](javafxdoc:Node) and [Shape](javafxdoc:Shape) properties.
44+
The [`Transition`](javafxdoc:Transition) abstract class serves as the foundational class for all transitions, presenting a common form of `Animation`.
45+
JavaFX provides a variety of built-in transitions for common [`Node`](javafxdoc:Node) and [`Shape`](javafxdoc:Shape) properties.
4946

5047
### Fade Transition
51-
The [FadeTransition](javafxdoc:FadeTransition) creates a fade effect.
48+
The [`FadeTransition`](javafxdoc:FadeTransition) creates a fade effect.
5249
This is done by updating the `opacity` property of the `Node` at regular intervals.
5350

5451
![FadeTransition](/assets/images/javafx/animation/transition/fade-example.gif)
@@ -62,9 +59,10 @@ transition.setInterpolator(Interpolator.LINEAR);
6259

6360
transition.play();
6461
```
62+
(For a complete guide on setting up a JavaFX application, refer to this article: [JavaFX Application Basic Structure By Example](https://dev.java/learn/javafx/structure/))
6563

6664
### Fill Transition
67-
The [FillTransition](javafxdoc:FillTransition) creates an animation, that changes the filling of a shape.
65+
The [`FillTransition`](javafxdoc:FillTransition) creates an animation, that changes the filling of a shape.
6866
This is done by updating the `fill` property of the `Shape` at regular intervals.
6967

7068
![FillTransition](/assets/images/javafx/animation/transition/fill-example.gif)
@@ -80,8 +78,8 @@ transition.play();
8078
```
8179

8280
### Translate Transition
83-
The [TranslateTransition](javafxdoc:TranslateTransition) creates a move/translate animation from one position to another in a straight line.
84-
This is done by updating the `translateX`, `translateY` and `translateZ` properties of the `Node` at regular interval.
81+
The [`TranslateTransition`](javafxdoc:TranslateTransition) creates a move/translate animation from one position to another in a straight line.
82+
This is done by updating the `translateX`, `translateY` and `translateZ` properties of the `Node` at regular intervals.
8583

8684
![TranslateTransition](/assets/images/javafx/animation/transition/translate-example.gif)
8785
```java
@@ -96,8 +94,8 @@ transition.play();
9694
```
9795

9896
### Path Transition
99-
The [PathTransition](javafxdoc:PathTransition) creates a move animation using a complex predefined path specified by a sequence of shapes.
100-
The translation along the path is done by updating the `translateX` and `translateY` properties of the `Node`, and the `rotate` variable will get updated if `orientation` is set to `OrientationType.ORTHOGONAL_TO_TANGENT`, at regular interval.
97+
The [`PathTransition`](javafxdoc:PathTransition) creates a move animation using a complex predefined path specified by a sequence of shapes.
98+
The translation along the path is done by updating the `translateX` and `translateY` properties of the `Node`, and the `rotate` variable will get updated if `orientation` is set to `OrientationType.ORTHOGONAL_TO_TANGENT`, at regular intervals.
10199

102100
![PathTransition](/assets/images/javafx/animation/transition/path-example.gif)
103101
```java
@@ -114,8 +112,8 @@ transition.play();
114112
```
115113

116114
### Rotate Transition
117-
The [RotateTransition](javafxdoc:RotateTransition) creates a rotation animation.
118-
This is done by updating the `rotate` property of the `Node` at regular interval.
115+
The [`RotateTransition`](javafxdoc:RotateTransition) creates a rotation animation.
116+
This is done by updating the `rotate` property of the `Node` at regular intervals.
119117
The angle value is specified in degrees.
120118

121119
![RotateTransition](/assets/images/javafx/animation/transition/rotate-example.gif)
@@ -132,8 +130,8 @@ transition.play();
132130
```
133131

134132
### Scale Transition
135-
The [ScaleTransition](javafxdoc:ScaleTransition) creates a scale animation, that changes the size of a node.
136-
This is done by updating the `scaleX`, `scaleY` and `scaleZ` properties of the `Node` at regular interval.
133+
The [`ScaleTransition`](javafxdoc:ScaleTransition) creates a scale animation, that changes the size of a node.
134+
This is done by updating the `scaleX`, `scaleY` and `scaleZ` properties of the `Node` at regular intervals.
137135

138136
![ScaleTransition](/assets/images/javafx/animation/transition/scale-example.gif)
139137
```java
@@ -148,7 +146,7 @@ transition.play();
148146
```
149147

150148
### Stroke Transition
151-
The [StrokeTransition](javafxdoc:StrokeTransition) creates an animation, that changes the stroke color of a shape.
149+
The [`StrokeTransition`](javafxdoc:StrokeTransition) creates an animation, that changes the stroke color of a shape.
152150
This is done by updating the `stroke` property of the `Shape` at regular intervals.
153151

154152
![StrokeTransition](/assets/images/javafx/animation/transition/stroke-example.gif)
@@ -164,11 +162,42 @@ transition.setInterpolator(Interpolator.LINEAR);
164162
transition.play();
165163
```
166164

165+
### Sequential Transition
166+
The [`SequentialTransition`](javafxdoc:SequentialTransition) plays a series of animations in sequential order.
167+
It is not recommended to contain an `Animation` that is not the last one with `Duration.INDEFINITE` as this will block all later animations in the sequence.
168+
167169
### Pause Transition
168-
The [PauseTransition](javafxdoc:PauseTransition) executes an `Animation.onFinished` at the end of its execution.
170+
The [`PauseTransition`](javafxdoc:PauseTransition) creates a pause for a specified `duration`.
171+
This behavior is useful to create a delay in a `SequentialTransition` in which no properties change.
172+
173+
![PauseTransition](/assets/images/javafx/animation/transition/pause-example.gif)
174+
```java
175+
Circle circle = new Circle(150, 150, 20, Color.GREEN);
176+
circle.setStrokeWidth(5);
177+
178+
ScaleTransition smaller = new ScaleTransition(Duration.seconds(1.5));
179+
smaller.setToX(0.25);
180+
smaller.setToY(0.25);
181+
smaller.setInterpolator(Interpolator.LINEAR);
182+
183+
ScaleTransition larger = new ScaleTransition(Duration.seconds(1.5));
184+
larger.setToX(1);
185+
larger.setToY(1);
186+
larger.setInterpolator(Interpolator.LINEAR);
187+
188+
SequentialTransition transition = new SequentialTransition(
189+
circle,
190+
smaller,
191+
new PauseTransition(Duration.seconds(2)),
192+
larger
193+
);
194+
transition.play();
195+
```
196+
Note that this code doesn't set the target `Node` in the transitions itself, but instead in the `SequentialTransition` which is the parent transition here.
197+
It is going to automatically use the target `Node` for child transitions that have no `Node` specified themselves.
169198

170199
### Parallel Transition
171-
The [ParallelTransition](javafxdoc:ParallelTransition) plays a list of animations in parallel.
200+
The [`ParallelTransition`](javafxdoc:ParallelTransition) plays a group of animations in parallel.
172201

173202
![ParallelTransition](/assets/images/javafx/animation/transition/parallel-example.gif)
174203
```java
@@ -188,26 +217,22 @@ rotate.setInterpolator(Interpolator.LINEAR);
188217
ParallelTransition transition = new ParallelTransition(rectangle, translate, rotate);
189218
transition.play();
190219
```
191-
### Sequential Transition
192-
The [SequentialTransition](javafxdoc:SequentialTransition) plays a list of animations in sequential order.
193-
It is not recommended to contain an `Animation`, which is not the last one, with `Duration.INDEFINITE` as this will block all later animations in the sequence.
194220

195221
## Timeline
196-
A [Timeline](javafxdoc:Timeline) is used to define a free form `Animation` on any `WritableValue<T>`. It is helpful if none of the built-in transitions operate on the required properties.
197-
198-
It consists of a sequential series of `KeyFrame`s.
199-
Each `KeyFrame` encapsulates a moment in time (**Cue Point**), and collectively specify how target properties evolve over the entire duration.
222+
A [`Timeline`](javafxdoc:Timeline) is used to define a free form `Animation` on any `WritableValue<T>`. It is helpful if none of the built-in transitions operate on the required properties.
223+
It consists of a sequential series of `KeyFrame`s, each of which encapsulates a moment in time. Collectively they specify how target properties evolve over the entire duration.
200224

201-
> **Warning:** A running Timeline is being referenced from the FX runtime. Infinite Timeline might result in a memory leak if not stopped properly. All the objects with animated properties would not be garbage collected.
225+
> **Warning:** A running `Timeline` is being referenced from the FX runtime. In an infinite timeline,
226+
> the objects with animated properties would not be garbage collected, which might result in a memory leak.
227+
> Therefore, ensure you stop the timeline instance when it is no longer needed.
202228
203229
### KeyFrame
204-
A [KeyFrame](javafxdoc:KeyFrame) represents a specific moment in an animation sequence (**Cue Point**) and comprises a collection of `KeyValue` instances that change from start to the given `Duration`.
205-
230+
A [`KeyFrame`](javafxdoc:KeyFrame) represents a specific moment in an animation sequence (**Cue Point**) and comprises a collection of `KeyValue` instances that change over the given `Duration`.
206231
A KeyFrame can have a name which then can be used to identify this `KeyFrame` in an animation, for example for starting from this specific `KeyFrame` using `playFrom(String cuePoint)`.
207232
It is also possible to provide an `onFinished` implementation, which will be invoked when hitting this cue point.
208233

209234
### KeyValue
210-
A [KeyValue](javafxdoc:KeyValue) establishes a mapping between a `WritableValue<T>` and a target value of type `T`. This is used to define the change of a value.
235+
A [`KeyValue`](javafxdoc:KeyValue) establishes a mapping between a `WritableValue<T>` and a target value of type `T`. This is used to define the change of a value.
211236
An `Interpolator` can be additionally defined to set the rate of change for this value. The `KeyValue` class is immutable.
212237

213238
### Example
@@ -225,41 +250,63 @@ timeline.play();
225250
```
226251

227252
## Interpolator
228-
The [Interpolator](javafxdoc:Interpolator) abstract class defines the rate of change at which values change over time, influencing the smoothness of animations.
253+
The [`Interpolator`](javafxdoc:Interpolator) abstract class defines the rate of change at which values change over time, influencing the smoothness of animations.
254+
There are several built-in implementations for common interpolation techniques.
229255

230-
It provides several built-in implementations:
231-
- [Interpolator.DISCRETE](javafxdoc:Interpolator.DISCRETE): The `DISCRETE` interpolator creates a **sudden** transition between values without any intermediate steps.
232-
- [Interpolator.LINEAR](javafxdoc:Interpolator.LINEAR): The `LINEAR` interpolator produces a **constant** rate of change between values over time.
233-
- [Interpolator.EASE_IN](javafxdoc:Interpolator.EASE_IN): The `EASE_IN` interpolator starts the animation slowly and accelerates as it progresses.
234-
- [Interpolator.EASE_OUT](javafxdoc:Interpolator.EASE_OUT): The `EASE_OUT` interpolator starts quickly and slows down as it progresses.
235-
- [Interpolator.EASE_BOTH](javafxdoc:Interpolator.EASE_BOTH): The `EASE_BOTH` interpolator starts slowly, accelerates in the middle and slows down towards the end. It combines the characteristics of `EASE_IN` and `EASE_OUT`.
256+
**Note:** By default, all transitions, excluding `ParallelTransition` and `SequentialTransition`, utilize the `Interpolator#EASE_BOTH`.
236257

237-
Additionally, there are two static factory methods for [SPLINE](javafxdoc:Interpolator.SPLINE) and [TANGENT](javafxdoc:Interpolator.TANGENT) interpolation.
258+
Here is a visualization of the `Interpolator` using the example from [`Timeline`](#example):
238259

239-
[//]: # (ToDo: sync gifs)
240-
Here is a visualization of the Interpolator using the example from [Timeline](#example):
241260
### Discrete
261+
The [`Interpolator.DISCRETE`](javafxdoc:Interpolator.DISCRETE) interpolator creates a **sudden** transition between values without any intermediate steps.
262+
242263
![Discrete](/assets/images/javafx/animation/interpolator/discrete-example.gif)
264+
265+
```java
266+
Circle circle = new Circle(50, 150, 10, Color.GREEN);
267+
268+
KeyValue x = new KeyValue(circle.translateXProperty(), 200, Interpolator.DISCRETE);
269+
KeyFrame frame = new KeyFrame(Duration.seconds(5), x);
270+
Timeline timeline = new Timeline(frame);
271+
272+
timeline.play();
273+
```
243274
### Linear
275+
The [`Interpolator.LINEAR`](javafxdoc:Interpolator.LINEAR) interpolator produces a **constant** rate of change between values over time.
276+
244277
![Linear](/assets/images/javafx/animation/interpolator/linear-example.gif)
278+
245279
### Ease In
280+
The [`Interpolator.EASE_IN`](javafxdoc:Interpolator.EASE_IN) interpolator starts the animation slowly and accelerates as it progresses.
281+
246282
![EaseIn](/assets/images/javafx/animation/interpolator/ease-in-example.gif)
283+
247284
### Ease Out
285+
The [`Interpolator.EASE_OUT`](javafxdoc:Interpolator.EASE_OUT) interpolator starts quickly and slows down as it progresses.
286+
248287
![EaseOut](/assets/images/javafx/animation/interpolator/ease-out-example.gif)
288+
249289
### Ease Both
290+
The [`Interpolator.EASE_BOTH`](javafxdoc:Interpolator.EASE_BOTH) interpolator starts slowly, accelerates in the middle and slows down towards the end.
291+
It combines the characteristics of `EASE_IN` and `EASE_OUT`.
292+
250293
![EaseBoth](/assets/images/javafx/animation/interpolator/ease-both-example.gif)
251294

252-
## AnimationTimer
295+
Additionally, there are two static factory methods for [`Interpolator.SPLINE`](javafxdoc:Interpolator.SPLINE) and [`Interpolator.TANGENT`](javafxdoc:Interpolator.TANGENT) interpolation.
296+
297+
## Animation Timer
253298

254-
The [AnimationTimer](javafxdoc:AnimationTimer) abstract class provides the lowest level option to create an animation.
299+
The [`AnimationTimer`](javafxdoc:AnimationTimer) abstract class provides the lowest level option to create an animation.
255300
The `handle(long now)` method gets called in each frame while it is active. The timestamp `now` is the time of the current frame in nanoseconds and will be the same for all `AnimationTimer`s called during that frame.
256301
Additionally, the `AnimationTimer` adds `start()` and `stop()` methods to handle the lifetime of the animation.
257302

258-
**Note:** The `handle` method will be called in the **JavaFX Application Thread** and thus shouldn't do heavy computations.
303+
**Note:** The `handle` method will be called in the **JavaFX Application Thread**, so it should avoid long-running and blocking operations.
304+
To maintain a smooth frame rate of 30 frames per second, the whole JavaFX application ideally allocates no more than 33 milliseconds per frame.
259305

260306

261307
## Conclusion
262-
The `javafx.animation` package offers a simple framework for creating dynamic animations within JavaFX applications.
263-
From the foundational `AnimationTimer` and `Animation` classes to the more specialized `Transition` and `Timeline` classes,
264-
each component provides unique capabilities for creating animations. Additionally, you are provided with various
265-
common `Interpolator` implementations.
308+
In this tutorial, you've explored the `javafx.animation` package and learned how to create dynamic animations within JavaFX applications.
309+
We started by understanding the base `Animation` class, and then moved on to `Transition` and `Timeline` classes, which provide different ways
310+
to create and control animations. Additionally, you have learnt how to control the progression of an animation via several `Interpolator` examples.
311+
Finally, we covered the `AnimationTimer` class, which allows for animations with precise frame-by-frame updates. With these tools, you are now
312+
equipped to create rich animations in your JavaFX applications.

0 commit comments

Comments
 (0)