I'm trying to fade-in one object at a time in javafx. I've tried to use a for loop to loop through the nodes of a group but all the nodes in a group seem to be displayed at the same time instead of being faded-in one at time. i just can't seem to figure out where the problem is.
Group points = new Group();
for(int i = 0; i < ipSize; i++){
double xCentre = ipXPoints[i]-5;
double yCentre = ipYPoints[i]-5;
Circle point = new Circle(xCentre , yCentre, 10, Color.FORESTGREEN);
points.getChildren().add(point);
}
pane.getChildren().add(points);
Timeline timeline = new Timeline();
for(Node node: pane.getChildren()){
timeline.getKeyFrames().addAll(
new KeyFrame(Duration.seconds(0), // set start position at 0
new KeyValue(node.opacityProperty(), 0, Interpolator.EASE_BOTH)
),
new KeyFrame(Duration.seconds(3),
new KeyValue(node.opacityProperty(), 1, Interpolator.EASE_BOTH)
)
);
timeline.play();
}
EDIT: I've also tried this but it keeps playing all the nodes at the same time instead of one at a time.
FadeTransition fade = new FadeTransition(Duration.seconds(3), node);
fade.setFromValue(0);
fade.setToValue(1);
fade.setAutoReverse(false);
fade.setCycleCount(1);
fade.setInterpolator(Interpolator.EASE_BOTH);
fade.play();
Thanks for your help :)
The reason why you get all the circles showing at the same time is that KeyFrame
duration is actually not the duration of the frame, but the absolute duration from the start of the animation. So you are specifying all of your transitions to happen between 0s and 3s. To fix your code, you would need to set the first pair of KeyFrame durations to 0s and 3s, the second pair to 3s and 6s, the third pair to 6s and 9s, etc.
Alternatively, you can use a SequentialTransition
of FadeTransitions
:
import java.util.Random;
import javafx.animation.FadeTransition;
import javafx.animation.SequentialTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SequentialFadeIn extends Application {
@Override
public void start(Stage stage) {
int width = 600;
int height = 400;
Group points = new Group();
SequentialTransition seq = new SequentialTransition();
Random random = new Random();
for(int i = 0; i < 10; i++){
double xCentre = random.nextInt(width);
double yCentre = random.nextInt(height);
Circle point = new Circle(xCentre , yCentre, 10, Color.FORESTGREEN);
point.setOpacity(0.0);
points.getChildren().add(point);
FadeTransition fade = new FadeTransition(Duration.seconds(3), point);
fade.setToValue(1.0);
seq.getChildren().add(fade);
}
stage.setScene(new Scene(points, width, height));
stage.show();
seq.play();
}
public static void main(String[] args) {
launch(args);
}
}