Skip to content

UFX.pointer: handle both mouse and touch events

Christopher Night edited this page Mar 12, 2024 · 2 revisions

Quick usage example

let pointer = UFX.pointer(document.body)
if (pointer.click) handle_click_at(pointer.pos)

Overview

Call UFX.pointer once a frame, passing in an HTML DOM element, such as document.body or a canvas. UFX.pointer will capture mouse and touch events on the given element, and return an object that represents the events since the previous frame (or since the last time UFX.pointer was called).

UFX.pointer is not appropriate for very complex UI designs. It does not try to report all events with 100% accuracy. Certain edge cases will be dropped, such as right-clicking while the left mouse button is held down, or tapping while another finger is held down.

Event model

When a mouse button is pressed and then unpressed, a series of events is generated. There are two main possibilities:

  • down -> click + up
  • down -> hold -> move -> move -> ... -> up

If button is held down for enough time (0.5 seconds) or moves by enough distance (5 pixels), then a hold event occurs and UFX.pointer starts treating it as a drag, dispatching a move event every frame that the mouse moves by at least 1 pixel. Small movements of less than 5 pixels that occur before the hold event do not generate move events.

The value of isdown is true between the down and up events. The value of isheld is true between the hold and up events.

In addition, at any point after a down event, a cancel event may occur. For example if you right click while holding the left mouse button. In this case no further events (up, click, hold, or move) will occur until the next down event.

Event prefixes

Left mouse button and single-finger touch events both generate non-prefixed event names (such as pointer.down). Middle-button (pointer.mdown, etc.), right-button (pointer.rdown, etc.), and two-finger (pointer.dclick, etc.) events are also reported with the m, r, and d prefixes.

Mouse wheel

Multitouch

Return value fields

The return value from UFX.pointer is a JSON-able object with information on all events that have occurred since the last call to UFX.pointer. I'll call it pointer for this section.

let pointer = UFX.pointer(canvas)

In order to reduce space when JSONing, any fields that are falsy are omitted. For example when the middle mouse button is not being held, then pointer.mheld is undefined rather than false.

pointer.pos

The last known (x, y) position of the mouse, with respect to the top-left corner of the DOM element that was passed to UFX.pointer.

pointer.within

pointer.click (pointer.mclick, pointer.rclick, pointer.dclick)

pointer.down (pointer.mdown, pointer.rdown, pointer.ddown)

pointer.up (pointer.mup, pointer.rup, pointer.dup)

pointer.move (pointer.mmove, pointer.rmove, pointer.dmove)

pointer.hold (pointer.mhold, pointer.rhold, pointer.dhold)

pointer.cancel (pointer.mcancel, pointer.rcancel, pointer.dcancel)

pointer.isdown (pointer.misdown, pointer.risdown, pointer.disdown)

pointer.isheld (pointer.misheld, pointer.risheld, pointer.disheld)

pointer.wheel

pointer.pinch

UFX.pointer options

To change an option from its default value, simply assign to it at any time:

UFX.pointer.allowcontextmenu = true

UFX.pointer.roundpos (default: true)

UFX.pointer.allowcontextmenu (default: false)

Whether to allow the browser default behavior of opening the context menu on a right-click.

UFX.pointer.thold (default: 0.5)

Time in seconds that a mouse button can be depressed before generating a hold event and being considered "held".

UFX.pointer.rhold (default: 5)

Distance in pixels that the mouse can move while a button is depressed before generating a hold event and being considered "held".

UFX.pointer.spinch (default: 0)

UFX.pointer.lpinch (default: 0.25)

UFX.pointer.atilt (default: 10)

Other attributes

UFX.pointer.touch

UFX.pointer.pos

UFX.pointer.within