Animation 关键帧之间的JavaFx动画延迟

Animation 关键帧之间的JavaFx动画延迟,animation,javafx,delay,Animation,Javafx,Delay,我有一个小代码片段,用于启动场景之间转换的动画: static void initClosingAnimation() { ObservableList<Node> components = window.getScene().getRoot().getChildrenUnmodifiable(); time = new Timeline(); for (Node component : components) { KeyValue

我有一个小代码片段,用于启动场景之间转换的动画:

static void initClosingAnimation() {
    ObservableList<Node> components = window.getScene().getRoot().getChildrenUnmodifiable();
    time = new Timeline();
    
    for (Node component : components) {
        KeyValue keyvalue = new KeyValue(component.translateXProperty(), window.getWidth(), Interpolator.EASE_OUT);
        KeyFrame keyframe = new KeyFrame(Duration.seconds(0.4), keyvalue);
        time.getKeyFrames().add(keyframe);
    }
    time.play();
}
static void initclosinganization(){
ObservableList components=window.getScene().getRoot().getChildrenUnmodifiable();
时间=新的时间线();
用于(节点组件:组件){
KeyValue KeyValue=新的KeyValue(component.translateProperty()、window.getWidth()、Interpolator.EASE\u OUT);
关键帧=新关键帧(持续时间。秒(0.4),keyvalue);
time.getKeyFrames().add(关键帧);
}
时间。玩();
}
该代码从场景中获取所有现有组件,然后向每个组件添加一个单独的关键帧,以创建从左到右的过渡。然而,通过这种方式,每一个组件都在同一时间移动,这不是我对这个函数的想法


是否有一种干净的方法在每个关键帧之间添加一个小的延迟,以便每个组件一个接一个地淡出,或者这是我所想到的方法吗?

只需为每个组件使用不同的时间点:

void initClosingAnimation() {
    ObservableList<Node> components = window.getScene().getRoot().getChildrenUnmodifiable();
    time = new Timeline();

    Duration startTime = Duration.ZERO ;
    Duration endTime = Duration.seconds(0.4);

    Duration offset = Duration.seconds(0.1);
    
    for (Node component : components) {
        KeyValue startValue = new KeyValue(component.translateXProperty(), component.getTranslateX(), Interpolator.EASE_OUT);
        KeyValue endValue = new KeyValue(component.translateXProperty(), window.getWidth(), Interpolator.EASE_OUT);
        KeyFrame start = new KeyFrame(startTime, startValue);
        KeyFrame end = new KeyFrame(endTime, endValue);
        time.getKeyFrames().add(start);
        time.getKeyFrames().add(end);
        startTime = startTime.add(offset);
        endTime = endTime.add(offset);
    }
    time.play();
}
void initclosinganization(){
ObservableList components=window.getScene().getRoot().getChildrenUnmodifiable();
时间=新的时间线();
持续时间开始时间=持续时间.0;
持续时间endTime=持续时间秒(0.4);
持续时间偏移=持续时间秒(0.1);
用于(节点组件:组件){
KeyValue startValue=新的KeyValue(component.translateProperty(),component.getTranslateX(),Interpolator.EASE_OUT);
KeyValue endValue=新的KeyValue(component.TranslateProperty()、window.getWidth()、Interpolator.EASE\u OUT);
关键帧开始=新关键帧(开始时间,开始值);
关键帧结束=新关键帧(结束时间,结束值);
time.getKeyFrames().add(开始);
time.getKeyFrames().add(结束);
startTime=startTime.add(偏移量);
endTime=endTime.add(偏移量);
}
时间。玩();
}
下面是一个完整的示例(对上面的方法签名稍作修改):

导入javafx.animation.Interpolator;
导入javafx.animation.KeyFrame;
导入javafx.animation.KeyValue;
导入javafx.animation.Timeline;
导入javafx.application.application;
导入javafx.collections.ObservableList;
导入javafx.geometry.Pos;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
导入javafx.stage.Window;
导入javafx.util.Duration;
公共类应用程序扩展应用程序{
@凌驾
公众假期开始(阶段){
VBox根=新的VBox(5);
根部设置对齐(位置中心);
for(inti=1;i初始化信号(stage,stage::hide));
场景=新场景(根,400600);
舞台场景;
stage.setOnCloseRequest(e->{
初始化(stage,stage::hide);
e、 消费();
});
stage.show();
}
私有void initclosinganization(窗口窗口,可运行未完成){
ObservableList components=window.getScene().getRoot().getChildrenUnmodifiable();
时间线时间=新时间线();
持续时间开始时间=持续时间.0;
持续时间endTime=持续时间秒(0.4);
持续时间偏移=持续时间秒(0.1);
用于(节点组件:组件){
KeyValue startValue=新的KeyValue(component.translateProperty(),component.getTranslateX(),Interpolator.EASE_OUT);
KeyValue endValue=新的KeyValue(component.TranslateProperty()、window.getWidth()、Interpolator.EASE\u OUT);
关键帧开始=新关键帧(开始时间,开始值);
关键帧结束=新关键帧(结束时间,结束值);
time.getKeyFrames().add(开始);
time.getKeyFrames().add(结束);
startTime=startTime.add(偏移量);
endTime=endTime.add(偏移量);
}
time.setOnFinished(e->onFinished.run());
时间。玩();
}
公共静态void main(字符串[]args){
发射();
}
}

只需为每个
关键帧使用不同的时间点(由
持续时间表示)
。以前尝试过,但不起作用。“不起作用”不是很有帮助。它应该运作良好;如果建议的解决方案不起作用,请发布一条消息,并准确地解释出现了什么问题。我的意思是,我在每次for循环运行结束时添加了一个float变量作为持续时间的参数,但由于某些原因,这并没有解决问题。请注意您的语句“代码从场景中获取所有现有组件”这不一定是真的。它只需要根的直接子节点。会在这里和那里调整一些值,但很有帮助!
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.util.Duration;


public class App extends Application {

    @Override
    public void start(Stage stage) {
        VBox root = new VBox(5);
        root.setAlignment(Pos.CENTER);
        for (int i = 1 ; i <= 10 ; i++) root.getChildren().add(new Label("Item "+i));
        Button close = new Button("Close");
        root.getChildren().add(close);
        close.setOnAction(e -> initClosingAnimation(stage, stage::hide));
        Scene scene = new Scene(root, 400, 600);
        stage.setScene(scene);
    
        stage.setOnCloseRequest(e -> {
            initClosingAnimation(stage, stage::hide);
            e.consume();
        });
    
        stage.show();
    }
    
    private void initClosingAnimation(Window window, Runnable onFinished) {
        ObservableList<Node> components = window.getScene().getRoot().getChildrenUnmodifiable();
        Timeline time = new Timeline();

        Duration startTime = Duration.ZERO ;
        Duration endTime = Duration.seconds(0.4);

        Duration offset = Duration.seconds(0.1);
        
        for (Node component : components) {
            KeyValue startValue = new KeyValue(component.translateXProperty(), component.getTranslateX(), Interpolator.EASE_OUT);
            KeyValue endValue = new KeyValue(component.translateXProperty(), window.getWidth(), Interpolator.EASE_OUT);
            KeyFrame start = new KeyFrame(startTime, startValue);
            KeyFrame end = new KeyFrame(endTime, endValue);
            time.getKeyFrames().add(start);
            time.getKeyFrames().add(end);
            startTime = startTime.add(offset);
            endTime = endTime.add(offset);
        }
        time.setOnFinished(e -> onFinished.run());
        time.play();
    }

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

}