Created
April 26, 2016 12:04
-
-
Save jackofseattle/a1f658c67bd4b34fff6ec0f063189790 to your computer and use it in GitHub Desktop.
Etch-a-sketch in Elm! Go to http://elm-lang.org/try and paste in this code.
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
-- Etch-a-sketch with Elm | |
-- Paste this code into http://elm-lang.org/try | |
-- Use the arrow keys to draw a line etch-a-sketch style | |
import Color exposing (..) | |
import Graphics.Collage exposing (..) | |
import Graphics.Element exposing (..) | |
import Keyboard | |
import Time exposing (fps) | |
-- New Types to work with | |
type alias Model = | |
{ points : List Point | |
, x : Int | |
, y : Int | |
} | |
type alias Point = (Int, Int) | |
-- This is all of the data for the app | |
initialModel : Model | |
initialModel = | |
{ points = [(0, 0)] -- all of the points we'll draw | |
, x = 0 -- current cursor position x and y | |
, y = 0 | |
} | |
-- The view just translates the current model points into a canvas. | |
view : Model -> Element | |
view model = | |
collage 500 500 [(drawLine model.points)] | |
-- Functional piece - Elm takes care of the silly bitmap logic for us | |
drawLine : List Point -> Form | |
drawLine points = | |
let | |
intsToFloats (x, y) = | |
(toFloat x, toFloat y) | |
shape = path (List.map intsToFloats points) | |
in | |
shape | |
|> traced (solid blue) | |
-- As we know our model will change over time, lets convert it | |
-- into a stream that responds to our update function | |
model : Signal Model | |
model = | |
Signal.foldp update initialModel (pointsSignal Keyboard.arrows) | |
-- By default, signals are tiggered at the end of an event. | |
-- We want the line to coninuously draw, so we'll check for | |
-- key events 60 times per second instead. | |
pointsSignal : Signal {x :Int, y: Int} -> Signal {x :Int, y: Int} | |
pointsSignal keypresses = | |
Signal.sampleOn (fps 60) keypresses | |
-- Simple update function to add any new points into | |
-- the model | |
update : {x : Int, y: Int} -> Model -> Model | |
update arrows model = | |
let | |
newX = model.x + arrows.x | |
newY = model.y + arrows.y | |
in | |
{ model | |
| points = (newX, newY) :: model.points | |
, x = newX | |
, y = newY | |
} | |
-- Now just to render our application. | |
main : Signal Element | |
main = Signal.map view model |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment