在JavaFX中需要PathTransition的帮助

时间:2015-09-21 17:54:46

标签: java animation javafx javafx-2 javafx-8

我试图让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);
    }
}

在编译和执行此代码时,我得到一个循环路径的圆圈。但是在每次旋转之后,在下一次旋转开始之前会有一点延迟,即使我已将延迟设置为零。

因此,使用此代码,当我在路径上创建多个圆圈时(我为每个圆圈采用不同的路径,因此看起来它们位于相同的路径上,并使用{{1}从稍后的时间阶段开始每个人<同步他们的位置),它变得非常混乱。

我想要的是,多个圆圈均匀地在圆形路径上移动,但是这种轻微的延迟使它看起来非常糟糕。

所以我的问题是

  1. 如何消除延迟?以不同的方式构建路径会有帮助吗?有没有办法消除这种延迟?

  2. 圆圈的旋转从路径上的3'时钟位置开始,有没有办法改变路径上节点的初始位置?

  3. 我可以将多个节点添加到同一路径吗?假设5个圆形节点到路径,具有不同的初始位置。

2 个答案:

答案 0 :(得分:3)

  1. 致电pathTransition.setInterpolator(Interpolator.LINEAR);
  2. 您可以旋转路径:path.setRotate(-90);
  3. 我认为有一种简单的方法(使用不同的起始位置),仍然使用PathTransition。您可以使用Timeline获得类似的效果,并将每个圆圈的旋转绑定到您使用时间轴“动画”的属性:
  4. -

    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);
        }
    }
    

答案 1 :(得分:3)

您可以使用多个路径转换(每个节点一个),每个转换的开始时间偏移您希望节点开始的路径上的距离(使用jumpTo)。

这是解决方案的(简化)变体:&#34; How to write text along a Bezier Curve?&#34;。该解决方案适用于沿任意路径行进的节点,而不仅仅是以圆形行进的节点。

path transition

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);
    }
}