diff --git a/layout-iscroll2.html b/layout-iscroll2.html
index d450001..f33b5e8 100755
--- a/layout-iscroll2.html
+++ b/layout-iscroll2.html
@@ -117,7 +117,10 @@ $(document).ready(function(){
window.MagazineScroller = makeScrollHandler($('.viewer'), {
hScroll: true,
vScroll: false,
- callback: function(speed, distance){
+ callback: function(speed, distance, touches){
+ if(touches > 0){
+ return true
+ }
// XXX this is not too correct...
// ...make this mode specific...
if(getMagazineScale() >= 1){
diff --git a/layout.js b/layout.js
index bcf972b..f790eac 100755
--- a/layout.js
+++ b/layout.js
@@ -74,196 +74,6 @@ var togglePageView = createCSSClassToggler(
/************************************************** 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 ***/
// XXX make this more acurate...
diff --git a/lib/jli.js b/lib/jli.js
index 888faab..293c18d 100755
--- a/lib/jli.js
+++ b/lib/jli.js
@@ -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.fn.reverseChildren = function(){