同步动画的最佳方法

时间:2019-09-02 21:29:26

标签: java animation javafx synchronization

public class App extends javafx.application.Application {

    @Override
    public void start(Stage primaryStage) {
        var root = new Pane();
        var button = new Button("Change");
        button.setLayoutX(225);
        button.setLayoutY(300);
        var rectangle = new Rectangle(150, 50, 200, 200);
        var effect = new BoxBlur(0, 0, 1);
        var text = new Text("POKUS");
        text.setLayoutX(230);
        text.setLayoutY(270);
        text.setEffect(effect);
        button.setOnMouseClicked((event) -> {
            event.consume();
            var random = new Random();
            var fill = new FillTransition(Duration.seconds(1), rectangle, (Color) rectangle.getFill(), Color.color(random.nextFloat(), random.nextFloat(), random.nextFloat()));
            var timeline = new Timeline(
                    new KeyFrame(Duration.millis(500),
                            new KeyValue(effect.widthProperty(), 10),
                            new KeyValue(effect.heightProperty(), 10)
                    )
            );
            var timeline2 = new Timeline(
                    new KeyFrame(Duration.millis(500),
                            new KeyValue(effect.widthProperty(), 0),
                            new KeyValue(effect.heightProperty(), 0)
                    )
            );
            timeline.setOnFinished((event2) -> {
                var number = random.nextInt(10) + 1;
                var word = "";
                for (var i = 0; i < number; i++) {
                    word += (char) ('a' + random.nextInt(26));
                }
                text.setText(word);
                text.setEffect(effect);
                timeline2.play();
            });
            new ParallelTransition(fill, timeline).play();
        });
        root.getChildren().addAll(button, rectangle, text);
        var scene = new Scene(root, 500, 500);
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

}

这证明了我的问题。

程序仅包含一个矩形,文本和一个按钮,该按钮运行矩形和文本的颜色变化的动画-在两种情况下都是随机的。

但是,矩形动画需要一秒钟,而文本动画则需要两次半秒。

此外,在第一个文本动画的结尾,必须生成文本。

差异可能会很小,但是我想问一下是否可以将第二个文本动画(timeline2)的时间调整为与矩形动画({{1 }})?

请帮助

谢谢

1 个答案:

答案 0 :(得分:2)

您可以使用Timelinefill属性设置动画。此外,您不需要使用多个时间轴来制作所有动画:

button.setOnAction((event) -> { // better to use ActionEvent to listen to button activation
    event.consume();
    var random = new Random();
    Color currentColor = (Color) rectangle.getFill();
    Color targetColor = Color.color(random.nextFloat(), random.nextFloat(), random.nextFloat());

    var timeline = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(rectangle.fillProperty(), currentColor)),
            new KeyFrame(Duration.millis(500),
                    evt -> {
                        var number = random.nextInt(10) + 1;
                        var word = "";
                        for (var i = 0; i < number; i++) {
                            word += (char) ('a' + random.nextInt(26));
                        }
                        text.setText(word);
                    },
                    new KeyValue(effect.widthProperty(), 10),
                    new KeyValue(effect.heightProperty(), 10)
            ), new KeyFrame(Duration.millis(1000),
                    new KeyValue(effect.widthProperty(), 0),
                    new KeyValue(effect.heightProperty(), 0),
                    new KeyValue(rectangle.fillProperty(), targetColor)
            )
    );
    timeline.play();
});