started on multitouch support...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-02-20 05:02:09 +04:00
parent d0f4d57c5b
commit 65796d8150
3 changed files with 199 additions and 191 deletions

View File

@ -117,7 +117,10 @@ $(document).ready(function(){
window.MagazineScroller = makeScrollHandler($('.viewer'), { window.MagazineScroller = makeScrollHandler($('.viewer'), {
hScroll: true, hScroll: true,
vScroll: false, vScroll: false,
callback: function(speed, distance){ callback: function(speed, distance, touches){
if(touches > 0){
return true
}
// XXX this is not too correct... // XXX this is not too correct...
// ...make this mode specific... // ...make this mode specific...
if(getMagazineScale() >= 1){ if(getMagazineScale() >= 1){

190
layout.js
View File

@ -74,196 +74,6 @@ var togglePageView = createCSSClassToggler(
/************************************************** event handlers ***/ /************************************************** event handlers ***/
// XXX make this more universal...
// - h/v scroll
// - general configuration
// - optional events...
// XXX should we use a callback or an event???
// XXX make this get the scrolled item automatically...
// ...now $('.magazine') is hardcoded...
function makeScrollHandler(root, config){
root = $(root)
// local data...
var scrolled
var scrolling = false
var touch = false
var touches = 0
var start_x
var start_y
var prev_x
var prev_y
var prev_t
var bounds
var shift
var scale
var x
var y
var t
var dx
var dy
var dt
function startMoveHandler(evt, callback){
prev_t = event.timeStamp || Date.now();
if(scroller.options.autoCancelEvents){
bounds = {
left: scroller.options.eventBounds,
right: root.width() - scroller.options.eventBounds,
top: scroller.options.eventBounds,
bottom: root.height() - scroller.options.eventBounds
}
}
scrolled = $(root.children()[0])
setTransitionDuration(scrolled, 0)
if(event.touches != null){
touch = true
}
scrolling = true
scroller.state = 'scrolling'
scroller.options.enabelStartEvent && root.trigger('userScrollStart')
//togglePageDragging('on')
shift = getElementShift(scrolled)
scale = getElementScale(scrolled)
// get the user coords...
prev_x = touch ? event.touches[0].pageX : evt.clientX
start_x = prev_x
prev_y = touch ? event.touches[0].pageY : evt.clientY
start_y = prev_y
return false
}
// XXX add limits to this...
// XXX slow down drag when at limit...
// XXX try and make this adaptive to stay ahead of the lags...
function moveHandler(evt){
evt.preventDefault()
t = event.timeStamp || Date.now();
// get the user coords...
x = touch ? event.touches[0].pageX : evt.clientX
y = touch ? event.touches[0].pageY : evt.clientY
touches = touch ? event.touches.length : 0
// XXX needs testing...
// check scroll bounds...
if(bounds != null){
if(scroller.options.hScroll && (x <= bounds.left || x >= bounds.right)
|| scroller.options.vScroll && (y <= bounds.top || y >= bounds.bottom)){
// XXX cancel the touch event and trigger the end handler...
return endMoveHandler(evt)
}
}
// do the actual scroll...
if(scrolling){
if(scroller.options.hScroll){
shift.left += x - prev_x
}
if(scroller.options.vScroll){
shift.top += y - prev_y
}
setElementTransform(scrolled, shift, scale)
// XXX these should be done every time the event is caught or
// just while scrolling?
dx = x - prev_x
dy = y - prev_y
dt = t - prev_t
prev_x = x
prev_y = y
prev_t = t
scroller.options.enableUserScrollEvent && root.trigger('userScroll')
}
return false
}
function endMoveHandler(evt){
// XXX get real transition duration...
setTransitionDuration($('.magazine'), 200)
x = touch ? event.changedTouches[0].pageX : evt.clientX
y = touch ? event.changedTouches[0].pageY : evt.clientY
touch = false
scrolling = false
scroller.state = 'waiting'
touches = 0
bounds = null
//togglePageDragging('off')
scroller.options.enableEndEvent && root.trigger('userScrollEnd', dx, dy, dt, start_x, start_y)
scroller.options.callback && scroller.options.callback(dx/dt, start_x-x)
return false
}
var scroller = {
options: {
hScroll: true,
vScroll: true,
enabelStartEvent: false,
enableUserScrollEvent: false,
enableEndEvent: false,
autoCancelEvents: false,
eventBounds: 5,
callback: null
},
start: function(){
this.state = 'waiting'
// XXX STUB: this makes starting the scroll a bit sluggish,
// find a faster way...
//togglePageDragging('on')
// NOTE: if we bind both touch and mouse events, on touch devices they
// might start interfering with each other...
if('ontouchmove' in window){
root
.on('touchstart', startMoveHandler)
.on('touchmove', moveHandler)
.on('touchend', endMoveHandler)
.on('touchcancel', endMoveHandler)
} else {
root
.on('mousedown', startMoveHandler)
.on('mousemove', moveHandler)
.on('mouseup', endMoveHandler)
}
return this
},
stop: function(){
this.state = 'stopped'
if('ontouchmove' in window){
root
.off('touchstart', startMoveHandler)
.off('touchmove', moveHandler)
.off('touchend', endMoveHandler)
} else {
root
.off('mousedown', startMoveHandler)
.off('mousemove', moveHandler)
.off('mouseup', endMoveHandler)
}
return this
},
// XXX check...
setCallback: function(func){
this.callback = func
},
// NOTE: this is updated live but not used by the system in any way...
state: 'stopped'
}
// merge the config with the defaults...
if(config != null){
$.extend(scroller.options, config)
}
return scroller
}
/********************************************************* helpers ***/ /********************************************************* helpers ***/
// XXX make this more acurate... // XXX make this more acurate...

View File

@ -488,6 +488,201 @@ function makeKeyboardHandler(keybindings, unhandled){
// XXX handle multiple fingers...
// XXX setup basic styles for the contained element...
// XXX revise...
// XXX test on other devices...
function makeScrollHandler(root, config){
root = $(root)
// local data...
var scrolled
var scrolling = false
var touch = false
var touches = 0
var start_x
var start_y
var prev_x
var prev_y
var prev_t
var bounds
var shift
var scale
var x
var y
var t
var dx
var dy
var dt
function startMoveHandler(evt, callback){
prev_t = event.timeStamp || Date.now();
if(scroller.options.autoCancelEvents){
bounds = {
left: scroller.options.eventBounds,
right: root.width() - scroller.options.eventBounds,
top: scroller.options.eventBounds,
bottom: root.height() - scroller.options.eventBounds
}
}
scrolled = $(root.children()[0])
setTransitionDuration(scrolled, 0)
if(event.touches != null){
touch = true
}
scrolling = true
scroller.state = 'scrolling'
scroller.options.enabelStartEvent && root.trigger('userScrollStart')
//togglePageDragging('on')
shift = getElementShift(scrolled)
scale = getElementScale(scrolled)
// get the user coords...
prev_x = touch ? event.touches[0].pageX : evt.clientX
start_x = prev_x
prev_y = touch ? event.touches[0].pageY : evt.clientY
start_y = prev_y
return false
}
// XXX add limits to this...
// XXX slow down drag when at limit...
// XXX try and make this adaptive to stay ahead of the lags...
function moveHandler(evt){
evt.preventDefault()
t = event.timeStamp || Date.now();
// get the user coords...
x = touch ? event.touches[0].pageX : evt.clientX
y = touch ? event.touches[0].pageY : evt.clientY
touches = touch ? event.touches.length : 0
// XXX needs testing...
// check scroll bounds...
if(bounds != null){
if(scroller.options.hScroll && (x <= bounds.left || x >= bounds.right)
|| scroller.options.vScroll && (y <= bounds.top || y >= bounds.bottom)){
// XXX cancel the touch event and trigger the end handler...
return endMoveHandler(evt)
}
}
// do the actual scroll...
if(scrolling){
if(scroller.options.hScroll){
shift.left += x - prev_x
}
if(scroller.options.vScroll){
shift.top += y - prev_y
}
setElementTransform(scrolled, shift, scale)
// XXX these should be done every time the event is caught or
// just while scrolling?
dx = x - prev_x
dy = y - prev_y
dt = t - prev_t
prev_x = x
prev_y = y
prev_t = t
scroller.options.enableUserScrollEvent && root.trigger('userScroll')
}
return false
}
function endMoveHandler(evt){
// XXX get real transition duration...
setTransitionDuration($('.magazine'), 200)
x = touch ? event.changedTouches[0].pageX : evt.clientX
y = touch ? event.changedTouches[0].pageY : evt.clientY
touches = touch ? event.touches.length : 0
// XXX stop only if no fingers are touching or let the callback decide...
//togglePageDragging('off')
scroller.options.enableEndEvent && root.trigger('userScrollEnd', dx, dy, dt, start_x, start_y)
if(scroller.options.callback
// XXX revise this....
&& scroller.options.callback(dx/dt, start_x-x, touches) === false
|| touches == 0){
// cleanup and stop...
touch = false
scrolling = false
scroller.state = 'waiting'
bounds = null
}
return false
}
var scroller = {
options: {
hScroll: true,
vScroll: true,
enabelStartEvent: false,
enableUserScrollEvent: false,
enableEndEvent: false,
autoCancelEvents: false,
eventBounds: 5,
// NOTE: if this returns false explicitly, this will stop scrolling.
callback: null
},
// NOTE: this is updated live but not used by the system in any way...
state: 'stopped',
start: function(){
this.state = 'waiting'
// XXX STUB: this makes starting the scroll a bit sluggish,
// find a faster way...
//togglePageDragging('on')
// NOTE: if we bind both touch and mouse events, on touch devices they
// might start interfering with each other...
if('ontouchmove' in window){
root
.on('touchstart', startMoveHandler)
.on('touchmove', moveHandler)
.on('touchend', endMoveHandler)
.on('touchcancel', endMoveHandler)
} else {
root
.on('mousedown', startMoveHandler)
.on('mousemove', moveHandler)
.on('mouseup', endMoveHandler)
}
return this
},
stop: function(){
this.state = 'stopped'
if('ontouchmove' in window){
root
.off('touchstart', startMoveHandler)
.off('touchmove', moveHandler)
.off('touchend', endMoveHandler)
} else {
root
.off('mousedown', startMoveHandler)
.off('mousemove', moveHandler)
.off('mouseup', endMoveHandler)
}
return this
},
// XXX check...
setCallback: function(func){
this.callback = func
}
}
// merge the config with the defaults...
if(config != null){
$.extend(scroller.options, config)
}
return scroller
}
/************************************************ jQuery extensions **/ /************************************************ jQuery extensions **/
jQuery.fn.reverseChildren = function(){ jQuery.fn.reverseChildren = function(){