Open delabassee opened 1 year ago
Hi,
I recently wrote some introduction to javafx.animation
, which summarizes the whole package with a few examples.
It probably needs some refining and going deeper into the topic but already covers a lot about Animation
, Timeline
, Transitions
etc. I would really like to share it here and think this fits into this request.
Cool! Care to share and allow us to review the content to see if it'll work?
Should I share it here before starting to make a PR? Otherwise, I would follow README.md
here works! Or you can send to java_devrel_grp@oracle.com
Ok so I am still unsure about the structure, but I want to at least mention every concept because this package is not that big.
It currently includes some GIFs and screenshots because it was initially intended to share on discord, this would need some updates. The transition description might need some updates as well, because they are currently just copied from the Javadoc description.
The javafx.animation
package in JavaFX offers a simple framework for creating animations and transitions in a JavaFX application. It operates on the principle of WritableValue\<T> which are used across JavaFX. 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.
The Animation
abstract class provides the core functionality of all animations. An Animation
can be in 3 states: [PAUSED, RUNNING, STOPPED]. It provides multiple play()
/playFrom()
, a stop()
and a pause()
method to control its flow. You can additionally set the cycle count which say how often the animation repeats, auto reverse to make an animation run back and forth while looping, and so on. A quick look into the Javadocs provide a great overview of its functionalities.
A KeyValue
establishes a mapping between a WritableValue<T>
to a target value of type T
. This is used to define the change of a value. Interpolator
can be additionally defined to change the behavior over time.
A KeyFrame
represents a specific moment in an animation sequence (Cue Point) and comprises a collection of KeyValue
instances that change over the given Duration. The KeyFrame ensures a smooth transition using the internal interpolator of these KeyValue
instances, mapping the property values over the specified duration to reach their target values upon completion. A KeyFrame can have a name which then can be used to identify this KeyFrame
in an animation, or even start from this specific KeyFrame
.
A Timeline
defines an Animation
as a sequential series of KeyFrame
instances. Each KeyFrame
encapsulates a moment in time (Cue Point), and collectively specify how target properties evolve over the entire duration.
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.
This one basically moves the Circle 200px in x direction over the duration of 5 seconds:
Circle object = new Circle(50, 150, 10, Color.GREEN);
KeyValue x = new KeyValue(object.translateXProperty(), 200);
KeyFrame frame = new KeyFrame(Duration.seconds(5), x);
Timeline timeline = new Timeline(frame);
timeline.play();
The Transition
abstract class serves as the foundational class for all transitions, presenting an alternative form of the Animation
. JavaFX provides a variety of built-in transitions:
duration
. This is done by updating the opacity
variable of the node
at regular interval.duration
. This is done by updating the fill
variable of the shape at regular intervals.duration
. The translation along the path is done by updating the translateX
and translateY
variables of the node
, and the rotate
variable will get updated if orientation
is set to OrientationType.ORTHOGONAL_TO_TANGENT
, at regular interval.Animation.onFinished
at the end of its duration
.duration
. This is done by updating the rotate
variable of the node
at regular interval. The angle value is specified in degrees.duration
. This is done by updating the scaleX
, scaleY
and scaleZ
variables of the node
at regular interval.duration
. This is done by updating the stroke
variable of the shape
at regular intervals.duration
. This is done by updating the translateX
, translateY
and translateZ
variables of the node
at regular interval.The Interpolator
abstract class defines the rate of change of animated values over time, influencing the smoothness of animations. It provides various built-in implementations:
Here is a visualization of the Interpolator using the example from Timeline:
Additionally, there are two static factory methods for SPLINE and TANGENT interpolation.
The javafx.animation
package provides a simple framework for creating and managing animations in a JavaFX application. It includes classes like Animation
, KeyValue
, KeyFrame
, Timeline
, Transition
and Interpolator
that offer a wide range of features for controlling animation flow. Furthermore, it provides built-in transitions for common effects and allows handling events upon animation completion.
Hey @SquidXTV, thank you for the proposal! I really like the clear and well-structured approach to the topic. I didn't know anything about it before and now feel like I have a basic understanding; definitely enough to start creating some animations. 😃
Interpolater
in the KeyValue
section (or a note that more detail is explained below) or in what sense a Transition
is "an alternative form of the Animation
".Hey @SquidXTV, thank you for the proposal! I really like the clear and well-structured approach to the topic. I didn't know anything about it before and now feel like I have a basic understanding; definitely enough to start creating some animations. 😃
- Most paragraphs could do with a bit more details, e.g. on
Interpolater
in theKeyValue
section (or a note that more detail is explained below) or in what sense aTransition
is "an alternative form of theAnimation
".- It's a matter of personal preference but maybe show the first example code and GIF (the wandering circle) before starting to explain the concepts? Along the lines of "look how cool this is, let's figure out how it works".
- Definitely keep the GIFs, they're great! In fact, maybe add more, e.g. for color or size changes? 😁
- Instead of just listing what was explained, the conclusion should summarize it.
Thanks a lot for the feedback, I can just agree. :D
I would structure the explanation for each built-in Interpolator
like I did with the built-in Transition
.
I am not sure about the extra GIFs, I definitely would like to add more, but if I create an example for just FillTransition
, then I am kinda missing an example GIF for every other Transition
, which would kinda make it incomplete. It is not much work to create an GIF example for all built-in Transition
and it would add a better overview to what they do. It is also easier for the reader as they do not need to read the explanation for each Transition
to have a quick understanding. Would it be too much though?
I am also unsure about the Java Docs screenshots. I included them because the initial idea was to post it on discord. Should I do that differently for the website? If so, how would I do it?
My progress for today. Still missing some stuff.
I now included most of the built-in transition examples. It kinda feels too much though, I might drop some of them in the future. What do you think about it?
The javafx.animation
package in JavaFX offers a simple framework for creating animations and transitions in a JavaFX application. It operates on the principle of WritableValue\<T> which are used across JavaFX. 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.
The Animation
abstract class provides the core functionality of all animations. An Animation
can be in 3 states: [PAUSED, RUNNING, STOPPED]. It provides multiple play()
/playFrom()
, a stop()
and a pause()
method to control its flow. You can additionally set the cycle count which say how often the animation repeats, auto reverse to make an animation run back and forth while looping, and so on. A quick look into the Javadocs provide a great overview of its functionalities.
A KeyValue
establishes a mapping between a WritableValue<T>
to a target value of type T
. This is used to define the change of a value. Interpolator
can be additionally defined to change the behavior over time.
A KeyFrame
represents a specific moment in an animation sequence (Cue Point) and comprises a collection of KeyValue
instances that change over the given Duration. The KeyFrame ensures a smooth transition using the internal interpolator of these KeyValue
instances, mapping the property values over the specified duration to reach their target values upon completion. A KeyFrame can have a name which then can be used to identify this KeyFrame
in an animation, or even start from this specific KeyFrame
.
A Timeline
defines an Animation
as a sequential series of KeyFrame
instances. Each KeyFrame
encapsulates a moment in time (Cue Point), and collectively specify how target properties evolve over the entire duration.
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.
This one basically moves the Circle 200px in x direction over the duration of 5 seconds:
Circle object = new Circle(50, 150, 10, Color.GREEN);
KeyValue x = new KeyValue(object.translateXProperty(), 200);
KeyFrame frame = new KeyFrame(Duration.seconds(5), x);
Timeline timeline = new Timeline(frame);
timeline.play();
The Transition
abstract class serves as the foundational class for all transitions, presenting an alternative form of the Animation
. JavaFX provides a variety of built-in transitions:
duration
. This is done by updating the opacity
variable of the node
at regular interval.duration
. This is done by updating the fill
variable of the shape at regular intervals.duration
. The translation along the path is done by updating the translateX
and translateY
variables of the node
, and the rotate
variable will get updated if orientation
is set to OrientationType.ORTHOGONAL_TO_TANGENT
, at regular interval.Animation.onFinished
at the end of its duration
.duration
. This is done by updating the rotate
variable of the node
at regular interval. The angle value is specified in degrees.duration
. This is done by updating the scaleX
, scaleY
and scaleZ
variables of the node
at regular interval.duration
. This is done by updating the stroke
variable of the shape
at regular intervals.duration
. This is done by updating the translateX
, translateY
and translateZ
variables of the node
at regular interval.Note: By default, all transitions, excluding ParallelTransition
and SequentialTransition
, utilize the Interpolator#EASE_BOTH
.
Here is a visualization of most built-in transitions:
FadeTransition transition = new FadeTransition(Duration.seconds(5), object);
transition.setFromValue(1.0);
transition.setToValue(0);
transition.setInterpolator(Interpolator.LINEAR);
FillTransition transition = new FillTransition(Duration.seconds(5), object);
transition.setFromValue(Color.GREEN);
transition.setToValue(Color.BLACK);
transition.setInterpolator(Interpolator.LINEAR);
Path path = new Path();
path.getElements().add(new MoveTo(50, 50)); // starting point
path.getElements().add(new LineTo(250, 250));
PathTransition transition = new PathTransition(Duration.seconds(5), path, object);
transition.setInterpolator(Interpolator.LINEAR);
RotateTransition transition = new RotateTransition(Duration.seconds(5), object);
transition.setFromAngle(0);
transition.setToAngle(360);
transition.setInterpolator(Interpolator.LINEAR);
ScaleTransition transition = new ScaleTransition(Duration.seconds(5), object);
transition.setToX(0.1);
transition.setToY(0.1);
transition.setInterpolator(Interpolator.LINEAR);
StrokeTransition transition = new StrokeTransition(Duration.seconds(5), object);
transition.setFromValue(Color.GREEN);
transition.setToValue(Color.BLACK);
transition.setInterpolator(Interpolator.LINEAR);
TranslateTransition transition = new TranslateTransition(Duration.seconds(5), object);
transition.setToX(200);
transition.setToY(200);
transition.setInterpolator(Interpolator.LINEAR);
The Interpolator
abstract class defines the rate of change of animated values over time, influencing the smoothness of animations. It provides various built-in implementations:
DISCRETE
interpolator creates a sudden transition between values without any intermediate steps.LINEAR
interpolator produces a constant rate of change between values over time.EASE_IN
interpolator starts the animation slowly and accelerates as it progresses.EASE_OUT
interpolator starts quickly and slows down as it progresses.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
.Here is a visualization of the Interpolator using the example from Timeline:
Additionally, there are two static factory methods for SPLINE and TANGENT interpolation.
The javafx.animation
package provides a simple framework for creating and managing animations in a JavaFX application. It includes classes like Animation
, KeyValue
, KeyFrame
, Timeline
, Transition
and Interpolator
that offer a wide range of features for controlling animation flow. Furthermore, it provides built-in transitions for common effects and allows handling events upon animation completion.
Hey @SquidXTV, sorry that I didn't get back to you sooner. I like the addition of code and animations for the transitions. My other points above still apply, though, right? And I came up with two more changes that I think would make this even better:
I am also unsure about the Java Docs screenshots
Yeah, those work better in Discord than on dev.java. 😉 I think the sections containing them could do with a bit more explanation and maybe an example or two, anyway. There's no need to list, e.g., all constructors of a class but seeing how one or two of them work can be helpful.
Hey @SquidXTV, sorry that I didn't get back to you sooner. I like the addition of code and animations for the transitions. My other points above still apply, though, right? And I came up with two more changes that I think would make this even better:
- Explain towards the end of the introduction that you will go over the API type by type. (It's always nice for the user to know what's happening.)
- Don't link the headers. We don't do that elsewhere on dev.java and it will be missed because it's unexpected (or stand out if noticed). Instead, link the first mention of the word in the text.
I am also unsure about the Java Docs screenshots
Yeah, those work better in Discord than on dev.java. 😉 I think the sections containing them could do with a bit more explanation and maybe an example or two, anyway. There's no need to list, e.g., all constructors of a class but seeing how one or two of them work can be helpful.
All good, didn't have the time myself. Going to improve it over the next days.
Ok I have done some bigger revamp of the structure and changes to the text in general, I am quite happy with the current result, though I might be bad at writing conclusions, haha.
The javafx.animation package in JavaFX offers a simple framework for creating animations and transitions in a JavaFX application. It operates on the principle of WritableValue\<T> which are used across JavaFX. 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. I will go through all types of animations, including AnimationTimer
, Animation
, Transition
and Timeline
.
The AnimationTimer abstract class provides the lowest level option to create an animation. The handle(long now)
method gets called in each frame while it is active. The timestamp long now
is the nanoseconds time of the current frame and will be the same for all AnimationTimer
called during that frame. Additionally, the AnimationTimer
adds the start()
and stop()
to handle the lifetime of the animation.
Note that the handle implementation will be called on the JavaFX Application Thread and thus shouldn't do heavy computations.
The Animation abstract class provides the core functionality of all other animations. An Animation
consists of multiple properties:
targetFramerate
is the maximum framerate (frames per second) at which this Animation
will run.currentTime
is the current Duration
point of the Animation
.rate
defines the direction and speed at which the Animation
is expected to be played. It supports both positive and negative numbers.cycleCount
defines the number of cycles of this Animation
. It can't be changed while running and must be positive.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.totalDuration
indicates the total duration of this Animation
, including repeats. It is the result of cycleDuration * cycleCount
or possibly Duration.INDEFINITE
.delay
is the Duration
that delays the Animation
when starting.autoReverse
property defines if the Animation
will reverse direction on alternating cycles.onFinished
event handler is used to define additional behavior when the Animation
finished.status
represents the current state of the Animation
, possible states are PAUSED, RUNNING and STOPPED.Additionally, it provides multiple play()
/playFrom(String cuePoint)
, a stop()
and a pause()
method to control its flow.
A quick look into the Javadocs provides a great overview of its functionalities.
The Transition abstract class serves as the foundational class for all transitions, presenting a common form of Animation
.
JavaFX provides a variety of built-in transitions:
duration
. This is done by updating the opacity
property of the Node
at regular intervals.duration
. This is done by updating the fill
property of the Shape
at regular intervals.duration
. 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.Animation.onFinished
at the end of its duration
.duration
. This is done by updating the rotate
property of the Node
at regular interval. The angle value is specified in degrees.duration
. This is done by updating the scaleX
, scaleY
and scaleZ
properties of the Node
at regular interval.Animation
, which is not the last one, with Duration.INDEFINITE
as this will block all later animations in the sequence. duration
. This is done by updating the stroke
property of the Shape
at regular intervals.duration
. This is done by updating the translateX
, translateY
and translateZ
properties of the Node
at regular interval.Note: By default, all transitions, excluding ParallelTransition
and SequentialTransition
, utilize the Interpolator#EASE_BOTH
.
Here is a visualization of most built-in transitions:
FadeTransition transition = new FadeTransition(Duration.seconds(5), object);
transition.setFromValue(1.0);
transition.setToValue(0);
transition.setInterpolator(Interpolator.LINEAR);
FillTransition transition = new FillTransition(Duration.seconds(5), object);
transition.setFromValue(Color.GREEN);
transition.setToValue(Color.BLACK);
transition.setInterpolator(Interpolator.LINEAR);
Path path = new Path();
path.getElements().add(new MoveTo(50, 50)); // starting point
path.getElements().add(new LineTo(250, 250));
PathTransition transition = new PathTransition(Duration.seconds(5), path, object);
transition.setInterpolator(Interpolator.LINEAR);
RotateTransition transition = new RotateTransition(Duration.seconds(5), object);
transition.setFromAngle(0);
transition.setToAngle(360);
transition.setInterpolator(Interpolator.LINEAR);
ScaleTransition transition = new ScaleTransition(Duration.seconds(5), object);
transition.setToX(0.1);
transition.setToY(0.1);
transition.setInterpolator(Interpolator.LINEAR);
StrokeTransition transition = new StrokeTransition(Duration.seconds(5), object);
transition.setFromValue(Color.GREEN);
transition.setToValue(Color.BLACK);
transition.setInterpolator(Interpolator.LINEAR);
TranslateTransition transition = new TranslateTransition(Duration.seconds(5), object);
transition.setToX(200);
transition.setToY(200);
transition.setInterpolator(Interpolator.LINEAR);
A Timeline is used to define a free form Animation
of any WritableValue<T>
. It is helpful if none of the built-in transitions operate on the required properties.
It consists of a sequential series of KeyFrame
. Each KeyFrame
encapsulates a moment in time (Cue Point), and collectively specify how target properties evolve over the entire duration.
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.
A 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.
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
. It is also possible to provide an onFinished
implementation, which will be invoked when hitting this cue point.
A 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. An Interpolator
can be additionally defined to change the rate of change for this value. The KeyValue
class is immutable.
This example of Timeline
creates a Circle
which moves 200px in x direction over the duration of 5 seconds:
Circle object = new Circle(50, 150, 10, Color.GREEN);
KeyValue x = new KeyValue(object.translateXProperty(), 200);
KeyFrame frame = new KeyFrame(Duration.seconds(5), x);
Timeline timeline = new Timeline(frame);
timeline.play();
The Interpolator abstract class defines the rate of change at which values change over time, influencing the smoothness of animations.
It provides several built-in implementations:
DISCRETE
interpolator creates a sudden transition between values without any intermediate steps.LINEAR
interpolator produces a constant rate of change between values over time.EASE_IN
interpolator starts the animation slowly and accelerates as it progresses.EASE_OUT
interpolator starts quickly and slows down as it progresses.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
.Additionally, there are two static factory methods for SPLINE and TANGENT interpolation.
Here is a visualization of the Interpolator using the example from Timeline:
The javafx.animation
package offers a simple framework for creating dynamic animations within JavaFX applications.
From the foundational AnimationTimer
and Animation
classes to the more specialized Transition
and Timeline
classes,
each component provides unique capabilities for creating animations. Additionally, you are provided with various
common Interpolator
implementations.
As somebody who knows the JavaFX basics but not the animation package, I'm pretty much your target audience. On closer reading, I struggle to understand the relation between Animation
, AnimationTimer
, and Transition
- can you explain that in a bit more detail? Also, make sure to signal to the reader why they're reading a section. Is the one on Animation
something they're supposed to understand to the point where they can use the class? Or is it "just" a prerequisite to understand what comes next?
For the fade example (since it's the first one): Can you show a bit more of the surrounding code, so readers can understand how exactly they can use a transition? As far as I can tell, the object
variable references a JavaFX element (Is that the term? Whatever it is, maybe base the variable name on that - object
is too general) but I don't quite see how you trigger the start of the animation. If you'd rather explain that later, that's ok, but then you need to let the reader know.
Overall, put yourself in the shoes of somebody who doesn't know the API at all. For every piece of information: Does the reader already know everything they need to understand it? Do they understand how they're supposed to use the information (e.g. as prerequisite for what comes next or to use it as explained?).
When you've changed the text accordingly, feel free to open a PR, so we can do a more detailed preview. (I'll be out of office until early May, though, so no need to rush. 😉)
thanks @nipafx! @SquidXTV we can also have others review if @nipafx isn't back yet and you want to keep things moving.
Thanks for the feedback. Actually, the timing works out well for me too, as I currently have my finals. They end mid-May, so I'll pick up on this then.
ok great. when you're ready, go ahead and raise a PR! We'll get it reviewed quickly and try and bring it in for a landing by the end of May if that works for you. Good luck on finals!
Hi,
I have one more question, where should I place the content like the markdown and GIFs?
I probably shouldn't touch the already existing JavaFX tutorial series, right? So I would put it in
/07_rich_client_apps/
as a single page tutorial.
I would place the GIFs into the /images/javafx/
folder, but it is probably better to create a dedicated subfolder, or should I just dump everything in root?
Ya put into 07_rich_client_apps
as a single-page tutorial (if that's what it is, unless you want to break things up into a series) and then image assets into /images/javafx/<your_subfolder>
. We can move things around easily from there if needed. Call the subfolder whatever you want. /squidxtv, /advanced, /animation
Thank you!
Request Issue
No response
Website Section
No response
Proposal Details
No response
Author References
No response