在时间轴中同时播放JavaFX动画

lnlaulya  于 2023-11-15  发布在  Java
关注(0)|答案(2)|浏览(157)

我对JavaFX还很陌生。我正在尝试制作这个时间轴,其中每个关键帧都在前一个关键帧完成后发生。到目前为止,每个步骤都按照我的要求一个接一个地发生。然而,我一播放动画,rotateBack关键帧就开始旋转我的对象。关于如何使rotateBack只在moveToRight之后播放,有什么提示吗?此外,我想为rotateBack完成其旋转前moveToTop播放。谢谢。

  1. Pane selectedPane = select_pane.getValue();
  2. double rootWidth = root_pane.getWidth();
  3. double rootHeight = root_pane.getHeight();
  4. double sixthWidth = rootWidth / 6;
  5. KeyValue moveTopLeftX = new KeyValue(selectedPane.layoutXProperty(), 0);
  6. KeyValue moveDownY = new KeyValue(selectedPane.layoutYProperty(), root_pane.getHeight() - selectedPane.getHeight());
  7. KeyValue moveRightX = new KeyValue(selectedPane.layoutXProperty(), sixthWidth);
  8. KeyValue rotate180 = new KeyValue(selectedPane.rotateProperty(), 180);
  9. KeyValue moveToTopY = new KeyValue(selectedPane.layoutYProperty(), 0);
  10. KeyFrame startFrame = new KeyFrame(Duration.seconds(3), moveTopLeftX, moveToTopY);
  11. KeyFrame moveToRight = new KeyFrame(Duration.seconds(2), moveRightX);
  12. KeyFrame rotateBack = new KeyFrame(Duration.seconds(3), rotate180);
  13. KeyFrame moveToBottom = new KeyFrame(Duration.seconds(6), moveDownY);
  14. KeyFrame moveToTop = new KeyFrame(Duration.seconds(6), moveToTopY);
  15. Timeline timeline = new Timeline(startFrame, moveToBottom, moveToRight, rotateBack, moveToTop);
  16. timeline.play();

字符串
到目前为止,我所尝试的是在上面的代码中显示。任何提示非常感谢。

juud5qan

juud5qan1#

要在一个关键帧完成后才播放一个关键帧,您可以创建不同的时间轴,并在时间轴.setOnFinished()函数中播放下一个。
对于你的例子,它看起来像这样:

  1. Pane selectedPane = select_pane.getValue();
  2. double rootWidth = root_pane.getWidth();
  3. double rootHeight = root_pane.getHeight();
  4. double sixthWidth = rootWidth / 6;
  5. KeyValue moveTopLeftX = new KeyValue(selectedPane.layoutXProperty(), 0);
  6. KeyValue moveDownY = new KeyValue(selectedPane.layoutYProperty(), root_pane.getHeight() - selectedPane.getHeight());
  7. KeyValue moveRightX = new KeyValue(selectedPane.layoutXProperty(), sixthWidth);
  8. KeyValue rotate180 = new KeyValue(selectedPane.rotateProperty(), 180);
  9. KeyValue moveToTopY = new KeyValue(selectedPane.layoutYProperty(), 0);
  10. KeyFrame startFrame = new KeyFrame(Duration.seconds(3), moveTopLeftX, moveToTopY);
  11. KeyFrame moveToRight = new KeyFrame(Duration.seconds(2), moveRightX);
  12. KeyFrame rotateBack = new KeyFrame(Duration.seconds(3), rotate180);
  13. KeyFrame moveToBottom = new KeyFrame(Duration.seconds(6), moveDownY);
  14. KeyFrame moveToTop = new KeyFrame(Duration.seconds(6), moveToTopY);
  15. Timeline timelineStart = new Timeline(startFrame, moveToBottom, moveToRight);
  16. Timeline timelineRotateBack = new Timeline(rotateBack);
  17. Timeline timelineMoveToTop = new Timeline(moveToTop);
  18. timelineStart.setOnFinished(new EventHandler<ActionEvent>() {
  19. @Override
  20. public void handle(ActionEvent event) {
  21. timelineRotateBack.play();
  22. }
  23. });
  24. timelineRotateBack.setOnFinished(new EventHandler<ActionEvent>() {
  25. @Override
  26. public void handle(ActionEvent event) {
  27. timelineMoveToTop.play();
  28. }
  29. });
  30. timelineStart.play();

字符串
在这里,它将播放所有这些关键帧(startFrame,moveToBottom,moveToRight)第一,当所有动画完成时,它将播放rotateBack KeyFrame,当这一个完成时,它将播放moveToTop

展开查看全部
hmtdttj4

hmtdttj42#

过渡是解决这个问题的好方法

提供了一个基于SequentialTransition而不是Timeline的示例。您可以使用Timeline来代替,正如其他评论或答案中所指出的那样。然而,对于您描述的功能,使用transitions似乎更适合。
该示例对TranslateTransitionRotateTransition类型的各种事务进行排序,以执行所需的动画。
如果您希望部分序列并行执行,那么您可以对这些部分使用ParallelTransition(如果需要,可以组合并行和顺序转换)。

动画使用translate属性

在执行动画时,应该使用translate X/Y/Z属性,而不是layoutX/Y属性。虽然您可以对布局更改进行动画处理,但这是一个高级主题,不建议对JavaFX新手使用。这里提供的示例基于translate属性,而不是layout属性。

选择合适的插值器

关键帧的默认插值器是LINEAR,过渡的默认插值器是EASE_BOTH。通过在关键帧或过渡上设置插值器来选择适合您应用程序的插值器。对于这个例子,我觉得过渡的默认EASE_BOTH插值是最合适的,从而产生更平滑的动画感觉。

示例代码

  1. import javafx.animation.*;
  2. import javafx.application.Application;
  3. import javafx.scene.*;
  4. import javafx.scene.layout.*;
  5. import javafx.scene.paint.Color;
  6. import javafx.scene.shape.Rectangle;
  7. import javafx.stage.Stage;
  8. import javafx.util.Duration;
  9. import java.io.IOException;
  10. public class TransitionApp extends Application {
  11. private static final Color INDIA_INK = Color.web("#3d3f4a");
  12. private static final double W = 400, H = 400;
  13. private static final double BOX_W = 20, BOX_H = 20;
  14. private static final double BOX_TOP_SIDE_INDICATOR_H = 3;
  15. private static final double MOVE_STEP = 50;
  16. private static final Duration TIME_STEP = Duration.seconds(3);
  17. public void start(Stage stage) throws IOException {
  18. Group box = createBox(BOX_W, BOX_H, BOX_TOP_SIDE_INDICATOR_H);
  19. box.setTranslateX(W / 2 - BOX_W / 2);
  20. box.setTranslateY(H / 2 - BOX_H / 2);
  21. Pane root = new Pane(box);
  22. root.setBackground(Background.fill(INDIA_INK));
  23. root.setPrefSize(W, H);
  24. stage.setResizable(false);
  25. stage.setScene(new Scene(root));
  26. stage.show();
  27. SequentialTransition transition = createTransition(box);
  28. transition.play();
  29. }
  30. private SequentialTransition createTransition(Group box) {
  31. TranslateTransition moveToTopLeft = new TranslateTransition(TIME_STEP);
  32. moveToTopLeft.setToX(0);
  33. moveToTopLeft.setToY(0);
  34. TranslateTransition moveToBottom = new TranslateTransition(TIME_STEP.multiply(2));
  35. moveToBottom.setToY(H - BOX_H);
  36. TranslateTransition moveRight = new TranslateTransition(TIME_STEP);
  37. moveRight.setToX(MOVE_STEP);
  38. RotateTransition rotate180 = new RotateTransition(TIME_STEP);
  39. rotate180.setByAngle(180);
  40. TranslateTransition moveToTop = new TranslateTransition(TIME_STEP.multiply(2));
  41. moveToTop.setToY(0);
  42. SequentialTransition sequentialTransition = new SequentialTransition(
  43. box,
  44. moveToTopLeft, moveToBottom, moveRight, rotate180, moveToTop
  45. );
  46. sequentialTransition.setAutoReverse(true);
  47. sequentialTransition.setCycleCount(Transition.INDEFINITE);
  48. return sequentialTransition;
  49. }
  50. private static Group createBox(double w, double h, double topSideIndicatorH) {
  51. Rectangle rectangle = new Rectangle(
  52. w, h, Color.GREEN
  53. );
  54. Rectangle topLine = new Rectangle(
  55. w, topSideIndicatorH, Color.RED
  56. );
  57. return new Group(
  58. rectangle, topLine
  59. );
  60. }
  61. public static void main(String[] args) {
  62. launch(args);
  63. }
  64. }

字符串

展开查看全部

相关问题