Interaction Pattern

Since the correct handling of the divergent browser specific multitouch implementations is a difficult and recurring task we decided to encapsulate all related handlers for TouchEvent (WebKit, Mozilla) and PointerEvent (IE, Edge, Chrome) in a single delegate pattern.

The main differences are that PointerEvent are fired for each touch point, whereas the TouchEvent collects multiple TouchPoints into a single event. The basic PointMap and Interaction classes unify this behavior by collection all contact points regardless of their original mouse, touch, or pointer events.

Point Maps

The touch and pointer positions are collected in PointMaps which provide access to the positions via stringified touch and pointer ids. For mouse events the special id "mouse" is used. PointMaps can be cloned and pretty printed. In addition they provide auxiliary methods like mean and farthests which can be used to simplify the computation of gestures. In general mean can be used to compute the "center of interaction", i.e. the best guess of the anchor point for rotation and scaling operations.

If more than two touch points are involved it may be best to look for the pair of points which are farthest away from each other. These points will represent the fingers farthest away from each other, a more simple substitute for 3, 4 or 5 touch points. Here we add a third point to our example touches and test whether the maximal distant points are found:

Interaction Points and Interactions

Events and points change in time and gestures are computed from this dynamic behavior. To collect theses changes and to simplify the computation of gestures we collect PointMaps in a composite class InteractionPoints, which distinguishes start, current, previous, and ended point coordinates as well as the start timestamps.

Interaction objects extend the idea of mapping touch ids to points to multiple target objects. Each touch id is mapped not only to the changing points of this touch but also to the object that has been hit by the starting touch point. This object is the target of the interaction and remains for the whole duration of the multitouch gesture.

Interaction Delegate

The delegator registers all needed TouchEvent, PointerEvent, and MouseEvent handlers on a provided DOM elememt for a given target object, ensures that the events are captured by the target and boils the event handling down to simple onStart, onMove, onEnd events.

Let's look at an example of an InteractionDelegate and a target object that implements the IInteractionTarget interface. Typically you setup the delegator in the constructor of the class that uses the interation.

We can now check whether the promised interface methods are implemented by the class:

If we define an InteractionTarget that violates the IInteractionTarget interface we get an error. The following example of an interaction target uses an InteractionDelegate but does not implement the necessary methods:

Interaction Mapper

Often we need to assign UI elements to touch and pointer events. This is supported by a special InteractionMapper delegate. A InteractionMapper maps events to specific parts of a container interaction target. The InteractionTarget must implement a findTarget method that returns an object implementing the IInteractionTarget interface.

If the InteractionTarget also implements a mapPositionToPoint method this is used to map the points to the local coordinate space of the the target. This makes it easier to lookup elements and relate events to local positions.

Let's see an example. A graph that uses an InterationMapper for it´s child objects:

Now we simulate a sequence of onStart, onMove, onEnd events by calling the registered event handlers programmatically. Note that the defined event handlers log their calls.

Simple Dragging

Drag & Drop is a common interaction pattern. This behavior can be accomplished by a class that implements IInteractionMapperTarget as well as IInteractionTarget. You can grab the blue circle with touches or mouse and drag it around.

Multitouch

Multitouch-Events (simultaneous events) in browsers cannot be used by default. Even libraries like jQuery do not fix this problem. The static method "on" of the InteractionMapper allows simultaneous events and thus multitouch. The following events (and their specializations) can be used in addition to the default browser events: tap, doubletap, press, pan, swipe, pinch and rotate. See http://hammerjs.github.io for more details.

tap press pan swipe pinch rotate rotate

References