added swipeUp/Down events...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-02-22 00:57:00 +04:00
parent cd9ca4995a
commit 2762c87366
2 changed files with 93 additions and 58 deletions

View File

@ -158,6 +158,7 @@ $(document).ready(function(){
*/ */
.on('swipeLeft', function(evt, data){ .on('swipeLeft', function(evt, data){
// ribbon mode... // ribbon mode...
// XXX make this in a better, more event-oriented way...
if(isNavigationViewRelative()){ if(isNavigationViewRelative()){
setTimeout(function(){ setTimeout(function(){
data.scroller.root.trigger('screenReleased', data)}, 2) data.scroller.root.trigger('screenReleased', data)}, 2)
@ -172,6 +173,7 @@ $(document).ready(function(){
}) })
.on('swipeRight', function(evt, data){ .on('swipeRight', function(evt, data){
// ribbon mode... // ribbon mode...
// XXX make this in a better, more event-oriented way...
if(isNavigationViewRelative()){ if(isNavigationViewRelative()){
setTimeout(function(){ setTimeout(function(){
data.scroller.root.trigger('screenReleased', data)}, 2) data.scroller.root.trigger('screenReleased', data)}, 2)
@ -186,14 +188,16 @@ $(document).ready(function(){
}) })
// do snap and innertia... // do snap and innertia...
// NOTE: this will also handle swipeUp/swopeDown as we do not
// explicitly bind them...
.on('screenReleased', function(evt, data){ .on('screenReleased', function(evt, data){
// this makes things snap... // this makes things snap...
if(SNAP_TO_PAGES_IN_RIBBON){ if(SNAP_TO_PAGES_IN_RIBBON || !isNavigationViewRelative()){
setCurrentPage() setCurrentPage()
return return
} }
var speed = data.speed var speed = data.speed.x
var pages = $('.page') var pages = $('.page')
var mag = $('.magazine') var mag = $('.magazine')
// innertial scroll... // innertial scroll...

View File

@ -509,7 +509,7 @@ var MULTITOUCH_RELEASE_THRESHOLD = 100
// XXX test on other devices... // XXX test on other devices...
// XXX BUG: on landing a second finger while scrolling the things goes // XXX BUG: on landing a second finger while scrolling the things goes
// haywhire... // haywhire...
// XXX BUG: after long click the mouse is tracked and the view is scrolled... // ...check if this is gone...
// XXX split this into a seporate lib... // XXX split this into a seporate lib...
function makeScrollHandler(root, config){ function makeScrollHandler(root, config){
root = $(root) root = $(root)
@ -541,9 +541,10 @@ function makeScrollHandler(root, config){
var max_dy = 0 var max_dy = 0
function startMoveHandler(evt, callback){ function startMoveHandler(evt, callback){
var options = scroller.options
// ignore... // ignore...
if(scroller.options.ignoreElements if(options.ignoreElements
&& $(evt.target).closest(scroller.options.ignoreElements).length > 0){ && $(evt.target).closest(options.ignoreElements).length > 0){
ignoring = true ignoring = true
return return
} else { } else {
@ -552,7 +553,7 @@ function makeScrollHandler(root, config){
if(event.touches != null){ if(event.touches != null){
touch = true touch = true
} }
cancelThreshold = scroller.options.scrollCancelThreshold cancelThreshold = options.scrollCancelThreshold
touches = touch ? event.touches.length : 1 touches = touch ? event.touches.length : 1
// if we are already touching then just skip on this... // if we are already touching then just skip on this...
// XXX test this... // XXX test this...
@ -561,12 +562,12 @@ function makeScrollHandler(root, config){
} }
prev_t = event.timeStamp || Date.now(); prev_t = event.timeStamp || Date.now();
start_t = prev_t start_t = prev_t
if(scroller.options.autoCancelEvents){ if(options.autoCancelEvents){
bounds = { bounds = {
left: scroller.options.eventBounds, left: options.eventBounds,
right: root.width() - scroller.options.eventBounds, right: root.width() - options.eventBounds,
top: scroller.options.eventBounds, top: options.eventBounds,
bottom: root.height() - scroller.options.eventBounds bottom: root.height() - options.eventBounds
} }
} }
//togglePageDragging('on') //togglePageDragging('on')
@ -575,7 +576,7 @@ function makeScrollHandler(root, config){
// XXX these two are redundant... // XXX these two are redundant...
scrolling = true scrolling = true
scroller.state = 'scrolling' scroller.state = 'scrolling'
scroller.options.enabelStartEvent && root.trigger('userScrollStart') options.enabelStartEvent && root.trigger('userScrollStart')
shift = getElementShift(scrolled) shift = getElementShift(scrolled)
scale = getElementScale(scrolled) scale = getElementScale(scrolled)
@ -597,6 +598,7 @@ function makeScrollHandler(root, config){
if(ignoring){ if(ignoring){
return return
} }
var options = scroller.options
evt.preventDefault() evt.preventDefault()
t = event.timeStamp || Date.now(); t = event.timeStamp || Date.now();
// get the user coords... // get the user coords...
@ -605,21 +607,22 @@ function makeScrollHandler(root, config){
touches = touch ? event.touches.length : 1 touches = touch ? event.touches.length : 1
// XXX needs testing... // XXX needs testing...
// XXX do we need to account for scrollDisabled here???
// check scroll bounds... // check scroll bounds...
if(bounds != null){ if(bounds != null){
if(scroller.options.hScroll && (x <= bounds.left || x >= bounds.right) if(options.hScroll && (x <= bounds.left || x >= bounds.right)
|| scroller.options.vScroll && (y <= bounds.top || y >= bounds.bottom)){ || options.vScroll && (y <= bounds.top || y >= bounds.bottom)){
// XXX cancel the touch event and trigger the end handler... // XXX cancel the touch event and trigger the end handler...
return endMoveHandler(evt) return endMoveHandler(evt)
} }
} }
// do the actual scroll... // do the actual scroll...
if(scrolling){ if(!options.scrollDisabled && scrolling){
if(scroller.options.hScroll){ if(options.hScroll){
shift.left += x - prev_x shift.left += x - prev_x
} }
if(scroller.options.vScroll){ if(options.vScroll){
shift.top += y - prev_y shift.top += y - prev_y
} }
setElementTransform(scrolled, shift, scale) setElementTransform(scrolled, shift, scale)
@ -635,7 +638,7 @@ function makeScrollHandler(root, config){
prev_y = y prev_y = y
prev_t = t prev_t = t
scroller.options.enableUserScrollEvent && root.trigger('userScroll') options.enableUserScrollEvent && root.trigger('userScroll')
} }
return false return false
} }
@ -649,10 +652,11 @@ function makeScrollHandler(root, config){
} }
return return
} }
var options = scroller.options
// XXX get real transition duration... // XXX get real transition duration...
scroller.resetTransitions() scroller.resetTransitions()
//setTransitionDuration(scrolled, scroller.options.transitionDuration) //setTransitionDuration(scrolled, options.transitionDuration)
x = touch ? event.changedTouches[0].pageX : evt.clientX x = touch ? event.changedTouches[0].pageX : evt.clientX
y = touch ? event.changedTouches[0].pageY : evt.clientY y = touch ? event.changedTouches[0].pageY : evt.clientY
@ -665,22 +669,29 @@ function makeScrollHandler(root, config){
scroller.state = 'canceling' scroller.state = 'canceling'
} }
var data = {
orig_event: evt,
scroller: scroller,
speed: {
x: dx/dt,
y: dy/dt
},
distance: {
x: start_x-x,
y: start_y-y
},
duration: t-start_t,
// current touches...
touches: touches,
clicks: null,
}
// XXX stop only if no fingers are touching or let the callback decide... // XXX stop only if no fingers are touching or let the callback decide...
//togglePageDragging('off') //togglePageDragging('off')
scroller.options.enableEndEvent && root.trigger('userScrollEnd', dx, dy, dt, start_x, start_y) // XXX update this with the new data model!!! (see below)
if(scroller.options.callback options.enableEndEvent && root.trigger('userScrollEnd', data)
if(options.callback
// XXX revise this.... // XXX revise this....
// call the callback... && options.callback(data) === false
&& scroller.options.callback({
orig_event: evt,
scroller: scroller,
speed: dx/dt,
distance: start_x-x,
duration: t-start_t,
// current touches...
touches: touches,
clicks: null,
}) === false
|| touches == 0){ || touches == 0){
// cleanup and stop... // cleanup and stop...
touch = false touch = false
@ -705,6 +716,13 @@ function makeScrollHandler(root, config){
hScroll: true, hScroll: true,
vScroll: true, vScroll: true,
// this will disable scroll.
// NOTE: this is the same as setting both vScroll and hScroll
// to false, but can be set and reset without affecting
// the actual settings individually...
// NOTE: this takes priority over hScroll/vScroll.
scrollDisabled: false,
// sets the default transition settings while not scrolling... // sets the default transition settings while not scrolling...
transitionDuration: 200, transitionDuration: 200,
transitionEasing: 'ease', transitionEasing: 'ease',
@ -730,8 +748,11 @@ function makeScrollHandler(root, config){
// NOTE: if this returns false explicitly, this will stop scrolling. // NOTE: if this returns false explicitly, this will stop scrolling.
callback: postScrollCallback, callback: postScrollCallback,
// These are used by the default callback... // These are used by the default callback...
enableMultiClicks: false, enableMultiClicks: false,
// NOTE: if these are null, respective values from the env will
// be used.
clickThreshold: null, clickThreshold: null,
longClickThreshold: null, longClickThreshold: null,
multiClickTimeout: null, multiClickTimeout: null,
@ -792,6 +813,8 @@ function makeScrollHandler(root, config){
return scroller return scroller
} }
// default callback... // default callback...
// This will provide support for the folowing events on the scroll root // This will provide support for the folowing events on the scroll root
// element: // element:
@ -803,26 +826,25 @@ function makeScrollHandler(root, config){
// - longClick // - longClick
// - swipeLeft // - swipeLeft
// - swipeRight // - swipeRight
// - swipeUp
// - swipeDown
// - screenReleased // - screenReleased
// //
// NOTE: data.touches passed to the event is the number of touches // NOTE: data.touches passed to the event is the number of touches
// released within the multitouchTimeout. // released within the multitouchTimeout.
// this differs from what postScrollCallback actually gets in the // this differs from what postScrollCallback actually gets in the
// same field when it recieves the object. // same field when it recieves the object.
//
// XXX add up/down swipes
// XXX add double clicks
// XXX add generic snap // XXX add generic snap
// XXX add generic innertial scroll // XXX add generic innertial scroll
function postScrollCallback(data){ function postScrollCallback(data){
var scroller = data.scroller var scroller = data.scroller
var options = scroller.options
var root = scroller.root var root = scroller.root
var clickThreshold = scroller.options.clickThreshold || CLICK_THRESHOLD var clickThreshold = options.clickThreshold || CLICK_THRESHOLD
var longClickThreshold = scroller.options.longClickThreshold || LONG_CLICK_THRESHOLD var longClickThreshold = options.longClickThreshold || LONG_CLICK_THRESHOLD
var multitouchTimeout = scroller.options.multitouchTimeout || MULTITOUCH_RELEASE_THRESHOLD var multitouchTimeout = options.multitouchTimeout || MULTITOUCH_RELEASE_THRESHOLD
var enableMultiClicks = options.enableMultiClicks
var enableMultiClicks = scroller.options.enableMultiClicks var multiClickTimeout = options.multiClickTimeout || MULTI_CLICK_TIMEOUT
var multiClickTimeout = scroller.options.multiClickTimeout || MULTI_CLICK_TIMEOUT
var now = Date.now(); var now = Date.now();
@ -831,8 +853,7 @@ function postScrollCallback(data){
return root.trigger('scrollCancelled', data) return root.trigger('scrollCancelled', data)
} }
// ignore situations when the user is still touching... // handle multiple touches...
// ...like when he/she lifted one finger of several...
// XXX needs testing... // XXX needs testing...
if(data.touches > 0){ if(data.touches > 0){
var then = scroller._last_touch_release var then = scroller._last_touch_release
@ -848,15 +869,18 @@ function postScrollCallback(data){
// wait for the next touch release... // wait for the next touch release...
scroller._last_touch_release = now scroller._last_touch_release = now
return return
// calculate how many touches did participate... // calculate how many touches did participate...
} else { } else {
data.touches = scroller._touches + 1 data.touches = scroller._touches ? scroller._touches + 1 : 1
scroller._last_touch_release = null scroller._last_touch_release = null
scroller._touches = null scroller._touches = null
} }
// clicks, double clicks and long clicks... // clicks, double-clicks, multi-clicks and long-clicks...
if(Math.abs(data.distance) < clickThreshold){ if(Math.max(
Math.abs(data.distance.x),
Math.abs(data.distance.y)) < clickThreshold){
if(data.duration > longClickThreshold){ if(data.duration > longClickThreshold){
return root.trigger('longClick', data) return root.trigger('longClick', data)
} }
@ -890,23 +914,30 @@ function postScrollCallback(data){
scroller._clicks = null scroller._clicks = null
scroller._click_timeout_id = null scroller._click_timeout_id = null
}, multiClickTimeout) }, multiClickTimeout)
return
} }
} }
// left/right swipes... // swipes...
// XXX add up/down support... // XXX make these less brain dead...
// XXX check if these are bound... // ...when all is OK also call screenReleased (chain events)
if(data.distance <= -clickThreshold){ // also would be nice to add a generic swipe event...
return root.trigger('swipeLeft', data) if(Math.abs(data.distance.x) > Math.abs(data.distance.y)){
} if(data.distance.x <= -clickThreshold && root.data('events').swipeLeft){
if(data.distance >= clickThreshold){ return root.trigger('swipeLeft', data)
return root.trigger('swipeRight', data) } else if(data.distance.x >= clickThreshold && root.data('events').swipeRight){
return root.trigger('swipeRight', data)
}
} else {
if(data.distance.y <= -clickThreshold && root.data('events').swipeUp){
return root.trigger('swipeUp', data)
} else if(data.distance.y >= clickThreshold && root.data('events').swipeDown){
return root.trigger('swipeDown', data)
}
} }
// XXX snap... // this is triggered of no swipes were handled...
// XXX innertial scroll...
// XXX this may never get called directly....
return root.trigger('screenReleased', data) return root.trigger('screenReleased', data)
} }