java - SequentialTransition 内 javafx 中的反向转换
问题描述
给定一个我想反向播放的过渡 t,我使用代码
t.jumpTo(t.getTotalDuration());
t.setRate(-1);
这意味着我跳到过渡的末尾并向后播放。我的问题是,如果我将此转换作为顺序或并行转换的一部分播放,那么它将速率更改为其绝对值,因此它会向前播放。有没有办法“真正”反转转换,即获得一个新的转换,但速率 = 1,所以它在顺序和并行转换中仍然是反向的?
解决方案
对于过渡,这很简单:只需使用Interpolator
返回值的a 1-fraction
:
public class ReverseInterpolator extends Interpolator {
private final Interpolator reverse;
public ReverseInterpolator(Interpolator reverse) {
if (reverse == null) {
throw new IllegalArgumentException();
}
this.reverse = reverse;
}
@Override
protected double curve(double t) {
return reverse.interpolate(0d, 1d, 1 - t);
}
public static Interpolator reverse(Interpolator interpolator) {
return (interpolator instanceof ReverseInterpolator)
? ((ReverseInterpolator) interpolator).reverse
: new ReverseInterpolator(interpolator);
}
}
@Override
public void start(Stage primaryStage) throws Exception {
Rectangle rect1 = new Rectangle(0, 0, 100, 100);
rect1.setFill(Color.RED);
Rectangle rect2 = new Rectangle(0, 200, 100, 100);
rect2.setFill(Color.BLUE);
Pane root = new Pane(rect1, rect2);
TranslateTransition transition1 = new TranslateTransition(Duration.seconds(2), rect1);
transition1.setFromX(0);
transition1.setToX(400);
TranslateTransition transition2 = new TranslateTransition(Duration.seconds(2), rect2);
transition2.setFromX(0);
transition2.setToX(400);
ParallelTransition transition = new ParallelTransition(transition1, transition2);
transition.setOnFinished(evt -> {
transition2.setInterpolator(ReverseInterpolator.reverse(transition2.getInterpolator()));
transition.play();
});
transition.play();
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
对于general Animation
s,这有点棘手。您可以编写一个Transition
在每一帧上设置动画时间的代码:
public class AnimationTransition extends Transition {
private final Animation animation;
public AnimationTransition(Animation animation) {
this.animation = animation;
setInterpolator(Interpolator.LINEAR);
setCycleDuration(animation.getCycleDuration());
setCycleCount(animation.getCycleCount());
statusProperty().addListener((o, oldValue, newValue) -> {
switch(newValue) {
case PAUSED:
animation.pause();
break;
case STOPPED:
animation.stop();
}
});
// don't actually procede except for playfrom calls
animation.setRate(0);
}
@Override
protected void interpolate(double frac) {
animation.playFrom(animation.getCycleDuration().multiply(frac));
}
}
@Override
public void start(Stage primaryStage) throws Exception {
Rectangle rect1 = new Rectangle(0, 0, 100, 100);
rect1.setFill(Color.RED);
Rectangle rect2 = new Rectangle(0, 200, 100, 100);
rect2.setFill(Color.BLUE);
Pane root = new Pane(rect1, rect2);
TranslateTransition transition1 = new TranslateTransition(Duration.seconds(2), rect1);
transition1.setFromX(0);
transition1.setToX(400);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rect2.translateXProperty(), 0d)),
new KeyFrame(Duration.seconds(2), new KeyValue(rect2.translateXProperty(), 400d))
);
AnimationTransition transition2 = new AnimationTransition(timeline);
ParallelTransition transition = new ParallelTransition(transition1, transition2);
transition.setOnFinished(evt -> {
transition2.setInterpolator(ReverseInterpolator.reverse(transition2.getInterpolator()));
transition.play();
});
transition.play();
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
推荐阅读
- jpa - 为什么 JPA 重复持久方法不抛出异常?
- python - 函数不传递通过“for”循环接收到的值
- sql - 如何使用 SQL 按另一列中的值聚合一列中的数据
- image - 如何使用 Python 去除数字文本图像上的手写标记
- hive - 我安装了 Hadoop 3.2.0。和 Hive 并出现以下错误
- ruby-on-rails - 即使创建了带有参数的@user,也无法找到没有 ID 的用户
- wpf - 基于标准的点网(wpf)中两个网格的一对多映射
- centos - 如何修复 CentOS 上 Vysor 的插件问题
- javascript - 为什么我的变量在浏览器中不起作用,如何使它们成为全局变量?
- c# - 列出根目录下的所有文件