1

私はいくつかの javaFX コードを書いていて、いくつかのパスをグループに追加しました。このグループは、ルートに追加されて画面に表示されている別のグループに追加されました。ある時点で、PathTransition を使用して、この最下位レベルのグループを新しい場所にアニメーション化したいと考えています。トランジションの正しい座標を計算するのに問題があります。PathTransition は左上隅ではなく中央からノードをアニメーション化することを読んだので、Group.getLayoutX()/2 を開始 x に追加し、Group.getLayoutY()/2 を開始 y 座標に追加しようとしましたが、アニメーションが始まる前に、グループを新しい開始位置にジャンプさせているようです。最終目的地も少しずれているようです。複数のパスを含むグループをアニメーション化するより良い方法はありますか?

4

1 に答える 1

0

アニメーション化されているノードのレイアウト境界の半分に基づいて、パスをたどるノードのlayoutXとを調整します。layoutY

rect.setLayoutX(rect.getLayoutX() + rect.getLayoutBounds().getWidth()  / 2);
rect.setLayoutY(rect.getLayoutY() + rect.getLayoutBounds().getHeight() / 2);

アニメーション用の JavaFX 2 円パスから Uluk の円パス遷移コードを変更してみてください。

コードでは、ノードの元のレイアウトの左上隅がパスに従います。

ノードパスサンプル

import javafx.animation.PathTransition.OrientationType;
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ArcToDemo extends Application {

    private PathTransition pathTransitionEllipse;
    private PathTransition pathTransitionCircle;

    private void init(Stage primaryStage) {
        Group root = new Group();
        primaryStage.setResizable(false);
        primaryStage.setScene(new Scene(root, 600, 460));

        // Ellipse path example
        Rectangle rect = new Rectangle(0, 0, 40, 40);
        rect.setArcHeight(10);
        rect.setArcWidth(10);
        rect.setFill(Color.ORANGE);
        root.getChildren().add(rect);

        Path path = createEllipsePath(200, 200, 50, 100, 45);
        root.getChildren().add(path);

        pathTransitionEllipse = PathTransitionBuilder.create()
                .duration(Duration.seconds(4))
                .path(path)
                .node(rect)
                .orientation(OrientationType.NONE)
                .cycleCount(Timeline.INDEFINITE)
                .autoReverse(false)
                .build();

        rect.setLayoutX(rect.getLayoutX() + rect.getLayoutBounds().getWidth()  / 2);
        rect.setLayoutY(rect.getLayoutY() + rect.getLayoutBounds().getHeight() / 2);

        // Circle path example
        Rectangle rect2 = new Rectangle(0, 0, 20, 20);
        rect2.setArcHeight(10);
        rect2.setArcWidth(10);
        rect2.setFill(Color.GREEN);
        root.getChildren().add(rect2);

        Path path2 = createEllipsePath(400, 200, 150, 150, 0);
        root.getChildren().add(path2);

        pathTransitionCircle = PathTransitionBuilder.create()
                .duration(Duration.seconds(2))
                .path(path2)
                .node(rect2)
                .orientation(OrientationType.NONE)
                .cycleCount(Timeline.INDEFINITE)
                .autoReverse(false)
                .build();

        rect2.setLayoutX(rect2.getLayoutX() + rect2.getLayoutBounds().getWidth()  / 2);
        rect2.setLayoutY(rect2.getLayoutY() + rect2.getLayoutBounds().getHeight() / 2);
    }

    private Path createEllipsePath(double centerX, double centerY, double radiusX, double radiusY, double rotate) {
        ArcTo arcTo = new ArcTo();
        arcTo.setX(centerX - radiusX + 1); // to simulate a full 360 degree celcius circle.
        arcTo.setY(centerY - radiusY);
        arcTo.setSweepFlag(false);
        arcTo.setLargeArcFlag(true);
        arcTo.setRadiusX(radiusX);
        arcTo.setRadiusY(radiusY);
        arcTo.setXAxisRotation(rotate);

        Path path = PathBuilder.create()
                .elements(
                new MoveTo(centerX - radiusX, centerY - radiusY),
                arcTo,
                new ClosePath()) // close 1 px gap.
                .build();
        path.setStroke(Color.DODGERBLUE);
        path.getStrokeDashArray().setAll(5d, 5d);
        return path;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        init(primaryStage);
        primaryStage.show();
        pathTransitionEllipse.play();
        pathTransitionCircle.play();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

実装に関する注意事項

  1. このコードは、アニメーション化されているノードの元のレイアウト位置が 0,0 であることを前提としています (そうでない場合は、それに応じて調整する必要があります)。
  2. 正方形でないノードの場合、ノードとパスの間にわずかなギャップがあります (計算は、ノードの目に見える形状ではなく、レイアウト境界の長方形に基づいているため)。
  3. また、パス トランジションは、NONEではなくの方向を使用しORTHOGONAL_TO_TANGENTています (そうしないと、ノードが回転し始め、ノードがパスに分岐して移動しているように見えるため、レイアウトの計算で奇妙な効果が得られます)。

上記のアプローチの代わりに、ノードのコーナーが中央ではなくパスに追従し、ノードのレイアウトを変更する必要がないように、ノードのおよびプロパティを変更するTransitionのカスタム サブクラスを定義することができます。大幅に多くの作業。TranslateXTranslateY

于 2013-04-01T23:35:26.027 に答える