I am using RotateTransiton
to rotate a line, but it seems to rotate through center of the line. I would like to rotate it with pivot as one end of the line. Ho
(on JavaFX 2.2 and JavaFX 8) The best way in my opinion is tranlating the layoutBounds of the node (which contains the pivot point) and translating the node itself the opposite way.
An example:
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
primaryStage.setScene(new Scene(root, 140, 140));
Rectangle rect = new Rectangle(1, 1, 40, 40);
// comment movePivot to get the default rotation
movePivot(rect, -20, -20);
RotateTransition rt = new RotateTransition(Duration.seconds(4),rect);
rt.setToAngle(720);
rt.setCycleCount(Timeline.INDEFINITE);
rt.setAutoReverse(true);
rt.play();
primaryStage.show();
}
// this is the function you want
private void movePivot(Node node, double x, double y){
node.getTransforms().add(new Translate(-x,-y));
node.setTranslateX(x); node.setTranslateY(y);
}
public static void main(String[] args) {
launch(args);
}
}
The RotateTransition
works by changing the rotate property, which - as you have observed - defines a rotation around the center of the Node
.
If you want to rotate around a different point, define a Rotate transform, set its pivot, add it to the line's list of transforms, and use a Timeline
to manipulate its angle.
Here's an example:
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class RotateLineAboutEnd extends Application {
@Override
public void start(Stage primaryStage) {
Line line = new Line(200, 200, 200, 350);
Pane pane = new Pane(line);
Rotate rotation = new Rotate();
rotation.pivotXProperty().bind(line.startXProperty());
rotation.pivotYProperty().bind(line.startYProperty());
line.getTransforms().add(rotation);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rotation.angleProperty(), 0)),
new KeyFrame(Duration.seconds(1), new KeyValue(rotation.angleProperty(), 360)));
Button button = new Button("Rotate");
button.setOnAction(evt -> timeline.play());
button.disableProperty().bind(timeline.statusProperty().isEqualTo(Animation.Status.RUNNING));
HBox controls = new HBox(button);
controls.setAlignment(Pos.CENTER);
controls.setPadding(new Insets(12));
BorderPane root = new BorderPane(pane, null, null, controls, null);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}