原文: http://zetcode.com/gui/javafx/animation/

在本章中,我们将使用 JavaFX 中的动画。 我们使用AnimationTimerTransitionTimeline创建动画。

动画是连续的图像,使人产生了运动的幻觉。 但是,动画不仅限于运动。 随着时间的推移更改节点的背景也被视为动画。

JavaFX 提供了三种创建动画的基本工具:

  • 动画计时器
  • 过渡
  • 时间线

AnimationTimer是创建动画的最简单工具。 这是一个基本计时器。 在动画的每一帧中都会调用其handle()方法。 Transition是定义动画的基本高级框架。 动画由interpolate()方法的frac值控制。 Timeline是用于制作高级动画的最复杂的工具。 Timeline动画由KeyFrames定义,该动画概述了沿Timeline插补的一组变量在指定时间点的节点目标值。 动画属性由KeyValues定义。

动画类

Animation是 JavaFX 中定义高级动画的基本类。 TransitionTimeline都扩展了Animation。 动画以play()playFromStart()方法开始,以stop()方法结束。 可以通过调用pause()方法暂停动画,然后下一个play()调用从暂停的位置继续播放动画。 rate属性定义了预期播放动画的方向和速度。 delay属性指定动画的初始延迟量。 动画可以循环运行; cycleCount属性中定义了循环数,cycleDuration指示了循环的持续时间。 可以使用autoReverseProperty以交替的周期反转动画。

动画计时器

AnimationTimer允许创建一个定时器,该定时器在活动时在每个帧中被调用。 这是一个抽象类; 因此,我们需要创建一个扩展它的自定义类。 在每个帧中调用的handle()方法都必须重写。 AnimationTimerstart()方法启动计时器,stop()方法停止计时器。

AnimationTimerEx.java

  1. package com.zetcode;
  2. import javafx.animation.AnimationTimer;
  3. import javafx.application.Application;
  4. import javafx.scene.Scene;
  5. import javafx.scene.control.Label;
  6. import javafx.scene.layout.StackPane;
  7. import javafx.scene.text.Font;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program uses AnimationTimer to
  13. * create an animation.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class AnimationTimerEx extends Application {
  20. private double opacity = 1;
  21. private Label lbl;
  22. @Override
  23. public void start(Stage stage) {
  24. initUI(stage);
  25. }
  26. private void initUI(Stage stage) {
  27. StackPane root = new StackPane();
  28. lbl = new Label("JavaFX");
  29. lbl.setFont(Font.font(48));
  30. root.getChildren().add(lbl);
  31. AnimationTimer timer = new MyTimer();
  32. timer.start();
  33. Scene scene = new Scene(root, 300, 250);
  34. stage.setTitle("AnimationTimer");
  35. stage.setScene(scene);
  36. stage.show();
  37. }
  38. private class MyTimer extends AnimationTimer {
  39. @Override
  40. public void handle(long now) {
  41. doHandle();
  42. }
  43. private void doHandle() {
  44. opacity -= 0.01;
  45. lbl.opacityProperty().set(opacity);
  46. if (opacity <= 0) {
  47. stop();
  48. System.out.println("Animation stopped");
  49. }
  50. }
  51. }
  52. public static void main(String[] args) {
  53. launch(args);
  54. }
  55. }

该示例使用AnimationTimer在节点上创建淡出效果。

  1. lbl = new Label("JavaFX");
  2. lbl.setFont(Font.font(48));
  3. root.getChildren().add(lbl);

我们的动画更改了此Label控件的属性。

  1. AnimationTimer timer = new MyTimer();
  2. timer.start();

创建一个AnimationTimer并调用其start()方法。

  1. private class MyTimer extends AnimationTimer {
  2. @Override
  3. public void handle(long now) {
  4. doHandle();
  5. }
  6. ...
  7. }

我们创建AnimationTimer的具体子类并覆盖其handle()方法。

  1. private void doHandle() {
  2. opacity -= 0.01;
  3. lbl.opacityProperty().set(opacity);
  4. if (opacity <= 0) {
  5. stop();
  6. System.out.println("Animation stopped");
  7. }
  8. }

doHandle()方法中,我们减小opacity变量并更新opacityProperty。 如果opacity达到最小值,则使用stop()方法停止计时器。

渐隐过渡

Transition动画最适合计划的动画。 Transition具有具体的类,可用于创建可以并行或顺序执行的各种动画; 例如FadeTransitionPathTransitionRotateTransitionScaleTransition

FadeTransition创建一个跨越其持续时间的淡入淡出效果动画。 这是通过定期更新节点的opacity变量来完成的。

FadeTransitionEx.java

  1. package com.zetcode;
  2. import javafx.animation.Animation;
  3. import javafx.animation.FadeTransition;
  4. import javafx.application.Application;
  5. import javafx.event.EventHandler;
  6. import javafx.scene.Group;
  7. import javafx.scene.Scene;
  8. import javafx.scene.input.MouseEvent;
  9. import javafx.scene.shape.Rectangle;
  10. import javafx.stage.Stage;
  11. import javafx.util.Duration;
  12. /**
  13. * ZetCode JavaFX tutorial
  14. *
  15. * This program uses a FadeTransition. A rectangle
  16. * fades out after we click into its area.
  17. *
  18. * Author: Jan Bodnar
  19. * Website: zetcode.com
  20. * Last modified: June 2015
  21. */
  22. public class FadeTransitionEx extends Application {
  23. private FadeTransition ft;
  24. private Rectangle rect;
  25. @Override
  26. public void start(Stage stage) {
  27. initUI(stage);
  28. }
  29. private void initUI(Stage stage) {
  30. Group root = new Group();
  31. rect = new Rectangle(20, 20, 150, 150);
  32. rect.setOnMouseClicked(new RectClickHandler());
  33. ft = new FadeTransition(Duration.millis(5000), rect);
  34. ft.setFromValue(1.0);
  35. ft.setToValue(0.0);
  36. root.getChildren().add(rect);
  37. Scene scene = new Scene(root, 300, 250);
  38. stage.setTitle("Fading transition");
  39. stage.setScene(scene);
  40. stage.show();
  41. }
  42. private class RectClickHandler implements EventHandler<MouseEvent> {
  43. @Override
  44. public void handle(MouseEvent event) {
  45. doHandle();
  46. }
  47. private void doHandle() {
  48. Double opa = rect.getOpacity();
  49. if (opa.intValue() == 0) {
  50. return;
  51. }
  52. Animation.Status as = ft.getStatus();
  53. if (as == Animation.Status.RUNNING) {
  54. return;
  55. }
  56. if (as == Animation.Status.STOPPED) {
  57. ft.play();
  58. }
  59. }
  60. }
  61. public static void main(String[] args) {
  62. Application.launch(args);
  63. }
  64. }

本示例使用FadeTransition在矩形上创建淡出效果。 在矩形区域内单击鼠标后开始动画。

  1. rect = new Rectangle(20, 20, 150, 150);
  2. rect.setOnMouseClicked(new RectClickHandler());

鼠标单击的处理器设置为矩形。

  1. ft = new FadeTransition(Duration.millis(5000), rect);

创建了FadeTransition。 它的第一个参数是过渡的持续时间。 第二个参数是更新其opacity参数的节点。

  1. ft.setFromValue(1.0);
  2. ft.setToValue(0.0);

setFromValue()设置不透明度的开始值,setToValue()设置不透明度的结束值。

  1. Double opa = rect.getOpacity();

当前的不透明度值是通过getOpacity()方法确定的。

  1. if (opa.intValue() == 0) {
  2. return;
  3. }

矩形淡出后,我们取消了鼠标单击。

  1. Animation.Status as = ft.getStatus();
  2. if (as == Animation.Status.RUNNING) {
  3. return;
  4. }
  5. if (as == Animation.Status.STOPPED) {
  6. ft.play();
  7. }

getStatus()方法确定转换的状态。 如果状态为Animation.Status.STOPPED,我们将使用play()方法开始转换。

路径转换

PathTransition沿路径创建动画。 通过更新节点的translateXtranslateY变量来完成沿路径的转换。 请注意,我们必须使用支持元素绝对定位的节点。

PathTransitionEx.java

  1. package com.zetcode;
  2. import javafx.animation.PathTransition;
  3. import javafx.application.Application;
  4. import javafx.scene.Scene;
  5. import javafx.scene.layout.Pane;
  6. import javafx.scene.paint.Color;
  7. import javafx.scene.shape.Circle;
  8. import javafx.scene.shape.CubicCurveTo;
  9. import javafx.scene.shape.MoveTo;
  10. import javafx.scene.shape.Path;
  11. import javafx.stage.Stage;
  12. import javafx.util.Duration;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program uses a PathTransition to move
  17. * a circle along a path.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class PathTransitionEx extends Application {
  24. @Override
  25. public void start(Stage stage) {
  26. initUI(stage);
  27. }
  28. private void initUI(Stage stage) {
  29. Pane root = new Pane();
  30. Path path = new Path();
  31. path.getElements().add(new MoveTo(20, 120));
  32. path.getElements().add(new CubicCurveTo(180, 60, 250, 340, 420, 240));
  33. Circle circle = new Circle(20, 120, 10);
  34. circle.setFill(Color.CADETBLUE);
  35. PathTransition ptr = new PathTransition();
  36. ptr.setDuration(Duration.seconds(6));
  37. ptr.setDelay(Duration.seconds(2));
  38. ptr.setPath(path);
  39. ptr.setNode(circle);
  40. ptr.setCycleCount(2);
  41. ptr.setAutoReverse(true);
  42. ptr.play();
  43. root.getChildren().addAll(path, circle);
  44. Scene scene = new Scene(root, 450, 300);
  45. stage.setTitle("PathTransition");
  46. stage.setScene(scene);
  47. stage.show();
  48. }
  49. public static void main(String[] args) {
  50. launch(args);
  51. }
  52. }

该示例使用PathTransition沿路径移动圆。 动画在初始延迟 2 秒后开始。 它由两个周期组成。 动画受到尊敬; 也就是说,圆从起点到终点再返回。

  1. Pane root = new Pane();

我们使用Pane作为我们的根节点。 它支持动画所需的绝对定位。

  1. Path path = new Path();
  2. path.getElements().add(new MoveTo(20, 120));
  3. path.getElements().add(new CubicCurveTo(180, 60, 250, 340, 420, 240));

在这里,我们定义了动画对象将沿其移动的Path

  1. Circle circle = new Circle(20, 120, 10);
  2. circle.setFill(Color.CADETBLUE);

这个圆是动画中的运动对象。

  1. PathTransition ptr = new PathTransition();

创建一个PathTransition对象。

  1. ptr.setDuration(Duration.seconds(6));

setDuration()方法设置动画的持续时间。

  1. ptr.setDelay(Duration.seconds(2));

setDelay()方法设置动画的初始延迟。

  1. ptr.setPath(path);
  2. ptr.setNode(circle);

setPath()方法设置路径,setNode()设置动画的目标节点。

  1. ptr.setCycleCount(2);

我们的动画有两个循环。 循环次数通过setCycleCount()方法设置。

  1. ptr.setAutoReverse(true);

使用setAutoReverse()方法,我们可以反转动画的方向。 圆会移回到起始位置。

  1. ptr.play();

最后,play()方法开始播放动画。

JavaFX 动画 - 图1

图:PathTransition

并行转换

ParallelTransition并行播放Animations的列表。

ParallelTransitionEx.java

  1. package com.zetcode;
  2. import javafx.animation.FillTransition;
  3. import javafx.animation.ParallelTransition;
  4. import javafx.animation.RotateTransition;
  5. import javafx.animation.ScaleTransition;
  6. import javafx.application.Application;
  7. import javafx.scene.Scene;
  8. import javafx.scene.layout.Pane;
  9. import javafx.scene.paint.Color;
  10. import javafx.scene.shape.Rectangle;
  11. import javafx.stage.Stage;
  12. import javafx.util.Duration;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program creates a parallel
  17. * transition animation.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class ParallelTransitionEx extends Application {
  24. @Override
  25. public void start(Stage stage) {
  26. initUI(stage);
  27. }
  28. private void initUI(Stage stage) {
  29. Pane root = new Pane();
  30. Rectangle rect = new Rectangle(50, 50, 30, 30);
  31. rect.setArcHeight(10);
  32. rect.setArcWidth(10);
  33. rect.setFill(Color.CADETBLUE);
  34. RotateTransition rottr
  35. = new RotateTransition(Duration.millis(2000), rect);
  36. rottr.setByAngle(180);
  37. rottr.setCycleCount(2);
  38. rottr.setAutoReverse(true);
  39. ScaleTransition sctr = new ScaleTransition(Duration.millis(2000),
  40. rect);
  41. sctr.setByX(2);
  42. sctr.setByY(2);
  43. sctr.setCycleCount(2);
  44. sctr.setAutoReverse(true);
  45. FillTransition fltr = new FillTransition(Duration.millis(2000),
  46. rect, Color.CADETBLUE, Color.STEELBLUE);
  47. fltr.setCycleCount(2);
  48. fltr.setAutoReverse(true);
  49. root.getChildren().add(rect);
  50. ParallelTransition ptr = new ParallelTransition();
  51. ptr.getChildren().addAll(rottr, sctr, fltr);
  52. ptr.play();
  53. Scene scene = new Scene(root, 300, 250);
  54. stage.setTitle("ParallelTransition");
  55. stage.setScene(scene);
  56. stage.show();
  57. }
  58. public static void main(String[] args) {
  59. launch(args);
  60. }
  61. }

该示例并行播放三个过渡。 有一个旋转,缩放和背景颜色变化的矩形对象。

  1. RotateTransition rottr
  2. = new RotateTransition(Duration.millis(2000), rect);
  3. rottr.setByAngle(180);
  4. rottr.setCycleCount(2);
  5. rottr.setAutoReverse(true);

RotateTransition将矩形旋转指定角度。 旋转以两个周期发生并反转。

  1. ScaleTransition sctr = new ScaleTransition(Duration.millis(2000),
  2. rect);
  3. sctr.setByX(2);
  4. sctr.setByY(2);

ScaleTransition将矩形放大和缩小 2 倍。

  1. FillTransition fltr = new FillTransition(Duration.millis(2000),
  2. rect, Color.CADETBLUE, Color.STEELBLUE);

FillTransition将矩形的填充颜色从一种颜色值更改为另一种颜色值。

  1. ParallelTransition ptr = new ParallelTransition();
  2. ptr.getChildren().addAll(rottr, sctr, fltr);
  3. ptr.play();

三种类型的过渡放置在ParallelTransition中,它们并行(即同时)播放它们。

顺序转换

SequentialTransition按顺序播放Animations的列表。

SequentialTransitionEx.java

  1. package com.zetcode;
  2. import javafx.animation.FillTransition;
  3. import javafx.animation.RotateTransition;
  4. import javafx.animation.ScaleTransition;
  5. import javafx.animation.SequentialTransition;
  6. import javafx.application.Application;
  7. import javafx.scene.Scene;
  8. import javafx.scene.layout.Pane;
  9. import javafx.scene.paint.Color;
  10. import javafx.scene.shape.Rectangle;
  11. import javafx.stage.Stage;
  12. import javafx.util.Duration;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program plays three transitions in
  17. * a sequential order.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class SequentialTransitionEx extends Application {
  24. @Override
  25. public void start(Stage stage) {
  26. initUI(stage);
  27. }
  28. private void initUI(Stage stage) {
  29. Pane root = new Pane();
  30. Rectangle rect = new Rectangle(50, 50, 30, 30);
  31. rect.setArcHeight(10);
  32. rect.setArcWidth(10);
  33. rect.setFill(Color.CADETBLUE);
  34. RotateTransition rottr
  35. = new RotateTransition(Duration.millis(2000), rect);
  36. rottr.setByAngle(180);
  37. rottr.setCycleCount(2);
  38. rottr.setAutoReverse(true);
  39. ScaleTransition sctr = new ScaleTransition(Duration.millis(2000),
  40. rect);
  41. sctr.setByX(2);
  42. sctr.setByY(2);
  43. sctr.setCycleCount(2);
  44. sctr.setAutoReverse(true);
  45. FillTransition fltr = new FillTransition(Duration.millis(2000),
  46. rect, Color.CADETBLUE, Color.STEELBLUE);
  47. fltr.setCycleCount(2);
  48. fltr.setAutoReverse(true);
  49. root.getChildren().add(rect);
  50. SequentialTransition str = new SequentialTransition();
  51. str.getChildren().addAll(rottr, sctr, fltr);
  52. str.play();
  53. Scene scene = new Scene(root, 300, 250);
  54. stage.setTitle("SequentialTransition");
  55. stage.setScene(scene);
  56. stage.show();
  57. }
  58. public static void main(String[] args) {
  59. launch(args);
  60. }
  61. }

该示例按顺序播放三个过渡-一个接一个。

  1. SequentialTransition str = new SequentialTransition();
  2. str.getChildren().addAll(rottr, sctr, fltr);
  3. str.play();

这三个转换被添加到SequentialTransition中。

时间线

Timeline是使用 JavaFX 创建动画的最复杂的工具。 动画用KeyFrames定义,其中包含更改的节点的属性。 这些属性封装在KeyValues中。 Timeline内插属性的更改。

TimelineEx.java

  1. package com.zetcode;
  2. import javafx.animation.KeyFrame;
  3. import javafx.animation.KeyValue;
  4. import javafx.animation.Timeline;
  5. import javafx.application.Application;
  6. import javafx.scene.Scene;
  7. import javafx.scene.effect.Lighting;
  8. import javafx.scene.layout.Pane;
  9. import javafx.scene.paint.Color;
  10. import javafx.scene.shape.Rectangle;
  11. import javafx.stage.Stage;
  12. import javafx.util.Duration;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program uses a Timeline to
  17. * move a rectangle.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class TimelineEx extends Application {
  24. @Override
  25. public void start(Stage stage) {
  26. initUI(stage);
  27. }
  28. private void initUI(Stage stage) {
  29. Pane root = new Pane();
  30. Rectangle rect = new Rectangle(20, 20, 60, 60);
  31. rect.setEffect(new Lighting());
  32. rect.setFill(Color.CADETBLUE);
  33. Timeline tl = new Timeline();
  34. tl.setCycleCount(2);
  35. tl.setAutoReverse(true);
  36. KeyValue kv = new KeyValue(rect.translateXProperty(), 200);
  37. KeyFrame kf = new KeyFrame(Duration.millis(2000), kv);
  38. tl.getKeyFrames().addAll(kf);
  39. tl.play();
  40. root.getChildren().addAll(rect);
  41. Scene scene = new Scene(root, 350, 250);
  42. stage.setTitle("Timeline");
  43. stage.setScene(scene);
  44. stage.show();
  45. }
  46. public static void main(String[] args) {
  47. launch(args);
  48. }
  49. }

该示例使用Timeline为矩形动画。

  1. Rectangle rect = new Rectangle(20, 20, 60, 60);
  2. rect.setEffect(new Lighting());
  3. rect.setFill(Color.CADETBLUE);

此矩形是动画中的移动对象。

  1. Timeline tl = new Timeline();

创建一个Timeline对象。

  1. tl.setCycleCount(2);
  2. tl.setAutoReverse(true);

动画由两个循环组成,并且被反转。 矩形前后移动。

  1. KeyValue kv = new KeyValue(rect.translateXProperty(), 200);

KeyValue包含translateX属性,该属性会随着时间变化为 200。

  1. KeyFrame kf = new KeyFrame(Duration.millis(2000), kv);

实例化了KeyFrame。 第一个参数是其持续时间,第二个参数是KeyValue。 动画持续 2 秒钟,其translateX属性更改为 200。

  1. tl.getKeyFrames().addAll(kf);

关键帧将添加到帧列表。

顺序时间线动画

我们没有在时间轴中定义所有关键帧。 我们定义一些帧,其余的帧被插值。 关键帧在指定的时间点为时间轴内插的一组变量提供目标值。 为了顺序执行关键帧,我们利用了SequentialTransition类。

SequentialTimelineEx.java

  1. package com.zetcode;
  2. import javafx.animation.KeyFrame;
  3. import javafx.animation.KeyValue;
  4. import javafx.animation.SequentialTransition;
  5. import javafx.animation.Timeline;
  6. import javafx.application.Application;
  7. import javafx.scene.Scene;
  8. import javafx.scene.layout.Pane;
  9. import javafx.scene.paint.Color;
  10. import javafx.scene.shape.Circle;
  11. import javafx.stage.Stage;
  12. import javafx.util.Duration;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program creates a sequential Timeline
  17. * animation.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class SequentialTimelineEx extends Application {
  24. @Override
  25. public void start(Stage stage) {
  26. initUI(stage);
  27. }
  28. private void initUI(Stage stage) {
  29. Pane root = new Pane();
  30. Circle c = new Circle(50, 100, 10);
  31. c.setFill(Color.CADETBLUE);
  32. KeyValue kv1 = new KeyValue(c.scaleXProperty(), 4);
  33. KeyValue kv2 = new KeyValue(c.scaleYProperty(), 4);
  34. KeyFrame kf1 = new KeyFrame(Duration.millis(3000), kv1, kv2);
  35. Timeline scale = new Timeline();
  36. scale.getKeyFrames().add(kf1);
  37. KeyValue kv3 = new KeyValue(c.centerXProperty(), 250);
  38. KeyFrame kf2 = new KeyFrame(Duration.millis(5000), kv3);
  39. Timeline move = new Timeline();
  40. move.getKeyFrames().add(kf2);
  41. KeyValue kv4 = new KeyValue(c.scaleXProperty(), 1);
  42. KeyValue kv5 = new KeyValue(c.scaleYProperty(), 1);
  43. KeyFrame kf3 = new KeyFrame(Duration.millis(3000), kv4, kv5);
  44. Timeline scale2 = new Timeline();
  45. scale2.getKeyFrames().add(kf3);
  46. SequentialTransition seqtr = new SequentialTransition(scale,
  47. move, scale2);
  48. seqtr.play();
  49. root.getChildren().add(c);
  50. Scene scene = new Scene(root, 300, 250);
  51. stage.setTitle("Sequential Timeline animation");
  52. stage.setScene(scene);
  53. stage.show();
  54. }
  55. public static void main(String[] args) {
  56. launch(args);
  57. }
  58. }

该示例创建顺序时间轴动画。 动画由三个Timelines组成,它们与SequentialTransition顺序执行。

  1. Circle c = new Circle(50, 100, 10);
  2. c.setFill(Color.CADETBLUE);

此动画中的移动对象是Circle

  1. KeyValue kv1 = new KeyValue(c.scaleXProperty(), 4);
  2. KeyValue kv2 = new KeyValue(c.scaleYProperty(), 4);
  3. KeyFrame kf1 = new KeyFrame(Duration.millis(3000), kv1, kv2);
  4. Timeline scale = new Timeline();
  5. scale.getKeyFrames().add(kf1);

这是第一个Timeline。 它会在三秒钟的时间内放大圆圈。

  1. KeyValue kv3 = new KeyValue(c.centerXProperty(), 250);
  2. KeyFrame kf2 = new KeyFrame(Duration.millis(5000), kv3);
  3. Timeline move = new Timeline();
  4. move.getKeyFrames().add(kf2);

第二个Timeline将圆圈向前移动。 动画的这一部分持续五秒钟。

  1. KeyValue kv4 = new KeyValue(c.scaleXProperty(), 1);
  2. KeyValue kv5 = new KeyValue(c.scaleYProperty(), 1);
  3. KeyFrame kf3 = new KeyFrame(Duration.millis(3000), kv4, kv5);
  4. Timeline scale2 = new Timeline();
  5. scale2.getKeyFrames().add(kf3);

第三个Timeline按比例缩小圆圈。

  1. SequentialTransition seqtr = new SequentialTransition(scale,
  2. move, scale2);
  3. seqtr.play();

这三个时间线放置在SequentialTransition中。 时间轴依次播放。

在本章中,我们介绍了 JavaFX 动画。