Skip to content

Instantly share code, notes, and snippets.

@botandrose
Created May 20, 2016 00:23
Show Gist options
  • Save botandrose/ee0957cdcd9ff4e2e86ad7a9578ca72e to your computer and use it in GitHub Desktop.
Save botandrose/ee0957cdcd9ff4e2e86ad7a9578ca72e to your computer and use it in GitHub Desktop.
Draw lines on an div with Elm
module DrawLines exposing (..)
import Html.App
import Mouse exposing (Position)
import Svg exposing (..)
import Svg.Attributes exposing (..)
main : Program Config
main =
Html.App.programWithFlags { init = init, subscriptions = subscriptions, update = update, view = view }
type alias Config =
{ offset : Position
, size : Position
}
type alias Model =
{ config : Config
, line : Maybe Line
, isDrawing : Bool
}
type alias Line =
{ start : Position
, end : Position
}
type Message = StartLine Position | UpdateLine Position | EndLine Position
init : Config -> ( Model, Cmd Message )
init config =
( Model config Nothing False, Cmd.none )
subscriptions : Model -> Sub Message
subscriptions model =
let
offset =
model.config.offset
abs2rel position =
{ position | x = position.x - offset.x, y = position.y - offset.y }
in
Sub.batch
[ Mouse.moves (UpdateLine << abs2rel)
, Mouse.downs (StartLine << abs2rel)
, Mouse.ups (EndLine << abs2rel)
]
update : Message -> Model -> ( Model, Cmd Message )
update message model =
let
updatedModel =
case message of
StartLine position ->
{ model | line = Just <| Line position position, isDrawing = True }
UpdateLine position ->
if model.isDrawing
then { model | line = Maybe.map (\line -> { line | end = position }) model.line }
else model
EndLine position ->
{ model | isDrawing = False }
in ( updatedModel, Cmd.none )
view : Model -> Svg Message
view model =
let
renderLine =
case model.line of
Just line ->
[ Svg.line
[ x1 <| toString line.start.x
, y1 <| toString line.start.y
, x2 <| toString line.end.x
, y2 <| toString line.end.y
, stroke "#D80707"
, strokeWidth "3"
, strokeMiterlimit "10"
, fill "none"
]
[]
]
Nothing -> []
size =
model.config.size
in
svg
[ version "1.1"
, width (toString size.x)
, height (toString size.y)
, viewBox ("0 0 " ++ toString size.x ++ " " ++ toString size.y)
]
renderLine
$(function() {
var $div = $("div");
var offset = $div.offset();
Elm.DrawLines.embed($div[0], {
offset: { x: parseInt(offset.left), y: parseInt(offset.top) },
size: { x: $div.width(), y: $div.height() }
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment