SvgClock Stop
SvgClock.ml module P = Preact
module S = P .Svg
module Clock = struct
let utcNow () =
Js .Date .now () -. (Js .Date .getTimezoneOffset (Js .Date .make () ) *. 60.0 *. 1000.0 )
let make =
fun [@preact.component "Clock" ] () ->
let [@hook] isRunning, setIsRunning = P .useState true in
let [@hook] now, setNow = P .useState (Js .Date .now () ) in
let [@hook] () = AnimationFrame .use (isRunning, fun _ -> setNow (utcNow () )) in
let circle =
S .circle [ S .cx "100" ; S .cy "100" ; S .r "98" ; S .fill "none" ; S .stroke "black" ] []
in
let line rotate stroke strokeWidth height =
S .line
[ S .x1 "100"
; S .y1 "100"
; S .x2 (Js .Int .toString (100 - height))
; S .y2 "100"
; S .stroke stroke
; S .strokeWidth (Js .Int .toString strokeWidth)
; S .strokeLinecap "round"
; S .transform ("rotate(" ^ Js .Float .toString rotate ^ " 100 100)" )
]
[]
in
let s = now /. 1000.0 in
let secondRotate = 90.0 +. (mod_float s 60.0 *. 360.0 /. 60.0 ) in
let minuteRotate = 90.0 +. (mod_float (s /. 60.0 ) 60.0 *. 360.0 /. 60.0 ) in
let hourRotate = 90.0 +. (mod_float (s /. 60.0 /. 60.0 ) 12.0 *. 360.0 /. 12.0 ) in
P .h2
[ P .style "text-align" "center" ]
[ S .svg
[ S .width "400" ; S .height "400" ; S .viewBox "0 0 200 200" ]
[ circle
; line hourRotate "#333" 4 50
; line minuteRotate "#333" 3 70
; line secondRotate "crimson" 2 90
]
; P .div
[]
[ P .button
[ P .onClick (fun _ -> setIsRunning (not isRunning)) ]
[ P .string (if isRunning then "Stop" else "Start" ) ]
]
]
end
let () =
match P .find "main" with
| Some element -> P .render (Clock .make () ) element
| None -> Js .Console .error "<main> not found!"
AnimationFrame.ml module P = Preact
let use =
fun [@preact.hook] (enabled, func) ->
let [@hook] () =
P .useEffect
(fun () ->
let id = ref None in
let rec loop t =
let () = func t in
let () = id := Some (Webapi .requestCancellableAnimationFrame loop) in
()
in
let () =
if enabled
then id := Some (Webapi .requestCancellableAnimationFrame loop)
else ()
in
Some
(fun () ->
match !id with
| Some id -> Webapi .cancelAnimationFrame id
| None -> () ))
(P ._1 enabled)
in
()