Elmで現在時刻を表示するアナログ時計


このエントリーをはてなブックマークに追加

Elmの公式サイトのexampleにtimeがあって

example time

アナログ時計(みたいなもの)を表示するサンプルなのだが

現在時刻の秒を表示しているのではなくて

適当に1秒刻みに秒針が動いているものが表示されているだけみたいなのと


2016年11月にElm v0.18 が出たので、練習がてら現在時刻を表示するアナログ時計を作ってみた


作成は公式のexample

下記stack overflowを参考にした

How do I get the current date in elm?

Elmのバージョンはもちろん0.18を使用した



とりあえずコードだけ載せる


SVGを使うので $ elm package install elm-lang/svg でelm-lang/svg を入れておくこと

とりあえず書いたコードは下記で

githubにもあげてみた

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
module TimeTest exposing (..)
import Html exposing (..)
import Svg exposing (..)
import Svg.Attributes exposing (..)
import Time exposing (..)
import Date exposing (..)
import Task
main =
Html.program
{ view = view
, init = init
, subscriptions = subscriptions
, update = update
}
-- MODEL
type alias Model =
Time
init : (Model, Cmd Msg)
init =
(0, now)
-- UPDATE
type Msg
= SetTime Time
update : Msg -> Model -> (Model, Cmd Msg)
update (SetTime time) _ =
(time, Cmd.none)
-- Elm公式サイトのtimeのExampleの書き方に従うなら下記
-- update msg model =
-- case msg of
-- SetTime newTime ->
-- (newTime, Cmd.none)
now : Cmd Msg
now =
Task.perform SetTime Time.now
-- SUBSCRIPTION
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every Time.second SetTime
-- VIEW
view model =
let
secondNow =
Date.second <| Date.fromTime <| model
minuteNow =
Date.minute <| Date.fromTime <| model
hourNow =
(Date.hour <| Date.fromTime <| model) % 12
angleSecond =
toFloat <| 6 * secondNow
angleMinute =
toFloat <| 6 * minuteNow
angleHour =
-- 下記は(toFloat <| 30 * hourNow) + (angleMinute / 12) と同じ
(+) (angleMinute / 12) <| (toFloat <| 30 * hourNow)
handSecondX =
toString (50 + 38 * sin (angleSecond * pi / 180))
handSecondY =
toString (50 - 38 * cos (angleSecond * pi / 180))
handMinuteX =
toString (50 + 32 * sin (angleMinute * pi / 180))
handMinuteY =
toString (50 - 32 * cos (angleMinute * pi / 180))
handHourX =
toString (50 + 25 * sin (angleHour * pi / 180))
handHourY =
toString (50 - 25 * cos (angleHour * pi / 180))
in
div []
[ svg [ viewBox "0 0 100 100", width "300px" ]
[ circle [ cx "50", cy "50", r "45", fill "#2a2a2a" ] []
, circle [ cx "50", cy "50", r "40", fill "#f6f6f6" ] []
, line [x1 "50", y1 "50", x2 handSecondX, y2 handSecondY, stroke "#2a2a2a", strokeWidth "0.5"][]
, line [x1 "50", y1 "50", x2 handMinuteX, y2 handMinuteY, stroke "#2a2a2a", strokeWidth "1"][]
, line [x1 "50", y1 "50", x2 handHourX, y2 handHourY, stroke "#2a2a2a", strokeWidth "2"][]
]
-- 以下は時間のデバッグ用に表示
, div [] [Html.text ("model(UNIX time): " ++ (toString model))]
, div [] [Html.text ("Date.fromTime model: " ++ (toString (Date.fromTime model)))]
]


下の画像みたいなのが表示されたら成功

余力があったら作り方のチュートみたいなのを書こうと思う


このエントリーをはてなブックマークに追加