Created
September 24, 2015 23:05
-
-
Save mgold/399923b7acd29b236b3b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module SpinSquare (Model, Action, init, update, view) where | |
{-| A fork of the eight example in the Elm Architecture tutorial, showing how it would be done with elm-animation. It | |
turns out to be a lot simpler, both because of the animation itself and because we cheat a little: we don't stop | |
asking for clock ticks even when we don't need them. This saves a lot of bookkeeping around current vs. elapsed | |
time, as the animation library assumes you have a constantly running clock shared among all components. | |
By definition, encapsulated components cannot share a clock, and so as you add more squares, expect things to get | |
slower. That said, two squares work just fine. This module is a drop-in replacement for the upstream version. | |
Excercise for the reader: change `update` to turn off the clock when the square is done rotating, and account for | |
the fact that when you turn the clock back on, it will have counted the intervening time. | |
Base fork: https://github.com/evancz/elm-architecture-tutorial/tree/master/examples/8 | |
Animation library: https://github.com/mgold/elm-animation | |
Add as a dependency: "mgold/elm-animation": "1.0.1 <= v < 2.0.0", | |
-} | |
import Animation exposing (Animation) | |
import Easing exposing (easeOutBounce) | |
import Effects exposing (Effects) | |
import Html exposing (Html) | |
import Svg exposing (svg, rect, g, text, text') | |
import Svg.Attributes exposing (..) | |
import Svg.Events exposing (onClick) | |
import Time exposing (Time, second) | |
-- MODEL | |
type alias Model = | |
{ angle : Animation | |
, clock : Time | |
} | |
effects : Effects Action | |
effects = Effects.tick Tick | |
init : (Model, Effects Action) | |
init = | |
( { angle = Animation.static 0 |> Animation.ease easeOutBounce |> Animation.duration second, clock = 0 } | |
, effects | |
) | |
rotateStep = 90 | |
-- UPDATE | |
type Action | |
= Spin | |
| Tick Time | |
update : Action -> Model -> (Model, Effects Action) | |
update msg model = | |
case msg of | |
Spin -> | |
if Animation.isRunning model.clock model.angle | |
then ( model, Effects.none ) | |
else let currentAngle = Animation.getTo model.angle | |
newAnimation = Animation.retarget model.clock (currentAngle + rotateStep) model.angle | |
newModel = { angle = newAnimation, clock = model.clock } | |
in ( newModel, effects) | |
Tick newClock -> | |
let newModel = { angle = model.angle, clock = newClock } | |
in ( newModel , effects ) | |
-- VIEW | |
view : Signal.Address Action -> Model -> Html | |
view address model = | |
let | |
angle = Animation.animate model.clock model.angle | |
in | |
svg | |
[ width "200", height "200", viewBox "0 0 200 200" ] | |
[ g [ transform ("translate(100, 100) rotate(" ++ toString angle ++ ")") | |
, onClick (Signal.message address Spin) | |
] | |
[ rect | |
[ x "-50" | |
, y "-50" | |
, width "100" | |
, height "100" | |
, rx "15" | |
, ry "15" | |
, style "fill: #60B5CC;" | |
] | |
[] | |
, text' [ fill "white", textAnchor "middle" ] [ text "Click me!" ] | |
] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment