TranslateTransition 不改变 (X,Y) 坐标
TranslateTransition does not change (X,Y) co-ordinates
在学习 javafx.animation API 时,我尝试了以下代码,
它只是在 (100,100) 处绘制一个矩形,并在 2 秒内 将其翻译 为 (200,200)。
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
public class SimpleAnimation extends Application {
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
VBox vb = new VBox();
Rectangle rect = new Rectangle (100, 100, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
final Duration SEC_2 = Duration.millis(2000);
System.out.println("Location before relocation = "+rect.getX()+","+rect.getY()+")");
TranslateTransition tt = new TranslateTransition(SEC_2,rect);
tt.setByX(100f);
tt.setByY(100f);
tt.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Location after relocation = " + rect.getX() + "," + rect.getY() + ")");
}
});
tt.play();
vb.getChildren().add(rect);
scene.setRoot(vb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
在这个 translationTransition 之后,矩形的 (x,y) 坐标应该是 (200,200) 对吗?
为了检查这一点,我尝试在 OnFinished() 事件处理程序中打印坐标。
不知道为什么它仍然打印 (100,100) ?
来自Javadocs:
This Transition creates a move/translate animation that spans its
duration. This is done by updating the translateX, translateY and
translateZ variables of the node at regular interval.
因此,如果您在转换结束时检查 translateX
和 translateY
属性,您会发现它们都等于 100
;即矩形已从其原始位置在两个方向上平移了 100
个单位。
具体取决于您想要做什么,您可以使用 translateX
和 translateY
属性,或者使用 boundsInParent
属性,这给出节点在其父坐标系中的边界(因此包括任何变换,例如平移)。
如果您希望 Rectangle
的 x
和 y
属性直接从动画中更改,请使用 Timeline
,它允许您指定属性(或属性)变化:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SimpleAnimation extends Application {
@Override
public void start(Stage stage) {
VBox vb = new VBox();
Rectangle rect = new Rectangle(100, 100, 100, 100);
rect.setManaged(false);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
final Duration SEC_2 = Duration.millis(2000);
System.out.println("Location before relocation = " + rect.getX() + ","
+ rect.getY() + ")");
Timeline timeline = new Timeline();
KeyFrame end = new KeyFrame(SEC_2,
new KeyValue(rect.xProperty(), 200),
new KeyValue(rect.yProperty(), 200));
timeline.getKeyFrames().add(end);
timeline.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Location after relocation = " + rect.getX()
+ "," + rect.getY() + ")");
}
});
timeline.play();
vb.getChildren().add(rect);
Scene scene = new Scene(vb, 500, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
请注意,为了让它起作用,我添加了调用 rect.setManaged(false)
。由于您在 VBox
中有 Rectangle
,它管理其子节点的布局,因此更改 x
和 y
属性将不会产生其他影响。 (另一种选择是将 VBox
替换为 Pane
,它不管理其子节点的放置。)
动画完成后,将动画节点移动到平移坐标:
tt.setOnFinished(event -> {
// The transition works by manipulating translation values,
// After the transition is complete, move the node to the new location
// and zero the translation after relocating the node.
rect.setX(rect.getX() + rect.getTranslateX());
rect.setY(rect.getY() + rect.getTranslateY());
rect.setTranslateX(0);
rect.setTranslateY(0);
});
此外,您将 Rectangle 放在 VBox 中,如果您希望矩形的 X&Y 坐标具有任何意义,请不要这样做。 VBox 是一个布局管理器,会忽略矩形的 X 和 Y 坐标(因为它会使内部的所有内容垂直布局)。而是在不执行布局的父级(例如组或窗格)中执行动画。
可执行示例:
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SimpleAnimation extends Application {
@Override
public void start(Stage stage) {
Rectangle rect = new Rectangle(100, 100, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
System.out.println("Location before relocation = " + rect.getX() + "," + rect.getY() + ")");
TranslateTransition tt = new TranslateTransition(
Duration.seconds(2),
rect
);
tt.setByX(100f);
tt.setByY(100f);
tt.setOnFinished(event -> {
rect.setX(rect.getX() + rect.getTranslateX());
rect.setY(rect.getY() + rect.getTranslateY());
rect.setTranslateX(0);
rect.setTranslateY(0);
System.out.println("Location after relocation = " + rect.getX() + "," + rect.getY() + ")");
});
tt.play();
Scene scene = new Scene(new Group(rect), 500, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
在学习 javafx.animation API 时,我尝试了以下代码, 它只是在 (100,100) 处绘制一个矩形,并在 2 秒内 将其翻译 为 (200,200)。
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
public class SimpleAnimation extends Application {
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
VBox vb = new VBox();
Rectangle rect = new Rectangle (100, 100, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
final Duration SEC_2 = Duration.millis(2000);
System.out.println("Location before relocation = "+rect.getX()+","+rect.getY()+")");
TranslateTransition tt = new TranslateTransition(SEC_2,rect);
tt.setByX(100f);
tt.setByY(100f);
tt.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Location after relocation = " + rect.getX() + "," + rect.getY() + ")");
}
});
tt.play();
vb.getChildren().add(rect);
scene.setRoot(vb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
在这个 translationTransition 之后,矩形的 (x,y) 坐标应该是 (200,200) 对吗?
为了检查这一点,我尝试在 OnFinished() 事件处理程序中打印坐标。
不知道为什么它仍然打印 (100,100) ?
来自Javadocs:
This Transition creates a move/translate animation that spans its duration. This is done by updating the translateX, translateY and translateZ variables of the node at regular interval.
因此,如果您在转换结束时检查 translateX
和 translateY
属性,您会发现它们都等于 100
;即矩形已从其原始位置在两个方向上平移了 100
个单位。
具体取决于您想要做什么,您可以使用 translateX
和 translateY
属性,或者使用 boundsInParent
属性,这给出节点在其父坐标系中的边界(因此包括任何变换,例如平移)。
如果您希望 Rectangle
的 x
和 y
属性直接从动画中更改,请使用 Timeline
,它允许您指定属性(或属性)变化:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SimpleAnimation extends Application {
@Override
public void start(Stage stage) {
VBox vb = new VBox();
Rectangle rect = new Rectangle(100, 100, 100, 100);
rect.setManaged(false);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
final Duration SEC_2 = Duration.millis(2000);
System.out.println("Location before relocation = " + rect.getX() + ","
+ rect.getY() + ")");
Timeline timeline = new Timeline();
KeyFrame end = new KeyFrame(SEC_2,
new KeyValue(rect.xProperty(), 200),
new KeyValue(rect.yProperty(), 200));
timeline.getKeyFrames().add(end);
timeline.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Location after relocation = " + rect.getX()
+ "," + rect.getY() + ")");
}
});
timeline.play();
vb.getChildren().add(rect);
Scene scene = new Scene(vb, 500, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
请注意,为了让它起作用,我添加了调用 rect.setManaged(false)
。由于您在 VBox
中有 Rectangle
,它管理其子节点的布局,因此更改 x
和 y
属性将不会产生其他影响。 (另一种选择是将 VBox
替换为 Pane
,它不管理其子节点的放置。)
动画完成后,将动画节点移动到平移坐标:
tt.setOnFinished(event -> {
// The transition works by manipulating translation values,
// After the transition is complete, move the node to the new location
// and zero the translation after relocating the node.
rect.setX(rect.getX() + rect.getTranslateX());
rect.setY(rect.getY() + rect.getTranslateY());
rect.setTranslateX(0);
rect.setTranslateY(0);
});
此外,您将 Rectangle 放在 VBox 中,如果您希望矩形的 X&Y 坐标具有任何意义,请不要这样做。 VBox 是一个布局管理器,会忽略矩形的 X 和 Y 坐标(因为它会使内部的所有内容垂直布局)。而是在不执行布局的父级(例如组或窗格)中执行动画。
可执行示例:
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SimpleAnimation extends Application {
@Override
public void start(Stage stage) {
Rectangle rect = new Rectangle(100, 100, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
System.out.println("Location before relocation = " + rect.getX() + "," + rect.getY() + ")");
TranslateTransition tt = new TranslateTransition(
Duration.seconds(2),
rect
);
tt.setByX(100f);
tt.setByY(100f);
tt.setOnFinished(event -> {
rect.setX(rect.getX() + rect.getTranslateX());
rect.setY(rect.getY() + rect.getTranslateY());
rect.setTranslateX(0);
rect.setTranslateY(0);
System.out.println("Location after relocation = " + rect.getX() + "," + rect.getY() + ")");
});
tt.play();
Scene scene = new Scene(new Group(rect), 500, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}