If upgrading from elm-mouse-events or elm-touch-events, please read the upgrade notes. Otherwise, if upgrading from elm-pointer-events 2.0.0, reading the CHANGELOG should be enough.
import Html.Events.Extra.Pointer as Pointer
-- ... example usage
div [ Pointer.onDown (\event -> PointerDownMsg event.pointer.offsetPos) ] [ text "click here" ]
This package aims at handling all kinds of pointer events in elm. To be more specific, this means:
MouseEvent
: standard mouse eventsWheelEvent
: standard wheel eventsDragEvent
: HTML5 drag eventsTouchEvent
: standard touch eventsPointerEvent
: new pointer events
If you are looking for only one standard kind of interaction (mouse or touch),
I recommend that you use the Mouse
or Touch
modules.
If however, you are designing a multi-device (desktop/tablet/mobile/...) experience,
I recommend that you use the Pointer
module.
Pointer events are a unified interface for similar input devices (mouse, pen, touch, ...). Since maintaining both mouse and touch events for compatibility is really cumbersome, using a unified pointer events interface is a relief.
Beware though, that the pointer API is not well supported by all browsers. Firefox < 59 and Safari do not natively support pointer events. So I strongly recommend to use this package in pair with the elm-pep polyfill for compatibility with major browsers.
The Mouse
and Pointer
modules have very similar API
so I will use Mouse
as an example.
Let's say you want the coordinates of a mouse down event relative to the DOM
element that triggered it.
In JavaScript, these are provided by the offsetX
and offsetY
properties
of the mouse event.
Using this module, these are similarly provided by the offsetPos
attribute
of a mouse Event
:
import Html.Events.Extra.Mouse as Mouse
-- ...
type Msg
= MouseDownAt ( Float, Float )
view =
div
[Mouse.onDown (\event -> MouseDownAt event.offsetPos)]
[text "click here"]
If you are using the Pointer
module,
it is recommended that you deactivate touch-action
to disable browsers scroll/pinch/... touch behaviors.
Also, if you are designing some kind of drawing application,
you want to be able to keep track of a pointer that leave the
drawing area to know if the pointer went up.
This is possible using what is called pointer capture.
But requires the use of ports. Look at examples/Pointer/
if you are interested in how to do this.
div
[ Pointer.onDown ...
, Pointer.onMove ...
, Pointer.onUp ...
-- no touch-action
, Html.Attributes.style "touch-action" "none"
]
[ -- the drawing area
]
Multi-touch interactions can be managed using the Touch
module.
In case you only want to handle single touch interactions,
you could do something like below:
import Html.Events.Extra.Touch as Touch
-- ...
type Msg
= StartAt ( Float, Float )
| MoveAt ( Float, Float )
| EndAt ( Float, Float )
view =
div
[ Touch.onStart (StartAt << touchCoordinates)
, Touch.onMove (MoveAt << touchCoordinates)
, Touch.onEnd (EndAt << touchCoordinates)
]
[text "touch here"]
touchCoordinates : Touch.Event -> ( Float, Float )
touchCoordinates touchEvent =
List.head touchEvent.changedTouches
|> Maybe.map .clientPos
|> Maybe.withDefault ( 0, 0 )
You can manage Wheel
events with the corresponding module.
Since it is an extension to the Mouse
module all mouse inherited properties
are also available in the attribute mouseEvent
.
To simply check for wheel rolling up or down you could do something like below:
import Html.Events.Extra.Wheel as Wheel
-- ...
type Msg
= Scrolling Float
view =
div
[Wheel.onWheel (\event -> Scrolling event.deltaY)]
[text "scroll here"]
The API presented by this package is slightly opinionated, to mitigate most errors induced by the complicated HTML5 drag events. This API is organized around two use cases:
- Dropping files from OS
- Drag and drop of DOM elements
For dropping files, everything can be done purely in elm so the API reflects that.
For drag and drop however some events require JavaScript function calls.
Consequently it requires the use of ports.
Two files, DragPorts.js
and Ports.elm
are provided in the source code
of this repo to help setup things.
More info is available in the module documentation.
One example for each use case is present in the examples/
directory.
Minimalist working examples are available for each module in the examples/
directory.
To test one example, cd
into one of them and compile the elm file with the command:
elm make Main.elm --output Main.js
Then use any static http server like:
$ python3 -m http.server 8888
And open your browser at localhost:8888
to load the index.html
page.
If you are interested in contributing in any way (feedback, bug report, implementation of new functionality, ...) don't hesitate to reach out on slack (user @mattpiz) and/or open an issue. Discussion is the best way to start any contribution.
The package documentation is available on the elm package website.
This Source Code Form is subject to the terms of the Mozilla Public License,v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.