Skip to content

Instantly share code, notes, and snippets.

@christianp
Created June 6, 2016 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianp/7047213b063c01ee18526ce399e871d4 to your computer and use it in GitHub Desktop.
Save christianp/7047213b063c01ee18526ce399e871d4 to your computer and use it in GitHub Desktop.
import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (on)
import Json.Decode as Json exposing ((:=))
import Mouse exposing (Position)
import Time exposing (Time, millisecond)
import String
import Task exposing (perform)
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Vector = {x:Float,y:Float}
vectorFromPosition position = {x = toFloat position.x, y = toFloat position.y}
type alias Model =
{ position : Vector
, mousePosition: Vector
, velocity: Vector
, time: Time
}
init : ( Model, Cmd Msg )
init =
({position = (Vector 200 200), mousePosition = (Vector 0 0), velocity = (Vector 0 0), time = 0}, perform (\x->NoMsg) InitTime Time.now )
-- UPDATE
type Msg
= MouseMove Position
| Tick Time
| InitTime Time
| NoMsg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
( updateHelp msg model, Cmd.none )
updateHelp : Msg -> Model -> Model
updateHelp msg model =
case msg of
MouseMove pos -> {model | mousePosition = vectorFromPosition pos}
Tick time -> updatePosition model time
InitTime time -> {model | time = time}
NoMsg -> model
(!+) : Vector -> Vector -> Vector
(!+) a b = Vector (a.x+b.x) (a.y+b.y)
(!*) : Float -> Vector -> Vector
(!*) f v = Vector (f*v.x) (f*v.y)
updatePosition : Model -> Time -> Model
updatePosition model time =
let
diff = time-model.time
a = model.position
b = model.mousePosition
dx = b.x - a.x
dy = b.y - a.y
addVelocity = Vector (dx*diff/10000.0) (dy*diff/10000.0)
velocity = 0.99 !* (model.velocity !+ addVelocity)
in
{model | time=time, position = model.position !+ velocity, velocity = velocity}
-- SUBSCRIPTIONS
subscriptions model = Sub.batch <| [moveSubscriptions model, Time.every (10*millisecond) Tick]
moveSubscriptions model = Mouse.moves MouseMove
-- VIEW
(=>) = (,)
floatMod a b = toFloat <| ((floor a) % b)
showTime rtime =
let
time = floatMod rtime (1000*60*60*24)
hours = floor (Time.inHours time)
minutes = floor (Time.inMinutes (time - (toFloat hours)*60*60*1000))
seconds = floor (Time.inSeconds (time - (toFloat hours)*60*60*1000 - (toFloat minutes)*60*1000))
in
String.join " : " (List.map (String.pad 2 '0') [
toString <| hours,
toString <| minutes,
toString <| seconds
])
view : Model -> Html Msg
view model =
let
realPosition = model.position
in
div [] [
p [] [text (showTime model.time)]
, div
[ style
[ "background-color" => "#3C8D2F"
, "cursor" => "move"
, "width" => "100px"
, "height" => "100px"
, "border-radius" => "4px"
, "position" => "absolute"
, "left" => px realPosition.x
, "top" => px realPosition.y
, "color" => "white"
, "display" => "flex"
, "align-items" => "center"
, "justify-content" => "center"
]
]
[ text "Drag Me!" ]
]
px : Float -> String
px number =
toString number ++ "px"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment