2

我正在尝试为 ScalaFX 应用程序中的布局更改设置动画,类似于这个问题。场景包括一个主窗格。每次单击它时,都会在其中添加另一个窗格(“儿子”)(实际上是在其中的 FlowPane 内)。窗格添加应该“推高”以前的儿子,如果需要,“挤压”以前的儿子(直到他们的最小高度)。

有两个问题:

  1. 动画不流畅。有时,当添加儿子或调整窗口大小时,会出现闪烁(“故障”),其中节点的位置和/或比例会暂时不正确。我尝试按照引用的答案中的建议设置初始值,但似乎没有解决它。
  2. 通过拖动底部边缘调整窗口大小时,移动动画从当前位置正确开始。但是,当拖动顶部边缘时,有一个跳跃是初始位置。

代码如下:

import scalafx.Includes._
import scalafx.scene.input.MouseEvent
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafx.animation.{ScaleTransition, TranslateTransition}
import scalafx.geometry.Pos
import scalafx.scene.control.ScrollPane
import scalafx.scene.layout._
import scalafx.util.Duration

object Main extends JFXApp {
  stage = new PrimaryStage { scene = new Scene (new NodePane, 800, 600) }
}

class NodePane(isExternal: Boolean = true) extends BorderPane  {
  def makeMargin = new FlowPane {
    prefHeight = 30
    minHeight = 10
  }

  top = makeMargin
  center = if (isExternal) new SonsPane() else new EmptySonsPane()
  bottom = makeMargin
}

class SonsPane extends ScrollPane {
  val vbox = new VBox {
    fitToHeight = true
    fitToWidth = true
    alignment = Pos.Center
  }
  content = vbox

  onMouseClicked = (e: MouseEvent) => vbox.content.add(makeSonPane())

  def makeSonPane() = {
    new NodePane(isExternal = false) {
      prefHeight = 150
      // initial initialization
//      scaleY = 0.1
      var prevPos = layoutY.value
      var prevHeight = height.value
      // change events
      layoutY.onChange {
        if (prevPos != 0) {
          val translation = new TranslateTransition(Duration(600), this) {
            fromY = prevPos - layoutY.value
            toY = 0
          }
          translateY = layoutY.value - prevPos
          translation.play()
        }
        prevPos = layoutY.value
      }
      height.onChange {
        val scaling = new ScaleTransition(Duration(600), this) {
          fromY = prevHeight / height.value
          toY = 1
        }
        scaleY = prevHeight / height.value
        scaling.play()
        prevHeight = height.value
      }
    }
  }
}

class EmptySonsPane extends FlowPane {
  style = "-fx-border-color: black; -fx-background-color: yellow; -fx-background-opacity: 0.5"
  minHeight = 100
}
4

0 回答 0