2 Replies Latest reply on Nov 26, 2013 7:21 PM by 2e9863d8-7212-45ad-9506-dcdcd9cf9079

    Reverse animation/transition on event


      So I'm having a bit of issue getting an animation of mine to behave the way I want. My intent is to have an animation start on a button press (or any given event), play till its end, and then reverse once the button is released (which could happen in the middle of the animation, in which case the node should animate back to it's start position).


      I originally tried doing this with just the RotateTransition class (since that's the type of animation I'm doing), but couldn't get the behavior described above, so I started messing around with a Timeline.


      This is what I have so far, and works great for releasing before the animation completes, but I can't get the node to animate back to it's original position after it's completed. I can't seem figure out the right combination of setting the CycleCount, AutoReverseProperty, pausing/playing or whether or not I need multiple KeyFrames to express the different parts of the animation.


      SVGPath someNode = new SVGPath(); // The node I'm animating
      Timeline rotateTimeline= new Timeline();
      rotateTimeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000), new KeyValue(someNode.rotateProperty(), -50));
      // Events that start/stop the animation -- please ignore the keyCode conditionals as I might have them wrong...just typing them up on the fly as an example
      this.setOnKeyPressed(keyEvent -> {
          if(keyEvent.getCode() == KeyCode.ENTER) {
              someNode.getStyleClass().add("pressed"); // Is there a way to toggle style classes instead of having to add/remove them?
      this.setOnKeyReleased(keyEvent -> {
          if(keyEvent.getCode() == KeyCode.ENTER) {
              // This is where I tried all sorts of things, like setting autoreverse to be true, then playing the
       // timeline again, having two keyframes and pausing after the first is met and resuming here, and nothing seems to be working for me... 

      And not to bundle too many questions into a single thread, but is there any way to edit my forum name? I went to my profile prefs, and the text box to update my forum handle is grayed out... (e.g. http://i.imgur.com/5agcHja.png)

        • 1. Re: Reverse animation/transition on event

          I would initialize the forward and reverse rotations as independent rotations. Start the forward rotation on the key down, and stop it on the key up. Listen to the status of the forward rotation and start the reverse rotation when the forward one stops. (This will reverse the forward rotation either if the key is released or if the rotation reaches its end.)


          This uses a mouse for simplicity but the idea is the same:


          import javafx.animation.RotateTransition;
          import javafx.animation.Animation;
          import javafx.application.Application;
          import javafx.scene.Scene;
          import javafx.scene.layout.Pane;
          import javafx.scene.paint.Color;
          import javafx.scene.shape.Rectangle;
          import javafx.stage.Stage;
          import javafx.util.Duration;
          public class ReversableRotationTest extends Application {
            public void start(Stage primaryStage) {
            final Rectangle rect = new Rectangle(50, 150, 250, 150);
            final Pane root = new Pane();
            final RotateTransition forwardRotation = new RotateTransition(Duration.seconds(1), rect);
                  final RotateTransition reverseRotation = new RotateTransition();
                  // make the duration of the reverse rotation the same as the progress of the forward rotation:
                  // start forward rotation when mouse is pressed
                  root.setOnMousePressed(mouseEvent -> forwardRotation.playFromStart() );
                  // stop forward rotation when mouse released
            root.setOnMouseReleased(mouseEvent -> forwardRotation.stop() );
            // start reverse rotation when forward stops
            forwardRotation.statusProperty().addListener((obs, oldValue, newValue) -> {
                if (newValue == Animation.Status.STOPPED)
            Scene scene = new Scene(root, 400, 400);
            public static void main(String[] args) {
          • 2. Re: Reverse animation/transition on event

            Thanks James -- just what I was looking for!


            The only difference for my application is to start the reverse animation only on mouseRelease (not on the end of the forward animation), but that's easy enough.  Thanks again!