Created
June 6, 2016 14:25
-
-
Save christianp/7047213b063c01ee18526ce399e871d4 to your computer and use it in GitHub Desktop.
This file contains 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
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