【问题标题】:JavaFX 2 circle path for animationJavaFX 2动画的圆形路径
【发布时间】:2012-12-19 18:14:33
【问题描述】:

如何在 JavaFX 2 中创建圆形(或椭圆)javafx.scene.shape.Path

我找到了一些使用 CubicCurveTo 的示例:

Path path = new Path();
path.getElements().add(new CubicCurveTo(30, 10, 380, 120, 200, 120));

但我不明白贝塞尔坐标。我需要一个完整的动画路径。

【问题讨论】:

    标签: javafx-2


    【解决方案1】:

    您可以利用ArcTo 路径元素绘制圆形或椭圆路径:

    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.ORTHOGONAL_TO_TANGENT)
                    .cycleCount(Timeline.INDEFINITE)
                    .autoReverse(false)
                    .build();
    
    
            // Cirle 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.ORTHOGONAL_TO_TANGENT)
                    .cycleCount(Timeline.INDEFINITE)
                    .autoReverse(false)
                    .build();
        }
    
        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);
        }
    }
    

    ArcTo 功能的良好参考是ArcTo (JavaFX 8)。虽然是第8版,但功能的含义是相似的。
    输出:

    【讨论】:

    • 完美答案!谢谢。
    • 这是一个非常好的演示 Uluk :-)
    • 非常棒的例子......在你的动画中,每个循环后都会有轻微的延迟。有什么办法可以消除这种延迟并使循环旋转连续吗?
    【解决方案2】:

    我通过容器的rotateProperty 动画解决了同样的问题。只需两行即可创建动画。

        animationTimeLine = new Timeline(60, new KeyFrame(Duration.seconds(5), new KeyValue(circlePane.rotateProperty(), 360.0)));
    
        animationTimeLine.setCycleCount(INDEFINITE);
    

    【讨论】:

      【解决方案3】:

      这是@Uluk Biy 答案的更新版本。

      import javafx.animation.PathTransition;
      import javafx.animation.PathTransition.OrientationType;
      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.ArcTo;
      import javafx.scene.shape.ClosePath;
      import javafx.scene.shape.MoveTo;
      import javafx.scene.shape.Path;
      import javafx.scene.shape.Rectangle;
      import javafx.stage.Stage;
      import javafx.util.Duration;
      
      public class PathTDemo 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 = new PathTransition();
              pathTransitionEllipse.setDuration(Duration.seconds(4));
              pathTransitionEllipse.setPath(path);
              pathTransitionEllipse.setNode(rect);
              pathTransitionEllipse.setOrientation(OrientationType.ORTHOGONAL_TO_TANGENT);
              pathTransitionEllipse.setCycleCount(Timeline.INDEFINITE);
              pathTransitionEllipse.setAutoReverse(false);
      
              // Cirle 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 = new PathTransition();
              pathTransitionCircle.setDuration(Duration.seconds(2));
              pathTransitionCircle.setPath(path2);
              pathTransitionCircle.setNode(rect2);
              pathTransitionCircle.setOrientation(OrientationType.ORTHOGONAL_TO_TANGENT);
              pathTransitionCircle.setCycleCount(Timeline.INDEFINITE);
              pathTransitionCircle.setAutoReverse(false);
          }
      
          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 = new Path();
              path.getElements().addAll(
                      new MoveTo(centerX - radiusX, centerY - radiusY),
                      arcTo,
                      new ClosePath()); // close 1 px gap.
              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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-22
        • 1970-01-01
        相关资源
        最近更新 更多