Skip to content

Instantly share code, notes, and snippets.

@dustinheestand
Last active June 11, 2020 02:52
Show Gist options
  • Save dustinheestand/c939f93f4d47aecddce8d62a5024baf3 to your computer and use it in GitHub Desktop.
Save dustinheestand/c939f93f4d47aecddce8d62a5024baf3 to your computer and use it in GitHub Desktop.
-- Show the current time in your time zone.
--
-- Read how it works:
-- https://guide.elm-lang.org/effects/time.html
--
-- For an analog clock, check out this SVG example:
-- https://elm-lang.org/examples/clock
--
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Svg exposing (line, circle, g, svg)
import Svg.Attributes as A
import Task
import Time
-- MAIN
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ zone : Time.Zone
, time : Time.Posix
, running : Bool
}
init : () -> (Model, Cmd Msg)
init _ =
( Model Time.utc (Time.millisToPosix 0) True
, Task.perform AdjustTimeZone Time.here
)
-- UPDATE
type Msg
= Tick Time.Posix
| AdjustTimeZone Time.Zone
| ToggleClock
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Tick newTime ->
( { model | time = newTime }
, Cmd.none
)
AdjustTimeZone newZone ->
( { model | zone = newZone }
, Cmd.none
)
ToggleClock ->
( { model | running = not model.running}
, Cmd.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
case model.running of
True -> Time.every 1000 Tick
False -> Sub.none
-- VIEW
view : Model -> Html Msg
view model =
let
hour = Time.toHour model.zone model.time
minute = Time.toMinute model.zone model.time
second = Time.toSecond model.zone model.time
in
div [] [
svg [ A.width "700"
, A.height "700"
, A.viewBox "0 0 700 700"
]
[ g [ A.transform "translate (10 10) rotate (270 340 340)"]
(clockFace hour minute second)
]
, button [onClick ToggleClock] [text <| (\b ->
case b of
True -> "off"
False -> "on"
) model.running ]
]
clockFace : Int -> Int -> Int -> List (Svg.Svg msg)
clockFace h m s =
[ circle [A.cx "340", A.cy "340", A.r "340", A.fill "none", A.stroke "black"] []
, hourHand h m s
, minuteHand m s
, secondHand s
]
hourHand: Int -> Int -> Int -> Svg.Svg msg
hourHand h m s =
hand "90" "7" (toFloat (modBy 12 h) * 30.0 + toFloat m * 0.5 + toFloat s * 0.5 * 0.1)
minuteHand m s =
hand "40" "4" (toFloat m * 6.0 + toFloat s * 0.1)
secondHand s =
hand "20" "2" <| toFloat s * 6.0
hand l w d =
line [A.x1 "340"
, A.x1 "340"
, A.y1 "340"
, A.x2 "340"
, A.y2 l
, A.strokeWidth w
, A.stroke "black"
, A.transform ("rotate (" ++ (String.fromFloat d) ++ " 340 340)")] []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment