LoginSignup
1

More than 5 years have passed since last update.

[Elm] elm-touch-events使ってみた

Last updated at Posted at 2017-12-16

最近、elm-touch-eventsを使って遊んでみてるので、その簡単な解説をば。

elm-touch-eventsとは

Elmには、デフォルトでタッチイベントを制御する機能は入っていません(Elm 0.18では)。
これでは、スマホ向けに凝ったUIを作るときに、困ったりすることがありそうですね。

そこで便利なpackageが、elm-touch-eventsです。

何ができるの?

DOMをタッチしたときに、「指が触れたとき」、「指を動かしたとき」、「指を離したとき」の3つについて、
それぞれに発火するイベントを作成することができます。
マルチタッチにも対応しています。

デモ

スライド動作によるオブジェクトの移動と、
ピンチアウトによるズーム機能を実装しました。
https://ebiryu.github.io/elm-touch-demo/
(※スマホなどのタッチデバイスじゃないと動作しないです)

使い方

大体のことはpackageのページを見れば書いてありますが、
今回は日本語のドキュメントを増やす意味で書いておきます。

インストール

elm-packageでインストールします。

elm-package install mpizenberg/elm-touch-events

SingleTouch

マルチタッチにも対応していると言いましたが、
シングルタッチはもっと簡単に実装できます。

デモのソースコードを見てみましょう。
https://github.com/ebiryu/elm-touch-demo/blob/master/src/Main.elm

まずはviewから。

objects : Model -> List (Svg Msg)
objects model =
    [
    ...
    , polygon
        [ SingleTouch.onStart SingleStart
        , SingleTouch.onMove SingleMove
        ...
        ]
        []
    ]

このobjectsはviewで読み込んでるsvgの要素ですが、
その中の一つの三角形に、attributeとしてonStartonMoveを追加しています。

このonStartonMoveは、HtmlのEventsのonInputのようなものです。
onInputでは、StringをMsgと一緒に返していますが、
onStartonMoveでは、DOM全体から見たときのタッチした座標をMsgに乗せて返します。

Msgは次のようになります。

type Msg
    = SingleStart Touch.Coordinates
    | SingleMove Touch.Coordinates
    | ...

Touch.Coordinateは、{clientX : Float, clientY : Float}という形になっているため、あとはこれらの値をupdate内で使ってあげればいい感じになります。

MultiTouch

MultiTouchでも、同様にonStartonMoveなどがあるのですが、SingleTouchとは違い、Touch.Coordinatesではなく、Touch.Eventを返します。

view : Model -> Html Msg
view model =
    div
        [ ...
        , MultiTouch.onStart MultiStart
        , MultiTouch.onMove MultiMove
        ]
        [ ...
        ]
type Msg
    = ...
    | MultiStart Touch.Event
    | MultiMove Touch.Event

このTouch.Eventは、そのままでは扱いづらいので、これを処理する関数もpackageに同梱されています。
それは、Touch.touchesTouch.changedTouchesTouch.targetTouchesの3つです。

これらについて詳細は、次のページに書いてあります。
https://www.html5rocks.com/ja/mobile/touch/
touches: 現在画面上にあるすべての指のリスト。
targetTouches: 現在の DOM 要素上にある指のリスト。
changedTouches: 現在のイベントに関与している指のリスト。たとえば、touchend イベントでは、離れた指のリストになります。

これら3つの関数は、指のリストをDict型で返します。
デモでは、次のように、Dict.valuesでList型に変換して使っています。

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ...

        MultiStart event ->
            let
                ...

                eventPositions =
                    Dict.values <| Touch.touches event

                ...
            in
                ...

        MultiMove event ->
            let
                ...

                eventPositions =
                    Dict.values <| Touch.changedTouches event

                ...
            in
                ...

こんな感じですね。
基本的には、指が触れたときにtouchesでその全部の指の位置を取り値を初期化し、
動いたときにもtouches、離したときその座標を取りたいときはchangedTouchesを使う感じになりそうです。

svgの移動やズームに使っているtransformについては、以下のページがとても参考になりました。
http://defghi1977.html.xdomain.jp/tech/svgMemo/svgMemo_04.htm

まとめ

elm-touch-eventsを使えば、スマホ向けのリッチなwebアプリもElmで作れそうですね。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1