desandro / draggabilly

:point_down: Make that shiz draggable
https://draggabilly.desandro.com
MIT License
3.86k stars 386 forks source link

Can't scroll vertical on touch device when bound to x-axis #118

Closed xmatthewx closed 6 years ago

xmatthewx commented 8 years ago

I'd like to use draggabilly for a swipe-to-dismiss feature, similar to gmail on Android. I've built a demo and I think that draggabilly performs and feels quite nice. It performs better and required much less code than using hammer.js. However...

When the elements fill the view, you can only scroll by dragging the small space between the elements, even though draggabilly is restricted to the x-axis.

Mobile test case: http://codepen.io/okfuture/pen/KVbYLr?editors=0010

Is there a way to allow default scroll behavior for the y-axis when restricted to x-axis?

desandro commented 8 years ago

Yes, this can be done. See demo http://codepen.io/desandro/pen/LGvYNy

// duck punch Draggabilly
var proto = Draggabilly.prototype;

var pointerMove = proto.pointerMove;
proto.pointerMove = function( event, pointer ) {
  var moveVector = this._dragPointerMove( event, pointer );
  this.touchVerticalScrollMove( event, pointer, moveVector );
  pointerMove.apply( this, arguments );
}

proto.hasDragStarted = function( moveVector ) {
  return !this.isTouchScrolling && Math.abs( moveVector.x ) > 3;
};

proto.canPreventDefaultOnPointerDown = function() {
  return false;
};

var touchScrollEvents = {
  touchmove: true,
  MSPointerMove: true
};

proto.touchVerticalScrollMove = function( event, pointer, moveVector ) {
  var isTouchScrollEvent = touchScrollEvents[ event.type ];
  // start scrolling if touch event and y moved 10px
  if ( this.options.touchVerticalScroll && isTouchScrollEvent &&
      !this.isTouchScrolling && Math.abs( moveVector.y ) > 10 ) {
    this.isTouchScrolling = true;
  }
};

var pointerUp = proto.pointerUp;
proto.pointerUp = function() {
  pointerUp.apply( this, arguments );
  delete this.isTouchScrolling;
};

But now that we have enabled scrolling, users can scroll to the right by dragging an item to the right.

At this point, the logic is different enough that I would consider writing your own Draggabilly-like class on top of Unidragger, rather than re-writing Draggabilly to do it.

xmatthewx commented 8 years ago

Thanks for writing up the demo @desandro! Very much appreciated.