namespace web_api_cookbook.UI open web_api_cookbook open web_api_cookbook.Units.Animation open web_api_cookbook.Units.Time open WebSharper open WebSharper.UI open WebSharper.JavaScript [] module Animate = let value (startPoint:float) endPoint (targetFps:float) (animationSeconds:float) = let frameInterval = 1. / targetFps * 1000.0 let frameCount = animationSeconds * targetFps let diff = startPoint - endPoint let increment = abs (diff / frameCount) let lerp = Math.lerp startPoint endPoint let interpolatedValue = Var.Create startPoint let rec callback (lastRedrawAt:float option) frameNo (now:float) = let now = now * 1.0 let lastRedrawAt = Option.getOrElse now lastRedrawAt let elapsed = now - lastRedrawAt let readyToRender = elapsed >= frameInterval * 1. match readyToRender with | false -> JS.Window.RequestAnimationFrame (callback (Some lastRedrawAt) frameNo) |> ignore | true -> let t = float frameNo * increment * 1. let nextVal = lerp t Var.Set interpolatedValue nextVal if nextVal <> endPoint then JS.Window.RequestAnimationFrame (callback (Some now) (frameNo + 1)) |> ignore JS.Window.RequestAnimationFrame (callback None 0) |> ignore interpolatedValue.View let valueWhen beginAnimation startPoint endPoint targetFps animationSeconds = function | true -> value startPoint endPoint targetFps animationSeconds | false -> View.Const startPoint |> View.MapCached <| beginAnimation |> View.Join