diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/AnimationProducer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/AnimationProducer.java index 0fa2925cf..5611ba16a 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/AnimationProducer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/AnimationProducer.java @@ -18,11 +18,12 @@ package org.jackhuang.hmcl.ui.animation; import javafx.animation.KeyFrame; +import javafx.util.Duration; import java.util.List; -@FunctionalInterface public interface AnimationProducer { + void init(AnimationHandler handler); List animate(AnimationHandler handler); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java index 5c3f977a0..31874beee 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java @@ -20,17 +20,43 @@ package org.jackhuang.hmcl.ui.animation; import javafx.animation.Interpolator; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; +import javafx.scene.Node; import javafx.util.Duration; +import org.jackhuang.hmcl.util.Lang; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; public enum ContainerAnimations { - NONE(c -> Collections.emptyList()), + NONE(c -> { + c.getPreviousNode().setTranslateX(0); + c.getPreviousNode().setTranslateY(0); + c.getPreviousNode().setScaleX(1); + c.getPreviousNode().setScaleY(1); + c.getPreviousNode().setOpacity(1); + c.getCurrentNode().setTranslateX(0); + c.getCurrentNode().setTranslateY(0); + c.getCurrentNode().setScaleX(1); + c.getCurrentNode().setScaleY(1); + c.getCurrentNode().setOpacity(1); + }, c -> Collections.emptyList()), /** * A fade between the old and new view */ - FADE(c -> + FADE(c -> { + c.getPreviousNode().setTranslateX(0); + c.getPreviousNode().setTranslateY(0); + c.getPreviousNode().setScaleX(1); + c.getPreviousNode().setScaleY(1); + c.getCurrentNode().setTranslateX(0); + c.getCurrentNode().setTranslateY(0); + c.getCurrentNode().setScaleX(1); + c.getCurrentNode().setScaleY(1); + }, c -> Arrays.asList(new KeyFrame(Duration.ZERO, new KeyValue(c.getPreviousNode().opacityProperty(), 1.0D, Interpolator.EASE_BOTH), new KeyValue(c.getCurrentNode().opacityProperty(), 0.0D, Interpolator.EASE_BOTH)), @@ -40,7 +66,12 @@ public enum ContainerAnimations { /** * A zoom effect */ - ZOOM_IN(c -> + ZOOM_IN(c -> { + c.getPreviousNode().setTranslateX(0); + c.getPreviousNode().setTranslateY(0); + c.getCurrentNode().setTranslateX(0); + c.getCurrentNode().setTranslateY(0); + }, c -> Arrays.asList(new KeyFrame(Duration.ZERO, new KeyValue(c.getPreviousNode().scaleXProperty(), 1, Interpolator.EASE_BOTH), new KeyValue(c.getPreviousNode().scaleYProperty(), 1, Interpolator.EASE_BOTH), @@ -52,7 +83,12 @@ public enum ContainerAnimations { /** * A zoom effect */ - ZOOM_OUT(c -> + ZOOM_OUT(c -> { + c.getPreviousNode().setTranslateX(0); + c.getPreviousNode().setTranslateY(0); + c.getCurrentNode().setTranslateX(0); + c.getCurrentNode().setTranslateY(0); + }, c -> (Arrays.asList(new KeyFrame(Duration.ZERO, new KeyValue(c.getPreviousNode().scaleXProperty(), 1, Interpolator.EASE_BOTH), new KeyValue(c.getPreviousNode().scaleYProperty(), 1, Interpolator.EASE_BOTH), @@ -64,7 +100,14 @@ public enum ContainerAnimations { /** * A swipe effect */ - SWIPE_LEFT(c -> + SWIPE_LEFT(c -> { + c.getPreviousNode().setScaleX(1); + c.getPreviousNode().setScaleY(1); + c.getPreviousNode().setOpacity(0); + c.getCurrentNode().setScaleX(1); + c.getCurrentNode().setScaleY(1); + c.getCurrentNode().setOpacity(1); + }, c -> Arrays.asList(new KeyFrame(Duration.ZERO, new KeyValue(c.getCurrentNode().translateXProperty(), c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH), new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH)), @@ -75,7 +118,14 @@ public enum ContainerAnimations { /** * A swipe effect */ - SWIPE_RIGHT(c -> + SWIPE_RIGHT(c -> { + c.getPreviousNode().setScaleX(1); + c.getPreviousNode().setScaleY(1); + c.getPreviousNode().setOpacity(0); + c.getCurrentNode().setScaleX(1); + c.getCurrentNode().setScaleY(1); + c.getCurrentNode().setOpacity(1); + }, c -> Arrays.asList(new KeyFrame(Duration.ZERO, new KeyValue(c.getCurrentNode().translateXProperty(), -c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH), new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH)), @@ -85,8 +135,18 @@ public enum ContainerAnimations { private final AnimationProducer animationProducer; - ContainerAnimations(AnimationProducer animationProducer) { - this.animationProducer = animationProducer; + ContainerAnimations(Consumer init, Function> animationProducer) { + this.animationProducer = new AnimationProducer() { + @Override + public void init(AnimationHandler handler) { + init.accept(handler); + } + + @Override + public List animate(AnimationHandler handler) { + return animationProducer.apply(handler); + } + }; } public AnimationProducer getAnimationProducer() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/TransitionHandler.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/TransitionHandler.java index 7a0fd8804..cec4a9d47 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/TransitionHandler.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/TransitionHandler.java @@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; +import javafx.application.Platform; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.layout.StackPane; @@ -78,14 +79,19 @@ public final class TransitionHandler implements AnimationHandler { updateContent(newView); - Timeline nowAnimation = new Timeline(); - nowAnimation.getKeyFrames().addAll(transition.animate(this)); - nowAnimation.getKeyFrames().add(new KeyFrame(duration, e -> { - previousNode.setMouseTransparent((Boolean) previousNode.getProperties().get(MOUSE_TRANSPARENT)); - view.getChildren().remove(previousNode); - })); - nowAnimation.play(); - animation = nowAnimation; + transition.init(this); + + // runLater or "init" will not work + Platform.runLater(() -> { + Timeline nowAnimation = new Timeline(); + nowAnimation.getKeyFrames().addAll(transition.animate(this)); + nowAnimation.getKeyFrames().add(new KeyFrame(duration, e -> { + previousNode.setMouseTransparent((Boolean) previousNode.getProperties().get(MOUSE_TRANSPARENT)); + view.getChildren().remove(previousNode); + })); + nowAnimation.play(); + animation = nowAnimation; + }); } private void updateContent(Node newView) {