, ,, , ,, , , , image/svg+xml , image/svg+xml , interact.js , image/svg+xml , ,, , ,


function showEventInfo (event) {
  const actionInfo = JSON.stringify(event.interaction.prepared, null, 2)

  event.target.textContent = `action: ${actionInfo} \ncoords: ${event.pageX}, ${event.pageY}`

const interactable = interact('.target')

  listeners: {
    move: showEventInfo,
    onend: showEventInfo,

  .on('dragmove dragend', showEventInfo)
    edges: { left: true, top: true, bottom: true, right: true }
  .on(['resizestart', 'resizemove', 'resizeend'], showEventInfo)
    enabled: true
  .on('gesture', {
    move: showEventInfo,
    end: showEventInfo,
<div>Drag, resize, or perform a multi-touch gesture</div>
.target {
  display: inline-block;
  min-height: 3rem;
  background-color: #29e;
  color: white;
  padding: 1rem;
  border-radius: 0.75rem;
function listener(event) {
  event.target.textContent = `${event.type} at ${event.pageX}, ${event.pageY}`

  .on('dragstart', listener)
  .on('dragmove dragend', listener)
  .on(['resizemove', 'resizeend'], listener)
    gesturestart: listener,
    gestureend: listener,

  onstart: listener,
  onmove: listener,
  onend: listener,

  listeners: [
      start: function (event) {
        console.log(event.type, event.pageX, event.pageY)

InteractEvents are fired for different actions. The event types include:

  • Draggable: dragstart, dragmove, draginertiastart, dragend
  • Resizable: resizestart, resizemove, resizeinertiastart, resizeend
  • Gesturable: gesturestart, gesturemove, gestureend

To respond to InteractEvents, you must add listeners for the event types on an interactable that’s configured for that action. The event object that was created is passed to these functions as the first and only parameter.

InteractEvent properties include the usual properties of mouse/touch events such as pageX/Y, clientX/Y, modifier keys etc. but also some properties providing information about the change in coordinates and event specific data. The table below displays all of these events.


targetThe element that is being interacted with
interactableThe Interactable that is being interacted with
interactionThe Interaction that the event belongs to
x0, y0Page x and y coordinates of the starting event
clientX0, clientY0Client x and y coordinates of the starting event
dx, dyChange in coordinates of the mouse/touch
velocityX, velocityYThe Velocity of the pointer
speedThe speed of the pointer
timeStampThe time of creation of the event object


dragEnterThe dropzone this Interactable was dragged over
dragLeaveThe dropzone this Interactable was dragged out of


edgesThe edges of the element that are being changed
rectAn object with the new dimensions of the target
deltaRectThe change in dimensions since the previous event


distanceThe distance between the event’s first two touches
angleThe angle of the line made by the two touches
daThe change in angle since previous event
scaleThe ratio of the distance of the start event to the distance of the current event
dsThe change in scale since the previous event
boxA box enclosing all touch points

In gesture events, page and client coordinates are the averages of touch coordinates and velocity is calculated from these averages.

Drop Events

    ondrop: function (event) {
      alert(event.relatedTarget.id + ' was dropped into ' + event.target.id)
  .on('dropactivate', function (event) {

Dropzones can receive the following events: dropactivate, dropdeactivate, dragenter, dragleave, dropmove, drop.

The dropzone events are plain objects with the following properties:

targetThe dropzone element
dropzoneThe dropzone Interactable
relatedTargetThe element that’s being dragged
draggableThe Interactable that’s being dragged
dragEventThe related drag event – drag{start,move,end}
timeStampTime of the event
typeThe event type

Pointer Events

interact(target).on('hold', function (event) {
  console.log(event.type, event.target)
  • down
  • move
  • up
  • cancel
  • tap
  • doubletap
  • hold

I call these pointerEvents (with a lower case “p”) because they present the events roughly as the real PointerEvent interface does, specifically:

  • event.pointerId provides the TouchEvent#identifier or PointerEvent#pointerId or undefined for MouseEvents
  • event.pointerType provides the pointer type
  • There are no simulated mouse events after touch events

The properties of the events may vary across browsers and devices depending on which event interfaces are supported. For Example, a down event from a touchstart will not provide tilt or pressure as specified in the PointerEvent interface.

Configuring pointer events

  holdDuration: 1000,
  ignoreFrom: '[no-pointer]',
  allowFrom: '.handle',
  origin: 'self',

pointerEvents are not snapped or restricted, but can be modified with the origin modifications. tap events have a dt property which is the time between the related down and up events. For doubletap dt is the time between the two previous taps. dt for hold events is the length of time that the pointer has been held down for (around 600ms).

Fast click

// fast click
interact('a[href]').on('tap', function (event) {
  window.location.href = event.currentTarget.href

tap and doubletap don’t have the delay that click events have on mobile devices so it works great for fast buttons and anchor links. Also, unlike regular click events, a tap isn’t fired if the pointer is moved before being released.