Swipe to Dismiss with Tabris.js

March 23, 2015 | 4 min Read

Swipe-to-dismiss is a common pattern in mobile apps. With a quick swipe of the finger an item can be removed from a list. This intuitive pattern is used in the e-mail applications of Android and iOS and in the app switcher of most mobile operating systems. With the new gesture support in Tabris.js 0.9.3 you will be able to implement this feature in your apps.

The Anatomy of Dismissal

Technically, the gesture is not just a simple swipe. There is more to it to make the user experience fluent and natural.

One important point is the touch feedback: a gesture without visual feedback feels broken. To make the user naturally aware that a swipe-to-dismiss gesture was triggered, the content to be dismissed usually moves along with the finger initiating the gesture.

To let the user cancel the gesture it is a good idea to implement a distance threshold beyond which the dismissal gesture is detected – e.g. if the user swipes the content item more than half of its container length, the gesture is accepted, otherwise it gets cancelled upon lifting the finger. This would make those users happy who like to change their mind or have mistakenly started swiping on the wrong item.

Only implementing a distance threshold is not enough for a great user experience though. Imagine having 10+ emails to delete: this means using the dismissal gesture on each one of them. Swiping each item through half the width of the screen would be an annoying occupation for the next couple of seconds. The fling gesture can make the task much more fun:

Flinging fast enough with your finger on the item can serve as an alternative way to trigger the dismissal. Flinging can be detected by evaluating the gesture’s velocity.

Swipe-to-Dismiss in Tabris.js

Tabris.js has a gesture API which exposes rich gesture data to JavaScript. One of the gestures is pan, which can be used to implement swipe-to-dismiss in Tabris.js. It is triggered on each movement of a finger when you touch a widget with the pan listener. This is what the event data may look like (values have been rounded to improve readability):

{
  state: "start",
  touches: [{x: 420, y: 52}],
  velocity: {x: -287, y: 68},
  translation: {x: -11, y: 4}
}

translation gives information about the touch offset during each movement, which can be set on the transform property of the container holding the CollectionView item widgets:

container.on("pan:horizontal", function(event) {
  this.set("transform", {translationX: event.translation.x});
});

This will make the item move along with the finger.

Determining whether the gesture was successful or not can be done when a pan event with the state end is fired. This means the pan gesture was completed:

container.on("pan:horizontal", function(event) {
  this.set("transform", {translationX: event.translation.x});
  if (event.state === "end") {
    handlePanFinished(event, container);
  }
});

function handlePanFinished(event, container) {
  var translation = Math.abs(event.translation.x);
  var velocity = Math.abs(event.velocity.x);
  var bounds = container.get("bounds");
  if (translation > bounds.width / 2 || velocity > 700) {
    animateDismiss(event, container, bounds);
  } else {
    animateCancel(event, container);
  }
}

In this example we determine whether the translation goes beyond the half of the container’s width or if the velocity of the gesture exceeds the specified threshold. If one of these is the case, a dismissal animation is executed and the CollectionView item gets removed. If these conditions are not met, the gesture is cancelled, and we animate the container’s translationX property back to its original value (0).

If you are interested in implementing swipe-to-dismiss in your Tabris.js application, you should check out the complete Tabris.js example in which we demonstrate the “core” swipe-to-dismiss functionality. It will be available in Tabris.js 0.9.3. If it doesn’t fulfill your needs, feel free to spice it up the way you want! The gesture API should be powerful enough to let you build even the most sophisticated swipe-to-dismiss solutions. Tabris.js puts the control in your hands and doesn’t limit you to an inflexible pre-made API just for this use case.

If you want to start playing with the code, go to tabrisjs.com and request an invite to the developer preview. Also, don’t forget to follow @tabrisjs on Twitter!

Christian Petrov

Christian Petrov

Christian is a working student at EclipseSource. He has worked on several Tabris.js apps, and has contributed to the Tabris.js framework development since its inception. …