aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/reading/component/widget/Animate.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/reading/component/widget/Animate.scala')
-rw-r--r--src/main/scala/reading/component/widget/Animate.scala55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/main/scala/reading/component/widget/Animate.scala b/src/main/scala/reading/component/widget/Animate.scala
new file mode 100644
index 0000000..0e848aa
--- /dev/null
+++ b/src/main/scala/reading/component/widget/Animate.scala
@@ -0,0 +1,55 @@
+package reading.component.widget
+
+import scala.collection.mutable.Map
+
+import org.scalajs.dom.{ window, document }
+import org.scalajs.dom.raw.HTMLElement
+
+object Animate {
+ val animationFrames: Map[String, Int] = Map.empty
+
+ def apply(
+ id: String,
+ duration: Double,
+ transition: (Double, Double) => Double,
+ animate: (Double, HTMLElement) => Unit,
+ onEnd: => Unit = ()
+ ): Unit = {
+ animationFrames.get(id) match {
+ case Some(animationFrame) => window.cancelAnimationFrame(animationFrame)
+ case None => ()
+ }
+ val animationFrame = window.requestAnimationFrame(ts =>
+ frame(id, ts, duration, transition, animate, onEnd)(ts))
+ animationFrames.put(id, animationFrame)
+ ()
+ }
+
+ private def frame(
+ id: String,
+ start: Double,
+ duration: Double,
+ transition: (Double, Double) => Double,
+ animate: (Double, HTMLElement) => Unit,
+ onEnd: => Unit
+ )(
+ timestamp: Double
+ ): Unit = {
+ document.getElementById(id).asInstanceOf[HTMLElement] match {
+ case element: HTMLElement =>
+ val elapsed = timestamp - start
+ if (elapsed < duration) {
+ animate(Transition.easeOut(elapsed, duration), element)
+ val animationFrame = window.requestAnimationFrame(frame(id, start, duration, transition, animate, onEnd))
+ animationFrames.put(id, animationFrame)
+ } else {
+ animate(1, element)
+ onEnd
+ }
+ case _ =>
+ val animationFrame = window.requestAnimationFrame(ts => frame(id, ts, duration, transition, animate, onEnd)(ts))
+ animationFrames.put(id, animationFrame)
+ }
+ ()
+ }
+}