OnsenUI icon indicating copy to clipboard operation
OnsenUI copied to clipboard

ons-gesture-detector swipe left/right timing

Open nickredding opened this issue 6 years ago • 0 comments

Swiping left/right with ons-gesture-detector seems laggy because the swipe event isn't fired until the gesture ends. Both jQuery Mobile and hammer.js will fire swipe events after the swipe has covered a minimum distance at a minimum rate. This makes the swipe feel responsive because the transition can start as soon as it's clear there is a swipe in progress.

The following adjustment to gesture-detector.js accomplishes this. I think it would be worthwhile to add this as an optional (parameterized) behaviour to onsenui. BTW dropping swipeVelocity from 0.6 to 0.3 is also worthwhile.


GestureDetector.gestures.Swipe = {
  name: 'swipe',
  index: 40,
  defaults: {
    /**
     * @property swipeMinTouches
     * @type {Number}
     * @default 1
     */
    swipeMinTouches: 1,

    /**
     * @property swipeMaxTouches
     * @type {Number}
     * @default 1
     */
    swipeMaxTouches: 1,

    /**
     * horizontal swipe velocity
     * @property swipeVelocityX
     * @type {Number}
     * @default 0.6
     */
    swipeVelocityX: 0.6,

    /**
     * vertical swipe velocity
     * @property swipeVelocityY
     * @type {Number}
     * @default 0.6
     */
    swipeVelocityY: 0.6,
	
	/* suggested change to enable better swipe responsiveness */
	/* swipeVelocity should also be lowered to 0.3 */
	swipeRequireRelease: false,
	minSwipeDeltaX: 30,
	nimSwipeDeltaY: 30
  },

  handler: function swipeGesture(ev, inst) {
	var touches = ev.touches.length,
	  options = inst.options;
    if (ev.eventType == EVENT_RELEASE || (!options.swipeRequireRelease && ev.eventType == EVENT_MOVE)) {

      // max touches
      if (touches < options.swipeMinTouches || touches > options.swipeMaxTouches) {
        return;
      }

      // when the distance we moved is too small we skip this gesture
      // or we can be already in dragging
      if ((ev.velocityX > options.swipeVelocityX && ev.deltaX > options.minSwipeDeltaX) || (ev.velocityY > options.swipeVelocityY && ev.deltaY > options.minSwipeDeltaY)) {
        // trigger swipe events
        inst.trigger(this.name, ev);
        inst.trigger(this.name + ev.direction, ev);
		if (ev.eventType == EVENT_MOVE) {
			ev.stopDetect();
		}
      }
    }
  }
};

nickredding avatar Aug 26 '19 21:08 nickredding