TornadoFX 中的连续动画?
Consecutive animation in TornadoFX?
通读文档后,我仍然对如何在另一个动画完成后执行动画感到困惑。我有这样的时间表:
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)
}
}
这 运行 一次完成所有动画,但我想 运行 每个动画都在另一个动画完成后播放!我不太明白该怎么做..(抱歉,如果这很明显,我对 Kotlin 很陌生,一般来说 Java!)
我看到关键帧有一个 onFinished
属性,但我不太明白我应该 将其设置为 .有一个更好的方法吗?谢谢!
有一个 JavaFX class "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)
}
}
}
基于@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)
}
}
}
这些转场中的时间轴构建器不会自动播放,而转场本身会在构建器完成后自动播放。您可以将 play=false
传递给转换构建器以禁用自动播放。
还要注意 0.5.seconds
生成 Duration 对象的用法:)
在这种情况下,您只是设置比例和旋转,库中已有一些不错的帮手。这应该适合你:
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
到处都是必需的,因为这些助手是为简单的一次性自动播放动画而设计的。
编辑
在a discussion in 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()
查看发行说明了解更多信息!
另一个编辑
看来我把事情复杂化了一点。如果您更喜欢它,可以直接使用它:
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()
通读文档后,我仍然对如何在另一个动画完成后执行动画感到困惑。我有这样的时间表:
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)
}
}
这 运行 一次完成所有动画,但我想 运行 每个动画都在另一个动画完成后播放!我不太明白该怎么做..(抱歉,如果这很明显,我对 Kotlin 很陌生,一般来说 Java!)
我看到关键帧有一个 onFinished
属性,但我不太明白我应该 将其设置为 .有一个更好的方法吗?谢谢!
有一个 JavaFX class "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)
}
}
}
基于@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)
}
}
}
这些转场中的时间轴构建器不会自动播放,而转场本身会在构建器完成后自动播放。您可以将 play=false
传递给转换构建器以禁用自动播放。
还要注意 0.5.seconds
生成 Duration 对象的用法:)
在这种情况下,您只是设置比例和旋转,库中已有一些不错的帮手。这应该适合你:
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
到处都是必需的,因为这些助手是为简单的一次性自动播放动画而设计的。
编辑
在a discussion in 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()
查看发行说明了解更多信息!
另一个编辑
看来我把事情复杂化了一点。如果您更喜欢它,可以直接使用它:
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()