Reputation:
I'm creating animation that will start rotating from left top corner to center of scene then go to right top corner and stop the rotation. Everything works fine but when it goes to top right corner it stop in wrong angle.
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.scene.Group;
import javafx.animation.Animation;
import javafx.animation.RotateTransition;
import javafx.animation.KeyValue;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.Interpolator;
import javafx.util.Duration;
import javafx.event.EventHandler;
import javafx.event.ActionEvent;
public class ComeWaitGo extends Application{
@Override
public void start(Stage stage){
Rectangle box = new Rectangle(0, 0, 50, 50);
RotateTransition rotate = new RotateTransition(Duration.millis(2000), box);
rotate.setCycleCount(Animation.INDEFINITE);
rotate.setByAngle(360);
rotate.setInterpolator(Interpolator.LINEAR);
rotate.play();
KeyValue one = new KeyValue(box.xProperty(), 125);
KeyValue two = new KeyValue(box.yProperty(), 100);
KeyValue three = new KeyValue(box.xProperty(), 125);
KeyValue four = new KeyValue(box.yProperty(), 100);
KeyValue five = new KeyValue(box.xProperty(), 250);
KeyValue six = new KeyValue(box.yProperty(), 0);
EventHandler<ActionEvent> stopRotate = new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent e){
rotate.stop();
}
};
KeyFrame frame = new KeyFrame(Duration.millis(3000), one, two);
KeyFrame frametwo = new KeyFrame(Duration.millis(8000), three, four);
KeyFrame framethree = new KeyFrame(Duration.millis(11000), stopRotate, five, six);
Timeline timeline = new Timeline();
timeline.getKeyFrames().addAll(frame, frametwo, framethree);
timeline.play();
Group root = new Group();
root.getChildren().addAll(box);
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.show();
}
}
As you can see in image. when Rectangle goes to top right corner it not showing properly. ( Red line is just showing the path of rectangle (Image Editied))
So how I can get this animation? So the rectangle at the end should be in proper angle.
Upvotes: 1
Views: 491
Reputation: 82461
Simply animate the rotate
property of box
using the timeline too, instead of using a seperate RotateTransition
animation in addition to the Timeline
animation:
KeyFrame framethree = new KeyFrame(Duration.millis(11000)
/*, stopRotate*/,
new KeyValue(box.rotateProperty(), 360d * 11000d / 2000d, Interpolator.LINEAR),
five,
six);
Alternatively combine both animations using a ParallelTransition
to make sure both animations run synchronous:
// rotate.play();
...
Timeline timeline = new Timeline();
ParallelTransition transitions = new ParallelTransition(timeline, rotate);
EventHandler<ActionEvent> stopRotate = new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
transitions.stop();
}
};
KeyFrame framethree = new KeyFrame(Duration.millis(11000), stopRotate, five, six);
timeline.getKeyFrames().addAll(frame, frametwo, framethree);
// timeline.play();
transitions.play();
complete start
methods as requested
Approach 1:
@Override
public void start(Stage stage) {
Rectangle box = new Rectangle(0, 0, 50, 50);
KeyValue one = new KeyValue(box.xProperty(), 125);
KeyValue two = new KeyValue(box.yProperty(), 100);
KeyValue three = new KeyValue(box.xProperty(), 125);
KeyValue four = new KeyValue(box.yProperty(), 100);
KeyValue five = new KeyValue(box.xProperty(), 250);
KeyValue six = new KeyValue(box.yProperty(), 0);
KeyFrame frame = new KeyFrame(Duration.millis(3000), one, two);
KeyFrame frametwo = new KeyFrame(Duration.millis(8000), three, four);
KeyFrame framethree = new KeyFrame(Duration.millis(11000), five, six, new KeyValue(box.rotateProperty(), 360d * 11000d / 2000d, Interpolator.LINEAR));
Timeline timeline = new Timeline();
timeline.getKeyFrames().addAll(frame, frametwo, framethree);
timeline.play();
Group root = new Group();
root.getChildren().addAll(box);
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.show();
}
Approach 2:
@Override
public void start(Stage stage) {
Rectangle box = new Rectangle(0, 0, 50, 50);
RotateTransition rotate = new RotateTransition(Duration.millis(2000), box);
rotate.setCycleCount(Animation.INDEFINITE);
rotate.setByAngle(360);
rotate.setInterpolator(Interpolator.LINEAR);
KeyValue one = new KeyValue(box.xProperty(), 125);
KeyValue two = new KeyValue(box.yProperty(), 100);
KeyValue three = new KeyValue(box.xProperty(), 125);
KeyValue four = new KeyValue(box.yProperty(), 100);
KeyValue five = new KeyValue(box.xProperty(), 250);
KeyValue six = new KeyValue(box.yProperty(), 0);
KeyFrame frame = new KeyFrame(Duration.millis(3000), one, two);
KeyFrame frametwo = new KeyFrame(Duration.millis(8000), three, four);
Timeline timeline = new Timeline();
ParallelTransition transitions = new ParallelTransition(timeline, rotate);
EventHandler<ActionEvent> stopRotate = new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
transitions.stop();
}
};
KeyFrame framethree = new KeyFrame(Duration.millis(11000), stopRotate, five, six);
timeline.getKeyFrames().addAll(frame, frametwo, framethree);
transitions.play();
Group root = new Group();
root.getChildren().addAll(box);
Scene scene = new Scene(root, 300, 250);
stage.setScene(scene);
stage.show();
}
Upvotes: 2
Reputation: 205785
One approach would be to reset the box's rotation in stopRotate()
:
EventHandler<ActionEvent> stopRotate = new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent e){
rotate.stop();
box.setRotate(0);
}
};
Upvotes: 2