first commit

This commit is contained in:
Christian Lawson-Perfect 2025-02-09 20:37:04 +00:00
commit a9af55fb0b
9 changed files with 238 additions and 0 deletions

128
src/App.elm Normal file
View file

@ -0,0 +1,128 @@
module App exposing (..)
import Browser
import Html as H exposing (Html)
import Html.Attributes as HA
import Html.Events as HE
import Svg
import Svg.Attributes as SA
import Time exposing (Posix)
main = Browser.document
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
type alias Model = { time: Posix }
init_model = { time = Time.millisToPosix 0 }
type Msg
= Tick Posix
init : () -> (Model, Cmd msg)
init _ = (init_model, Cmd.none)
update msg model = case msg of
Tick time -> ({ model | time = time }, Cmd.none)
subscriptions model = Time.every 50 Tick
ff = String.fromFloat
view model =
let
time = model.time
zone = Time.utc
now = (toFloat <| Time.posixToMillis time) / 1000
num_arms = 10
r_for n = 1 - 0.9*n/num_arms
period_for n = 10 ^ ((toFloat num_arms) - n)
arm n =
let
period = period_for n
an = (now / period - 0.25) * 2 * pi
r = r_for n
in
Svg.line
[ SA.x1 "0"
, SA.y1 "0"
, SA.x2 <| ff <| (*) r <| cos an
, SA.y2 <| ff <| (*) r <| sin an
, SA.strokeWidth "0.01"
, SA.stroke "black"
-- , SA.strokeDasharray <| (ff dash) ++ " " ++ (ff dash)
]
[]
arms = List.map (toFloat >> arm) (List.range 0 num_arms)
tick ii =
let
i = toFloat ii
an = 2 * pi * (i / 10 - 0.25)
r = 1
in
Svg.line
[ SA.x1 "0"
, SA.y1 "0"
, SA.x2 <| ff <| (*) r <| cos an
, SA.y2 <| ff <| (*) r <| sin an
, SA.strokeWidth "0.01"
, SA.stroke "#eee"
]
[]
inner_circle n =
let
fn = toFloat n
period = period_for fn
r = (r_for fn)
num_ticks = (floor period)
in
Svg.g
[]
[ Svg.circle
[ SA.r <| ff r
, SA.strokeWidth "0.002"
, SA.stroke "gray"
, SA.fill "none"
]
[]
, Svg.text_
[ SA.x "0"
, SA.y <| ff (-r)
, SA.fontSize "0.03"
, SA.textAnchor "middle"
]
[ Svg.text <| ff <| period]
]
circles = List.map (inner_circle) (List.range 0 num_arms)
in
{
title = "Unix epoch clock",
body =
[ Svg.svg
[ HA.attribute "viewBox" "-1.2 -1.2 2.4 2.6"]
[ Svg.g [] (List.map tick (List.range 0 9))
, Svg.g [] circles
, Svg.g [] arms
, Svg.text_
[ SA.x "0"
, SA.y "1.1"
, SA.textAnchor "middle"
, SA.dominantBaseline "central"
, SA.fontSize "0.1"
, SA.stroke "white"
, SA.strokeWidth "0.02"
, SA.style "paint-order: stroke fill"
]
[ Svg.text <| String.fromInt <| floor <| (\n -> (toFloat n)/1000) <| Time.posixToMillis model.time ]
]
]
}