implement opacity animation
This commit is contained in:
parent
e4f72b5c9e
commit
d50eb26b14
12
Client.fs
12
Client.fs
@ -1,17 +1,23 @@
|
||||
namespace web_api_cookbook
|
||||
|
||||
open WebSharper
|
||||
open WebSharper.JavaScript
|
||||
open WebSharper.UI
|
||||
open WebSharper.UI.Client
|
||||
open WebSharper.UI.Html
|
||||
open WebSharper.UI.Templating
|
||||
open Units.Animation
|
||||
open Units.Time
|
||||
|
||||
|
||||
[<JavaScript>]
|
||||
module Client =
|
||||
[<SPAEntryPoint>]
|
||||
let Main () =
|
||||
let isClicked = Var.Create false
|
||||
let opacityAnimated = Animate.valueWhen isClicked.View 1.0 0. 120.<frames/s> 1.<s>
|
||||
let opacityStyle = View.MapCached (sprintf "opacity: %f") opacityAnimated
|
||||
let onClick = on.click (fun _ _ -> Var.Set isClicked true)
|
||||
|
||||
div [] [
|
||||
p [] [ text "hello world!" ]
|
||||
UI.Components.button [attr.styleDyn opacityStyle; onClick] "Hide Me"
|
||||
]
|
||||
|> Doc.RunById "main"
|
||||
|
||||
31
Prelude.fs
Normal file
31
Prelude.fs
Normal file
@ -0,0 +1,31 @@
|
||||
namespace web_api_cookbook
|
||||
|
||||
open WebSharper
|
||||
|
||||
[<JavaScript>]
|
||||
module Option =
|
||||
let getOrElse def opt =
|
||||
if Option.isSome opt
|
||||
then Option.get opt
|
||||
else def
|
||||
|
||||
[<JavaScript>]
|
||||
module Units =
|
||||
module Animation =
|
||||
[<Measure>]
|
||||
type frames
|
||||
module Time =
|
||||
[<Measure>]
|
||||
type ms
|
||||
[<Measure>]
|
||||
type s
|
||||
|
||||
[<JavaScript>]
|
||||
module Math =
|
||||
let clamp a b c =
|
||||
if c < a then a
|
||||
else if c > b then b
|
||||
else c
|
||||
|
||||
[<Inline>]
|
||||
let inline lerp a b t = a + t * (b - a)
|
||||
52
Ui.fs
Normal file
52
Ui.fs
Normal file
@ -0,0 +1,52 @@
|
||||
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
|
||||
@ -9,6 +9,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Prelude.fs" />
|
||||
<Compile Include="Ui.fs" />
|
||||
<Compile Include="Client.fs" />
|
||||
<Compile Include="Startup.fs" />
|
||||
<None Include="package.json" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user