布局改变后的scalafx动画

时间:2014-10-15 10:15:45

标签: animation layout javafx scalafx

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

有两个问题:

  1. 动画不流畅。有时,当添加子或调整窗口大小时,存在闪烁(“假信号”),其中节点的位置和/或比例暂时变得不正确。我尝试按照引用的答案中的建议设置初始值,但似乎没有解决它。
  2. 通过拖动底部边缘调整窗口大小时,移动动画从当前位置正确启动。但是,拖动顶部边缘时,跳转是初始位置。
  3. 代码如下:

    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
    }
    

0 个答案:

没有答案