2016-11-14 108 views
1

我想實現SVG繪圖應用程序。榆木手柄mousemove /寫事件處理程序

我使用的是http://package.elm-lang.org/packages/elm-lang/mouse/1.0.1/Mouse,但它生成的訂閱提供了相對於整個文檔的位置,而不是相對於我的SVG元素。因此,我決定改用onmousemove

這裏是我的程序片段:

type MouseState = Up | Down 

type alias Model = { 
    mousePosition: Position, 
    mouseState: MouseState, 
    path: List Position 
} 

type Msg = MouseMove Position 
    | MouseUp Position 
    | MouseDown Position 
    | Noop 

update: Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case msg of 
     MouseMove position -> ({model | 
      mousePosition = position, 
      path = position :: model.path 
     }, Cmd.none) 
     MouseUp position -> ({model | mouseState = Up}, Cmd.none) 
     MouseDown position -> ({model | mouseState = Down}, Cmd.none) 
     _ -> (model, Cmd.none) 

subscriptions: Model -> Sub Msg 
subscriptions model = 
    Sub.batch [ 
     -- Mouse.moves MouseMove, -- remove this 
     Mouse.ups MouseUp, 
     Mouse.downs MouseDown 
    ] 

view: Model -> Html Msg 
view model = 
    div [] [ 
     div [] [ 
      Html.text (
       (toString model.mouseState) 
       ++ ", " ++ 
       (toString model.mousePosition.x) 
       ++ ", " ++ 
       (toString model.mousePosition.y) 
      )], 
     svg [ width "1200", height "1200", viewBox "0 0 1200 1200", on "mousemove" MouseMove] (
      List.map drawPoint model.path 
     ) 
    ] 

但編制該課程給我的錯誤:

Function `on` is expecting the 2nd argument to be: 

    Json.Decode.Decoder a 

But it is: 

    Position -> Msg 

Hint: I always figure out the type of arguments from left to right. If an 
argument is acceptable when I check it, I assume it is "correct" in subsequent 
checks. So the problem may actually be in how previous arguments interact with 
the 2nd. 

這帶來了兩個問題:如何寫一些解碼器,其將事件JSON到字符串,看看裏面是什麼,以及如何寫解碼器,從那個事件獲取座標?

+1

只是你可能想尋找到一個可能的方向:http://stackoverflow.com/a/40334086/1238847 – Tosh

回答

1

你需要一個Decoder那味精。您的留言是MouseMove,來自Position -> Msg的功能。你需要的是其簽名爲Decoder Msg的東西。 on需要事件,所以我們需要使用解碼器來獲取正確的信息。我並不確定你需要從JavaScript的MouseEvent中獲得哪些X和Y,但我們將在此示例中使用layerXlayerY(並且您可以將其更改爲正確的)。我們可以用applicatives來解決這個問題。

import Json.Decode as Decode exposing (Decoder) 
import Json.Decode.Extra as Decode exposing ((|:)) 


mouseMoveDecoder : Decoder Msg 
mouseMoveDecoder = 
    Decode.succeed MouseMove 
     |: (Decode.succeed Position 
      |: (Decode.field "layerX" Decode.int) 
      |: (Decode.field "layerY" Decode.int) 
     ) 

svg [ on "mousemove" mouseMoveDecoder ] [ ... ] 
+0

唉,有circuithub /榆樹沒有版本-json-extra與Elm 0.17.1一起使用。 :(我想我需要學習更多的這種語言才能理解你的答案。:) – Bunyk

+1

[此版本確實](http://package.elm-lang.org/packages/elm-community/json-extra/1.1 .0) – toastal

+0

糟糕,看起來像我忘了'npm update -g elm'。學習新技術時,最好確保你正在學習最新版本。 – Bunyk