[英]Consecutive animation in TornadoFX?
After reading through the documentation, I'm still a bit confused on how to execute an animation after another one has completed. 阅读完文档后,我仍然对如何在另一个完成后执行动画感到困惑。 I have a timeline like so: 我有一个这样的时间表:
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 runs them all at once, but I would like to run each animation after the other one has finished! 这会同时运行它们,但是我希望在另一个动画完成之后运行它们! I can't quite figure out how to do this.. ( sorry if this is obvious, I am very new to Kotlin and Java in general! ) 我无法弄清楚如何做到这一点..( 对不起,如果这很明显,我对Kotlin和Java一般都是新手! )
I see that the keyframe has an onFinished
property but I can't quite figure out what I'm supposed to actually set it to. 我看到关键帧有一个onFinished
属性,但我无法弄清楚我应该将它实际设置为什么。 Is there a better way to do this? 有一个更好的方法吗? Thank you! 谢谢!
Based on the structure proposed by @tornadofx-fan I've added builders for sequentialTransition and parallelTransition, so starting from TornadoFX 1.7.9 you can do the same like this: 基于@ tornadofx-fan提出的结构,我已经为sequentialTransition和parallelTransition添加了构建器,所以从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)
}
}
}
The timeline builder inside of these transitions don't automatically play, while the transition itself automatically plays when the builder is completed. 这些转换中的时间轴构建器不会自动播放,而转换器本身会在构建器完成时自动播放。 You can pass play=false
to the transition builder to disable autoplay. 您可以将play=false
传递给转换构建器以禁用自动播放。
Also note the usage of 0.5.seconds
to generate the Duration objects :) 还要注意使用0.5.seconds
来生成Duration对象:)
There's a JavaFX class "SequentialTransition" that will run your timelines in sequence. 有一个JavaFX类“SequentialTransition”将按顺序运行您的时间轴。 You'll need to disable the TornadoFX autoplay with a flag passed into the timeline builder. 您需要通过传递到时间线构建器的标志来禁用TornadoFX自动播放。 Check out ParallelTransition if you want to run these all at once using a similar coding pattern. 如果要使用类似的编码模式一次性运行这些,请查看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)
}
}
}
In this case where you're just setting scales and rotations, there are some nice helpers already in the library. 在这种情况下,您只需设置比例和旋转,库中已有一些不错的助手。 This should work for you: 这应该适合你:
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()
The play = false
everywhere is required since these helpers were designed for simple one-off auto-playing animations. 因为这些助手是为简单的一次性自动播放动画而设计的,所以需要play = false
无处不在。
Edit 编辑
After a discussion in Slack , these may be simplified in a future release, so the above may eventually be as easy as 在Slack讨论之后,这些可能会在将来的版本中得到简化,因此上述内容最终可能会变得如此简单
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()
Watch the release notes for more info! 观看发行说明以获取更多信息!
Another Edit 另一个编辑
Looks like I was over complicating things a bit. 看起来我过度复杂化了一些事情。 You can just use this if you like it 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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.