2025-07-21 12:09:48 +09:00

53 lines
1.9 KiB
Forth

namespace web_api_cookbook
open WebSharper
open WebSharper.JavaScript
open WebSharper.UI
open WebSharper.UI.Client
open WebSharper.UI.Html
[<JavaScript>]
module UI =
module Components =
let button attrs label =
button (attrs @ [attr.``type`` "button"]) [ text label ]
[<JavaScript>]
module Animate =
open Units.Animation
open Units.Time
let value (startPoint:float) endPoint (targetFps:float<frames/s>) (animationSeconds:float<s>) =
let frameInterval = 1. / targetFps * 1000.0<ms/s>
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<ms> option) frameNo (now:float) =
let now = now * 1.0<ms>
let lastRedrawAt = Option.getOrElse now lastRedrawAt
let elapsed = now - lastRedrawAt
let readyToRender = elapsed >= frameInterval * 1.<frames>
match readyToRender with
| false ->
JS.Window.RequestAnimationFrame (callback (Some lastRedrawAt) frameNo) |> ignore
| true ->
let t = float frameNo * increment * 1.<frames>
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