From c3a7ab52355e4a2ce38a884e42ff9ac4e0f9d288 Mon Sep 17 00:00:00 2001 From: LeshaInc Date: Sat, 7 Sep 2019 20:40:29 +0300 Subject: [PATCH] Better animation --- .../ocelot/desktop/graphics/Graphics.scala | 4 ++ .../desktop/ui/widget/NodeSelector.scala | 59 +++++++++++++++---- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/scala/ocelot/desktop/graphics/Graphics.scala b/src/main/scala/ocelot/desktop/graphics/Graphics.scala index b6c7aad..1fc5f1f 100644 --- a/src/main/scala/ocelot/desktop/graphics/Graphics.scala +++ b/src/main/scala/ocelot/desktop/graphics/Graphics.scala @@ -136,6 +136,10 @@ class Graphics extends Logging { stack.head.transform = stack.head.transform >> t } + def scale(v: Float): Unit = { + transform(Transform2D.scale(v)) + } + def translate(x: Float, y: Float): Unit = { transform(Transform2D.translate(x, y)) } diff --git a/src/main/scala/ocelot/desktop/ui/widget/NodeSelector.scala b/src/main/scala/ocelot/desktop/ui/widget/NodeSelector.scala index 87d6f19..9378204 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/NodeSelector.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/NodeSelector.scala @@ -3,16 +3,12 @@ package ocelot.desktop.ui.widget import ocelot.desktop.color.RGBAColor import ocelot.desktop.geometry.{Padding2D, Size2D, Vector2D} import ocelot.desktop.graphics.Graphics +import ocelot.desktop.ui.UiHandler import ocelot.desktop.ui.layout.LinearLayout import ocelot.desktop.ui.workspace.ScreenNode import ocelot.desktop.util.{Animation, Orientation} class NodeSelector extends Widget { - - private class Row extends Widget { - override val layout = new LinearLayout(this, Orientation.Horizontal) - } - override val layout = new LinearLayout(this) private val rowsWidget: Widget = new Widget { @@ -29,46 +25,82 @@ class NodeSelector extends Widget { // noinspection ScalaUnusedSymbol private def rows_=(rows: Array[Widget]): Unit = rowsWidget.children = rows + private var numNodes: Int = 0 + private def add(widget: Widget): Unit = { val row = if (rows.lastOption.exists(row => row.children.length < 4)) { rows.last } else { - val row = new Row() + val row = new Row(rows.length) rows :+= row row } row.children :+= widget + numNodes += 1 } for (_ <- 0 to 100) add(new ScreenNode()) private var _isShown: Boolean = false + private var isClosing: Boolean = false private var width = 0f private var finalHeight = 0f private var heightAnimation: Animation = _ + private var animationTime: Float = 0f def isShown: Boolean = _isShown override def update(): Unit = { if (isShown) { heightAnimation.update() + + if (isClosing) { + animationTime -= UiHandler.dt + } else { + animationTime += UiHandler.dt + } + size = Size2D(width, heightAnimation.value * finalHeight) - if (size.height < 1) + if (size.height < 1) { _isShown = false + isClosing = false + } } super.update() } override def draw(g: Graphics): Unit = { - if (isShown) { - g.foreground = RGBAColor(150, 150, 150, 60) - g.sprite = "Empty" - g.rect(position.x, position.y, size.width, size.height) - super.draw(g) + if (!isShown) return + + g.foreground = RGBAColor(150, 150, 150, 60) + g.sprite = "Empty" + g.rect(position.x, position.y, size.width, size.height) + super.draw(g) + } + + private class Row(rowIdx: Int) extends Widget { + override val layout = new LinearLayout(this, Orientation.Horizontal) + + override def drawChildren(g: Graphics): Unit = { + if (!isShown) return + + for ((child, i) <- children.zipWithIndex) { + val idx = rowIdx * 4 + i + val timeOffset = idx.toFloat * 0.02f + + g.save() + val sx = child.position.x + child.size.width / 2 + val sy = child.position.y + child.size.height / 2 + g.translate(sx, sy) + g.scale(((animationTime - timeOffset) / 0.1f).max(0f).min(1f)) + g.translate(-sx, -sy) + child.draw(g) + g.restore() + } } } @@ -77,6 +109,7 @@ class NodeSelector extends Widget { position = at heightAnimation = Animation.easeOutQuad(0.2f) heightAnimation.goUp() + animationTime = 0f width = inner.minimumSize.width finalHeight = inner.minimumSize.height.min(250) } @@ -85,5 +118,7 @@ class NodeSelector extends Widget { heightAnimation = Animation.easeInQuad(0.1f) heightAnimation.time = 1 heightAnimation.goDown() + animationTime = 0.16f + isClosing = true } }