2016-11-14 15 views
1

私はSVG描画アプリケーションを実装しようとしています。Elmハンドル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

あなたはそのMSGにDecoderを必要としています。あなたのメッセージはMouseMovePosition -> Msgの機能です。必要なのは、署名がDecoder Msgのものです。 onはイベントを受け取るので、適切な情報を得るためにデコーダを使用する必要があります。私は実際のXとYはあなたのJavaScriptのMouseEventから必要があるかわからないんだけど、私たちは、この例では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 /ニレのないバージョンではありませんElm 0.17.1で動作する-json-extraです。私はあなたの答えを理解するためにこの言語の詳細を学ぶ必要があると思います:) – Bunyk

+1

[このバージョンでは](http://package.elm-lang.org/packages/elm-community/json-extra/1.1 .0) – toastal

+0

私は 'npm update -g elm'をするのを忘れてしまったようです。新技術を学ぶときには、最新のバージョンを習得していることを確認することをお勧めします。 – Bunyk