首页 > 解决方案 > 完成后如何反转动画?

问题描述

我有一个动画列表,我希望能够通过单击“下一个”按钮来播放它们,并通过单击“上一个”按钮来播放它们。所以我可以播放第一个动画,然后播放第二个动画,然后向后播放第二个动画,并到达仅播放第一个动画后的位置。

我的问题是动画完成后我无法反转动画。我知道我可以设置autoReverse,但是每个动画都会立即反转。

这是一个动画的示例:

import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AnimTest extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Circle c = new Circle(5, Color.RED);
        TranslateTransition move = new TranslateTransition(Duration.seconds(2), c);
        move.setByX(10);
        move.setByY(10);

        Button next = new Button("Next");
        Button previous = new Button("Previous");
        next.setOnAction(e -> {
            move.setRate(1);
            move.play();
        });
        previous.setOnAction(e -> {
            move.setRate(-1);
            move.play();
        });

        Pane p = new Pane(c);
        p.setPrefSize(50, 50);
        HBox buttons = new HBox(next, previous);
        VBox root = new VBox(p, buttons);
        stage.setScene(new Scene(root));
        stage.show();
    }

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

按下“下一个”后,我希望“上一个”将球移回其原始位置(有效地 x x -10 和 y x -10),而不是反向播放“跟随”动画。

在实践中,我的动画为场景图中的不同对象设置动画,它们可以是并行/顺序转换。对于列表,我保留当前位置索引i并执行以下操作:

    next.setOnAction(e -> {
        Animation move = list.get(i);
        move.setRate(1);
        move.play();
        i++;
    });
    previous.setOnAction(e -> {
        i--;
        Animation move = list.get(i);
        move.setRate(-1);
        move.play();
    });

试图反转之前的动画。

我怎样才能做到这一点?

澄清一下,我的清单是Animation. 这TranslateTransition只是一个例子。

标签: javaanimationjavafx

解决方案


这里的问题是使用“相对”运动而不是绝对运动。

如果您设置byX = 10动画在向前播放时将节点 10 向右移动,这意味着反转动画的正确方法是立即将节点放置在结束位置,然后在开始动画之前将节点移回原始位置。

由于您不想一遍又一遍地使用相同的动画,因此对于使用“相对”值的动画来说,找到反转不同动画的正确方法可能很困难。如果您改为使用绝对动画,则不应简单地向后播放动画,这不会引起任何问题。

例子

@Override
public void start(Stage stage) {
    Circle c = new Circle(5, Color.RED);

    // create alternating right/down movement animations with absolute movement
    List<Animation> animations = new ArrayList<>(10);
    for (int i = 0; i < 10; i++) {
        TranslateTransition move = new TranslateTransition(Duration.seconds(1), c);
        animations.add(move);
        int step = i >> 1;
        if ((i & 1) == 0) {
            move.setFromX(step * 10);
            move.setToX((step + 1) * 10);
        } else {
            move.setFromY(step * 10);
            move.setToY((step + 1) * 10);
        }
    }

    final ListIterator<Animation> iterator = animations.listIterator();
    
    Button next = new Button("Next");
    Button previous = new Button("Previous");
    previous.setDisable(true);
    
    next.setOnAction(e -> {
        Animation move = iterator.next();
        
        next.setDisable(!iterator.hasNext());
        previous.setDisable(false);
        
        move.setRate(1);
        move.play();
    });
    
    previous.setOnAction(e -> {
        Animation move = iterator.previous();
        
        next.setDisable(false);
        previous.setDisable(!iterator.hasPrevious());
        
        move.setRate(-1);
        move.play();
    });

    Pane p = new Pane(c);
    p.setPrefSize(100, 100);
    HBox buttons = new HBox(next, previous);
    VBox root = new VBox(p, buttons);
    stage.setScene(new Scene(root));
    stage.show();
}

推荐阅读