package tray.animations;
import javafx.animation.*;
import javafx.util.Duration;
import tray.models.CustomStage;
public class SlideAnimation implements TrayAnimation {
private final Timeline showAnimation, dismissAnimation;
private final SequentialTransition sq;
private final CustomStage stage;
private boolean trayIsShowing;
public SlideAnimation(CustomStage customStage) {
this.stage = customStage;
showAnimation = setupShowAnimation();
dismissAnimation = setupDismissAnimation();
//It wouldn't allow me to play embedded animations so I had to create two separate
//Instances so I could play sequentially and individually.
sq = new SequentialTransition(setupShowAnimation(), setupDismissAnimation());
}
private Timeline setupShowAnimation() {
Timeline tl = new Timeline();
//Sets the x location of the tray off the screen
double offScreenX = stage.getOffScreenBounds().getX();
KeyValue kvX = new KeyValue(stage.xLocationProperty(), offScreenX);
KeyFrame frame1 = new KeyFrame(Duration.ZERO, kvX);
//Animates the Tray onto the screen and interpolates at a tangent for 300 millis
Interpolator interpolator = Interpolator.TANGENT(Duration.millis(300), 50);
KeyValue kvInter = new KeyValue(stage.xLocationProperty(), stage.getBottomRight().getX(), interpolator);
KeyFrame frame2 = new KeyFrame(Duration.millis(1300), kvInter);
//Sets opacity to 0 instantly
KeyValue kvOpacity = new KeyValue(stage.opacityProperty(), 0.0);
KeyFrame frame3 = new KeyFrame(Duration.ZERO, kvOpacity);
//Increases the opacity to fully visible whilst moving in the space of 1000 millis
KeyValue kvOpacity2 = new KeyValue(stage.opacityProperty(), 1.0);
KeyFrame frame4 = new KeyFrame(Duration.millis(1000), kvOpacity2);
tl.getKeyFrames().addAll(frame1, frame2, frame3, frame4);
tl.setOnFinished(e -> trayIsShowing = true);
return tl;
}
private Timeline setupDismissAnimation() {
Timeline tl = new Timeline();
double offScreenX = stage.getOffScreenBounds().getX();
Interpolator interpolator = Interpolator.TANGENT(Duration.millis(300), 50);
double trayPadding = 3;
//The destination X location for the stage. Which is off the users screen
//Since the tray has some padding, we want to hide that too
KeyValue kvX = new KeyValue(stage.xLocationProperty(), offScreenX + trayPadding, interpolator);
KeyFrame frame1 = new KeyFrame(Duration.millis(1400), kvX);
//Change the opacity level to 0.4 over the duration of 2000 millis
KeyValue kvOpacity = new KeyValue(stage.opacityProperty(), 0.4);
KeyFrame frame2 = new KeyFrame(Duration.millis(2000), kvOpacity);
tl.getKeyFrames().addAll(frame1, frame2);
tl.setOnFinished(e -> {
trayIsShowing = false;
stage.close();
stage.setLocation(stage.getBottomRight());
});
return tl;
}
/**
* The type of animation this class plays
*
* @return The type of animation this class plays
*/
@Override
public AnimationType getAnimationType() {
return AnimationType.SLIDE;
}
/**
* Plays both the show and dismiss animation using a sequential transition object
*
* @param dismissDelay How long to delay the start of the dismiss animation
*/
@Override
public void playSequential(Duration dismissDelay) {
sq.getChildren().get(1).setDelay(dismissDelay);
sq.play();
}
/**
* Plays the implemented show animation
*/
@Override
public void playShowAnimation() {
showAnimation.play();
}
/**
* Plays the implemented dismiss animation
*/
@Override
public void playDismissAnimation() {
dismissAnimation.play();
}
/**
* Signifies if the tray is current showing
*
* @return boolean resultant
*/
@Override
public boolean isShowing() {
return trayIsShowing;
}
}