在 JavaFX 中的 PathTransition 方面需要帮助
Need help in PathTransition in JavaFX
我试图让 8-12 个圆圈在彼此后面旋转一圈。
这是我正在尝试的代码
import javafx.animation.PathTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Cirlces extends Application {
@Override
public void start(final Stage stage) throws Exception {
final Group group = new Group();
final Scene scene = new Scene(group, 500, 500, Color.WHITE);
stage.setScene(scene);
stage.setTitle("Circles");
stage.show();
final Circle circle = new Circle(20, 20, 15);
circle.setFill(Color.DARKRED);
Circle path = new Circle(250,250,200);
path.setFill(Color.WHITE);
group.getChildren().add(path);
group.getChildren().add(circle);
final PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.seconds(2.0));
pathTransition.setDelay(Duration.ZERO);
pathTransition.setPath(path);
pathTransition.setNode(circle);
pathTransition
.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathTransition.setCycleCount(Timeline.INDEFINITE);
//pathTransition.setAutoReverse(true);
pathTransition.play();
}
public static void main(final String[] arguments) {
Application.launch(arguments);
}
}
在编译和执行这段代码时,我得到了一个在圆形路径上的圆圈。但是在每次旋转之后,在下一次旋转开始之前会有轻微的延迟,即使我已将延迟设置为零。
所以使用这段代码,当我在路径上创建多个圆圈时(我为每个圆圈走不同的路径,所以看起来它们在同一条路径上,并使用 playFrom()
来同步他们的位置),它变得非常混乱。
我想要的是,多个圆圈在一个圆的路径上匀速移动,但是稍有延迟就很不好看
所以我的问题是
我该怎么做才能消除这种延迟?以不同的方式构建路径会有帮助吗?有什么办法可以消除这种延迟吗?
圆的旋转从路径上的3点钟位置开始,请问有什么办法可以改变路径上节点的初始位置?
我可以将多个节点添加到同一路径吗?给路径说5个圆节点,初始位置不同
- 致电
pathTransition.setInterpolator(Interpolator.LINEAR);
- 您可以旋转路径:
path.setRotate(-90);
- 我认为没有简单的方法可以做到这一点(起始位置不同),仍然使用
PathTransition
。您可以使用 Timeline
并将每个圆的旋转绑定到 属性 您 "animate" 与时间轴的类似效果:
-
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class CircleTransitions extends Application {
@Override
public void start(final Stage stage) throws Exception {
final Group group = new Group();
final Scene scene = new Scene(group, 500, 500, Color.WHITE);
stage.setScene(scene);
stage.setTitle("Circles");
stage.show();
Circle path = new Circle(250,250,200);
path.setFill(Color.WHITE);
DoubleProperty angle = new SimpleDoubleProperty();
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(angle, 360)));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
group.getChildren().add(path);
for (int i=0; i<5; i++) {
Circle circle = new Circle(250, 450, 15);
circle.setFill(Color.DARKRED);
Rotate rotate = new Rotate(0, 250, 250);
circle.getTransforms().add(rotate);
rotate.angleProperty().bind(angle.add(360.0 * i / 5));
group.getChildren().add(circle);
}
}
public static void main(final String[] arguments) {
Application.launch(arguments);
}
}
您可以使用多个路径转换(每个节点一个),每个转换的开始时间偏移您希望节点开始的路径上的距离(使用 jumpTo
)。
这是对“How to write text along a Bezier Curve?”的解决方案的(简化)变体。该解决方案适用于沿任意路径移动的节点,而不仅仅是沿圆周移动的节点。
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;
public class CirclePathTransitions extends Application {
private static final int NUM_NODES = 5;
private static final double W = 200;
private static final double H = 200;
private static final double NODE_SIZE = H / 8.0;
@Override
public void start(final Stage stage) throws Exception {
Pane content = new Pane();
content.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
content.setPrefSize(W, H);
content.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
content.setStyle("-fx-background-color: coral;");
Shape path = new Circle(W/2, H/2, H * 3 / 8.0 - NODE_SIZE);
content.getChildren().add(new Circle(W/2, H/2, H * 3 / 8.0 - NODE_SIZE, Color.PALEGREEN));
for (int i = 0; i < NUM_NODES; i++) {
Node node = new Circle(NODE_SIZE / 2, Color.MIDNIGHTBLUE);
content.getChildren().add(node);
final Transition transition = createPathTransition(path, node);
transition.jumpTo(Duration.seconds(10).multiply(i * 1.0 / NUM_NODES));
transition.play();
}
stage.setScene(new Scene(new StackPane(content), W, H, Color.ALICEBLUE));
stage.show();
}
private PathTransition createPathTransition(Shape shape, Node node) {
final PathTransition transition = new PathTransition(
Duration.seconds(10),
shape,
node
);
transition.setAutoReverse(false);
transition.setCycleCount(PathTransition.INDEFINITE);
transition.setInterpolator(Interpolator.LINEAR);
return transition;
}
public static void main(String[] args) throws Exception {
launch(args);
}
}
我试图让 8-12 个圆圈在彼此后面旋转一圈。
这是我正在尝试的代码
import javafx.animation.PathTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Cirlces extends Application {
@Override
public void start(final Stage stage) throws Exception {
final Group group = new Group();
final Scene scene = new Scene(group, 500, 500, Color.WHITE);
stage.setScene(scene);
stage.setTitle("Circles");
stage.show();
final Circle circle = new Circle(20, 20, 15);
circle.setFill(Color.DARKRED);
Circle path = new Circle(250,250,200);
path.setFill(Color.WHITE);
group.getChildren().add(path);
group.getChildren().add(circle);
final PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.seconds(2.0));
pathTransition.setDelay(Duration.ZERO);
pathTransition.setPath(path);
pathTransition.setNode(circle);
pathTransition
.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathTransition.setCycleCount(Timeline.INDEFINITE);
//pathTransition.setAutoReverse(true);
pathTransition.play();
}
public static void main(final String[] arguments) {
Application.launch(arguments);
}
}
在编译和执行这段代码时,我得到了一个在圆形路径上的圆圈。但是在每次旋转之后,在下一次旋转开始之前会有轻微的延迟,即使我已将延迟设置为零。
所以使用这段代码,当我在路径上创建多个圆圈时(我为每个圆圈走不同的路径,所以看起来它们在同一条路径上,并使用 playFrom()
来同步他们的位置),它变得非常混乱。
我想要的是,多个圆圈在一个圆的路径上匀速移动,但是稍有延迟就很不好看
所以我的问题是
我该怎么做才能消除这种延迟?以不同的方式构建路径会有帮助吗?有什么办法可以消除这种延迟吗?
圆的旋转从路径上的3点钟位置开始,请问有什么办法可以改变路径上节点的初始位置?
我可以将多个节点添加到同一路径吗?给路径说5个圆节点,初始位置不同
- 致电
pathTransition.setInterpolator(Interpolator.LINEAR);
- 您可以旋转路径:
path.setRotate(-90);
- 我认为没有简单的方法可以做到这一点(起始位置不同),仍然使用
PathTransition
。您可以使用Timeline
并将每个圆的旋转绑定到 属性 您 "animate" 与时间轴的类似效果:
-
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class CircleTransitions extends Application {
@Override
public void start(final Stage stage) throws Exception {
final Group group = new Group();
final Scene scene = new Scene(group, 500, 500, Color.WHITE);
stage.setScene(scene);
stage.setTitle("Circles");
stage.show();
Circle path = new Circle(250,250,200);
path.setFill(Color.WHITE);
DoubleProperty angle = new SimpleDoubleProperty();
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(angle, 360)));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
group.getChildren().add(path);
for (int i=0; i<5; i++) {
Circle circle = new Circle(250, 450, 15);
circle.setFill(Color.DARKRED);
Rotate rotate = new Rotate(0, 250, 250);
circle.getTransforms().add(rotate);
rotate.angleProperty().bind(angle.add(360.0 * i / 5));
group.getChildren().add(circle);
}
}
public static void main(final String[] arguments) {
Application.launch(arguments);
}
}
您可以使用多个路径转换(每个节点一个),每个转换的开始时间偏移您希望节点开始的路径上的距离(使用 jumpTo
)。
这是对“How to write text along a Bezier Curve?”的解决方案的(简化)变体。该解决方案适用于沿任意路径移动的节点,而不仅仅是沿圆周移动的节点。
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;
public class CirclePathTransitions extends Application {
private static final int NUM_NODES = 5;
private static final double W = 200;
private static final double H = 200;
private static final double NODE_SIZE = H / 8.0;
@Override
public void start(final Stage stage) throws Exception {
Pane content = new Pane();
content.setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
content.setPrefSize(W, H);
content.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
content.setStyle("-fx-background-color: coral;");
Shape path = new Circle(W/2, H/2, H * 3 / 8.0 - NODE_SIZE);
content.getChildren().add(new Circle(W/2, H/2, H * 3 / 8.0 - NODE_SIZE, Color.PALEGREEN));
for (int i = 0; i < NUM_NODES; i++) {
Node node = new Circle(NODE_SIZE / 2, Color.MIDNIGHTBLUE);
content.getChildren().add(node);
final Transition transition = createPathTransition(path, node);
transition.jumpTo(Duration.seconds(10).multiply(i * 1.0 / NUM_NODES));
transition.play();
}
stage.setScene(new Scene(new StackPane(content), W, H, Color.ALICEBLUE));
stage.show();
}
private PathTransition createPathTransition(Shape shape, Node node) {
final PathTransition transition = new PathTransition(
Duration.seconds(10),
shape,
node
);
transition.setAutoReverse(false);
transition.setCycleCount(PathTransition.INDEFINITE);
transition.setInterpolator(Interpolator.LINEAR);
return transition;
}
public static void main(String[] args) throws Exception {
launch(args);
}
}