Serial animation in TornadoFX?

After reading the documentation, I was still a bit confused about how to perform the animation after completing another. I have a timeline like this:

timeline {
  keyframe(Duration.seconds(0.5)) {
    keyvalue(firstImg.scaleXProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(firstImg.scaleYProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(firstImg.rotateProperty(), 0.0, interpolator = Interpolator.EASE_BOTH)
  }

  keyframe(Duration.seconds(0.5)) {
    keyvalue(secondImg.scaleXProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(secondImg.scaleYProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(secondImg.rotateProperty(), 0.0, interpolator = Interpolator.EASE_BOTH)
  }

  keyframe(Duration.seconds(0.5)) {
    keyvalue(thirdImg.scaleXProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(thirdImg.scaleYProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(thirdImg.rotateProperty(), 0.0, interpolator = Interpolator.EASE_BOTH)
  }

  keyframe(Duration.seconds(0.5)) {
    keyvalue(fourthImg.scaleXProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(fourthImg.scaleYProperty(), 1.0, interpolator = Interpolator.EASE_BOTH)
    keyvalue(fourthImg.rotateProperty(), 0.0, interpolator = Interpolator.EASE_BOTH)
  }
}

This launches them all at once, but I would like to start each animation after the completion of the other! I can’t figure out how to do this .. (sorry if this is obvious, I am very new to Kotlin and Java in general!)

I see that the keyframe has a property onFinished, but I can’t understand what I should have installed it on. Is there a better way to do this? Thank!

+4
source share
3 answers

JavaFX "SequentialTransition", . TornadoFX , . ParallelTransition, , .

class STTest : View("My View") {

    val r1 = Rectangle(20.0, 20.0, Color.RED)
    val r2 = Rectangle(20.0, 20.0, Color.YELLOW)
    val r3 = Rectangle(20.0, 20.0, Color.GREEN)
    val r4 = Rectangle(20.0, 20.0, Color.BLUE)

    override val root = vbox {

        button("Animate") {
            setOnAction {

                val t1 = timeline(false) {
                    keyframe(Duration.seconds(0.5)) {
                        keyvalue(r1.translateXProperty(), 50.0, interpolator = Interpolator.EASE_BOTH)
                    }
                }
                val t2 = timeline(false) {
                    keyframe(Duration.seconds(0.5)) {
                        keyvalue(r2.translateXProperty(), 100.0, interpolator = Interpolator.EASE_BOTH)
                    }
                }
                val t3 = timeline(false) {
                    keyframe(Duration.seconds(0.5)) {
                        keyvalue(r3.translateXProperty(), 150.0, interpolator = Interpolator.EASE_BOTH)
                    }
                }
                val t4 = timeline(false) {
                    keyframe(Duration.seconds(0.5)) {
                        keyvalue(r4.translateXProperty(), 200.0, interpolator = Interpolator.EASE_BOTH)
                    }
                }

                /* functions look better
                val st = SequentialTransition()
                st.children += t1
                st.children += t2
                st.children += t3
                st.children += t4

                st.play()
                */  

                t1.then(t2).then(t3).then(t4).play()

            }
        }
        pane {
            add(r1)
            add(r2)
            add(r3)
            add(r4)
        }
    }

}
+3

, @tornadofx-fan, , , TornadoFX 1.7.9, :

class TransitionViews: View() {
   val r1 = Rectangle(20.0, 20.0, Color.RED)
   val r2 = Rectangle(20.0, 20.0, Color.YELLOW)
   val r3 = Rectangle(20.0, 20.0, Color.GREEN)
   val r4 = Rectangle(20.0, 20.0, Color.BLUE)

   override val root = vbox {
       button("Animate").action {
           sequentialTransition {
               timeline {
                   keyframe(0.5.seconds) {
                       keyvalue(r1.translateXProperty(), 50.0, interpolator = Interpolator.EASE_BOTH)
                   }
               }
               timeline {
                   keyframe(0.5.seconds) {
                       keyvalue(r2.translateXProperty(), 100.0, interpolator = Interpolator.EASE_BOTH)
                   }
               }
               timeline {
                   keyframe(0.5.seconds) {
                       keyvalue(r3.translateXProperty(), 150.0, interpolator = Interpolator.EASE_BOTH)
                   }
               }
               timeline {
                   keyframe(0.5.seconds) {
                       keyvalue(r4.translateXProperty(), 200.0, interpolator = Interpolator.EASE_BOTH)
                   }
               }
           }
       }
       pane {
           add(r1)
           add(r2)
           add(r3)
           add(r4)
       }
   }
}

, , . play=false , .

0.5.seconds Duration:)

+3

, , . :

val time = 0.5.seconds
firstImg.scale(time, Point2D(1.0, 1.0), play = false).and(firstImg.rotate(time, 0.0, play = false))
        .then(secondImg.scale(time, Point2D(1.0, 1.0), play = false).and(secondImg.rotate(time, 0.0, play = false)))
        .then(thirdImg.scale(time, Point2D(1.0, 1.0), play = false).and(thirdImg.rotate(time, 0.0, play = false)))
        .then(fourthImg.scale(time, Point2D(1.0, 1.0), play = false).and(fourthImg.rotate(time, 0.0, play = false)))
        .play()

play = false , .

Edit

After a discussion in Slack , this may be simplified in a future version, so in the end it may be as simple as

val time = 0.5.seconds
listOf(
    firstImg.scale(time, 1 p 1) and firstImg.rotate(time, 0),
    secondImg.scale(time, 1 p 1) and secondImg.rotate(time, 0),
    thirdImg.scale(time, 1 p 1) and thirdImg.rotate(time, 0),
    fourthImg.scale(time, 1 p 1) and fourthImg.rotate(time, 0)
).playSequential()

See release notes for more information!

Other Editing

Looks like I made things a little harder. You can just use this if you like more:

val time = 0.5.seconds
SequentialTransition(
    firstImg.scale(time, Point2D(1.0, 1.0), play = false).and(firstImg.rotate(time, 0.0, play = false)).
    secondImg.scale(time, Point2D(1.0, 1.0), play = false).and(secondImg.rotate(time, 0.0, play = false)),
    thirdImg.scale(time, Point2D(1.0, 1.0), play = false).and(thirdImg.rotate(time, 0.0, play = false)),
    fourthImg.scale(time, Point2D(1.0, 1.0), play = false).and(fourthImg.rotate(time, 0.0, play = false))
).play()
+1
source

Source: https://habr.com/ru/post/1681948/