简体   繁体   English

在JavaFX中的PathTransition中需要帮助

[英]Need help in PathTransition in JavaFX

I am trying to get around 8-12 circles rotate in a circle behind each other. 我试图使8到12个圆圈彼此之间绕一个圆圈旋转。

Here is the code I am trying 这是我正在尝试的代码

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

On compiling and executing this code, I get a circle which goes on a circular path. 在编译和执行此代码时,我得到一个沿圆形路径运行的圆。 But after each rotation, there is a slight delay before the next rotation starts, even though I have set the delay to zero. 但是,即使我将延迟设置为零,但在每次旋转之后,在下一个旋转开始之前都会有一些延迟。

So using this code, when I create multiple circles on the path (I take a different path for each circle, so it looks like they are on the same path and start each individual from a later time phase using playFrom() to synchronize their position), it gets really messy. 因此,使用此代码,当我在路径上创建多个圆圈时(我为每个圆圈使用了不同的路径,因此看起来它们在同一路径上,并使用playFrom()从后面的时间阶段开始每个人,以使其位置同步),它真的很乱。

What I want is, multiple circles moving on a circular path uniformly, but that slight delay makes it look very bad. 我想要的是,多个圆均匀地在圆形路径上移动,但是这种轻微的延迟使其看起来非常糟糕。

So my questions are 所以我的问题是

  1. What can I do to remove that delay? 我该怎么做才能消除这种延迟? Would constructing the path in a different way help? 以其他方式构造路径会有所帮助吗? Is there any way to remove that delay? 有什么办法可以消除这种延迟?

  2. The rotation of the circle starts from 3'o clock position on the path, is there any way to change the initial position of the node on the path? 圆的旋转从路径上的3点钟位置开始,是否有任何方法可以更改路径上节点的初始位置?

  3. Can I add multiple nodes to the same path? 是否可以将多个节点添加到同一路径? Say 5 circle nodes to the path, with different initial positions. 对路径说5个圆形节点,它们的初始位置不同。

  1. Call pathTransition.setInterpolator(Interpolator.LINEAR); 调用pathTransition.setInterpolator(Interpolator.LINEAR);
  2. You can rotate the path: path.setRotate(-90); 您可以旋转路径: path.setRotate(-90);
  3. I don't think there's an easy way to do this (with different starting positions), still using the PathTransition . 我不认为有一种简单的方法(使用不同的起始位置)来执行此操作,仍然使用PathTransition You can achieve a similar effect using a Timeline and binding a rotation for each circle to a property you "animate" with the timeline: 您可以使用Timeline并将每个圆的旋转绑定到使用Timeline “设置动画”的属性来实现类似的效果:

- --

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

You can use multiple path transitions (one per node), with the starting time of each transition offset by the distance along the path that you want a node to start at (using jumpTo ). 您可以使用多个路径过渡(每个节点一个),每个过渡的开始时间会偏移您希望节点开始的路径上的距离(使用jumpTo )。

This is a (simplified) variation on the solution to: " How to write text along a Bezier Curve? ". 这是以下解决方案的(简化)变体:“ 如何沿贝塞尔曲线书写文本? ”。 The solution will work for nodes traveling along an arbitrary path, not just nodes traveling in a circle. 该解决方案将适用于沿任意路径传播的节点,而不仅限于沿圆周传播的节点。

路径过渡

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM