the scroller framework almost generic, lots of minor tweeks...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-02-20 04:37:47 +04:00
parent 3f4f2e3859
commit d0f4d57c5b
3 changed files with 100 additions and 50 deletions

View File

@ -114,18 +114,22 @@ $(document).ready(function(){
window.THRESHOLD = 10 window.THRESHOLD = 10
var scroller = makeScrollHandler($('.viewer'), function(speed, distance){ window.MagazineScroller = makeScrollHandler($('.viewer'), {
// XXX this is not too correct... hScroll: true,
// ...make this mode specific... vScroll: false,
if(getMagazineScale() >= 1){ callback: function(speed, distance){
var cur = $('.current.page') // XXX this is not too correct...
if(distance > THRESHOLD){ // ...make this mode specific...
return nextPage(cur) if(getMagazineScale() >= 1){
} else if(distance < -THRESHOLD){ var cur = $('.current.page')
return prevPage(cur) if(distance > THRESHOLD){
return nextPage(cur)
} else if(distance < -THRESHOLD){
return prevPage(cur)
}
} }
} setCurrentPage()
setCurrentPage() },
}).start() }).start()
//setMagazineScale(0.5) //setMagazineScale(0.5)

View File

@ -44,6 +44,7 @@ var togglePageView = createCSSClassToggler(
// XXX this is not correct... // XXX this is not correct...
// ...need to fit one rectangel (page) into another (viewer) // ...need to fit one rectangel (page) into another (viewer)
// ...use the implementation in magazine.js
if(W >= H){ if(W >= H){
// fit to width... // fit to width...
var scale = W/w var scale = W/w
@ -80,13 +81,16 @@ var togglePageView = createCSSClassToggler(
// XXX should we use a callback or an event??? // XXX should we use a callback or an event???
// XXX make this get the scrolled item automatically... // XXX make this get the scrolled item automatically...
// ...now $('.magazine') is hardcoded... // ...now $('.magazine') is hardcoded...
function makeScrollHandler(root, callback){ function makeScrollHandler(root, config){
root = $(root)
// local data... // local data...
var scrolled
var scrolling = false var scrolling = false
var touch = false var touch = false
var touches = 0 var touches = 0
var start var start_x
var start_y
var prev_x var prev_x
var prev_y var prev_y
var prev_t var prev_t
@ -97,41 +101,35 @@ function makeScrollHandler(root, callback){
var y var y
var t var t
var dx var dx
var dy
var dt var dt
// XXX at this point this is not used...
var config = {
hScroll: true,
vScroll: false,
enableEvents: false,
autoCancelEvents: false,
eventBounds: 5,
}
function startMoveHandler(evt, callback){ function startMoveHandler(evt, callback){
prev_t = event.timeStamp || Date.now(); prev_t = event.timeStamp || Date.now();
if(config.autoCancelEvents){ if(scroller.options.autoCancelEvents){
bounds = { bounds = {
left: config.eventBounds, left: scroller.options.eventBounds,
right: root.width() - config.eventBounds, right: root.width() - scroller.options.eventBounds,
top: config.eventBounds, top: scroller.options.eventBounds,
bottom: root.height() - config.eventBounds bottom: root.height() - scroller.options.eventBounds
} }
} }
setTransitionDuration($('.magazine'), 0) scrolled = $(root.children()[0])
setTransitionDuration(scrolled, 0)
if(event.touches != null){ if(event.touches != null){
touch = true touch = true
} }
scrolling = true scrolling = true
scroller.state = 'scrolling' scroller.state = 'scrolling'
//root.trigger('userScrollStart') scroller.options.enabelStartEvent && root.trigger('userScrollStart')
//togglePageDragging('on') //togglePageDragging('on')
shift = getMagazineShift() shift = getElementShift(scrolled)
scale = getMagazineScale() scale = getElementScale(scrolled)
// get the user coords... // get the user coords...
prev_x = touch ? event.touches[0].pageX : evt.clientX prev_x = touch ? event.touches[0].pageX : evt.clientX
start = prev_x start_x = prev_x
prev_y = touch ? event.touches[0].pageY : evt.clientY
start_y = prev_y
return false return false
} }
@ -143,13 +141,14 @@ function makeScrollHandler(root, callback){
t = event.timeStamp || Date.now(); t = event.timeStamp || Date.now();
// get the user coords... // get the user coords...
x = touch ? event.touches[0].pageX : evt.clientX x = touch ? event.touches[0].pageX : evt.clientX
y = touch ? event.touches[0].pageY : evt.clientY
touches = touch ? event.touches.length : 0 touches = touch ? event.touches.length : 0
// XXX needs testing... // XXX needs testing...
// check scroll bounds... // check scroll bounds...
if(bounds != null){ if(bounds != null){
if(config.hScroll && (x <= bounds.left || x >= bounds.right) if(scroller.options.hScroll && (x <= bounds.left || x >= bounds.right)
|| config.vScroll && (y <= bounds.top || y >= bounds.bottom)){ || scroller.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)
} }
@ -157,17 +156,24 @@ function makeScrollHandler(root, callback){
// do the actual scroll... // do the actual scroll...
if(scrolling){ if(scrolling){
shift += x - prev_x if(scroller.options.hScroll){
setElementTransform($('.magazine'), shift, scale) 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 // XXX these should be done every time the event is caught or
// just while scrolling? // just while scrolling?
dx = x - prev_x dx = x - prev_x
dy = y - prev_y
dt = t - prev_t dt = t - prev_t
prev_t = t
prev_x = x prev_x = x
prev_y = y
prev_t = t
//root.trigger('userScroll') scroller.options.enableUserScrollEvent && root.trigger('userScroll')
} }
return false return false
} }
@ -175,20 +181,34 @@ function makeScrollHandler(root, callback){
// XXX get real transition duration... // XXX get real transition duration...
setTransitionDuration($('.magazine'), 200) setTransitionDuration($('.magazine'), 200)
x = touch ? event.changedTouches[0].pageX : evt.clientX x = touch ? event.changedTouches[0].pageX : evt.clientX
y = touch ? event.changedTouches[0].pageY : evt.clientY
touch = false touch = false
scrolling = false scrolling = false
scroller.state = 'waiting' scroller.state = 'waiting'
touches = 0 touches = 0
bounds = null bounds = null
//togglePageDragging('off') //togglePageDragging('off')
// XXX add speed to this... scroller.options.enableEndEvent && root.trigger('userScrollEnd', dx, dy, dt, start_x, start_y)
//root.trigger('userScrollEnd') scroller.options.callback && scroller.options.callback(dx/dt, start_x-x)
callback && callback(dx/dt, start - x)
return false return false
} }
var scroller = { var scroller = {
options: {
hScroll: true,
vScroll: true,
enabelStartEvent: false,
enableUserScrollEvent: false,
enableEndEvent: false,
autoCancelEvents: false,
eventBounds: 5,
callback: null
},
start: function(){ start: function(){
this.state = 'waiting' this.state = 'waiting'
// XXX STUB: this makes starting the scroll a bit sluggish, // XXX STUB: this makes starting the scroll a bit sluggish,
@ -233,6 +253,12 @@ function makeScrollHandler(root, callback){
// NOTE: this is updated live but not used by the system in any way... // NOTE: this is updated live but not used by the system in any way...
state: 'stopped' state: 'stopped'
} }
// merge the config with the defaults...
if(config != null){
$.extend(scroller.options, config)
}
return scroller return scroller
} }
@ -274,15 +300,18 @@ function getMagazineOffset(page, scale, align){
var offset = $('.viewer').width()/2 - (page.width()/2)*scale var offset = $('.viewer').width()/2 - (page.width()/2)*scale
} }
// NOTE: this without scaling also represents the inner width of
// the viewer...
var w = mag.outerWidth(true) var w = mag.outerWidth(true)
// XXX this depends on scale... // XXX this depends on scale...
var pos = page.position().left//*scale var pos = page.position().left//*scale
var l = 0
return -((w - w*scale)/2 + pos) + offset return -((w - w*scale)/2 + pos) + offset
} }
// XXX make this work for narrow and left/right alligned pages...
function getPageNumber(page){ function getPageNumber(page){
// a page is given explicitly, get the next one... // a page is given explicitly, get the next one...
if(page != null){ if(page != null){

View File

@ -196,14 +196,27 @@ function unanimated(obj, func, time){
// NOTE: at this point this works only on the X axis... // NOTE: at this point this works only on the X axis...
function setElementTransform(elem, offset, scale){ function setElementTransform(elem, offset, scale){
elem = $(elem)
if(offset == null){ if(offset == null){
var offset = getElementShift(elem).left offset = getElementShift(elem)
// number -- only the x coord...
} else if(typeof(offset) == typeof(1)){
offset = {
left: offset,
top: 0
}
// array...
} else if(offset.indexOf){
offset = {
left: offset[0] ? offset[0] : 0,
top: offset[1] ? offset[1] : 0
}
} }
if(scale == null){ if(scale == null){
var scale = getElementScale(elem) var scale = getElementScale(elem)
} }
if(USE_TRANSFORM){ if(USE_TRANSFORM){
var transform = 'translate('+ offset +'px, 0px) scale('+ scale +') translateZ(0px)' var transform = 'translate('+ offset.left +'px, '+ offset.top +'px) scale('+ scale +') translateZ(0px)'
elem.css({ elem.css({
'-ms-transform' : transform, '-ms-transform' : transform,
'-webkit-transform' : transform, '-webkit-transform' : transform,
@ -212,14 +225,17 @@ function setElementTransform(elem, offset, scale){
'transform' : transform, 'transform' : transform,
// XXX can we avoid this here?? // XXX can we avoid this here??
left: 0 left: 0,
// XXX is this correct???
top: ''
}) })
} else { } else {
var transform = 'translate(0px, 0px) scale('+ scale +') translateZ(0px)' var transform = 'translate(0px, 0px) scale('+ scale +') translateZ(0px)'
elem.css({ elem.css({
// NOTE: this will be wrong during a transition, that's why we // NOTE: this will be wrong during a transition, that's why we
// can pass the pre-calculated offset as an argument... // can pass the pre-calculated offset as an argument...
left: offset, left: offset.left,
top: offset.top,
// XXX can we avoid this here?? // XXX can we avoid this here??
'-ms-transform' : transform, '-ms-transform' : transform,
@ -284,15 +300,16 @@ function getElementShift(elem){
if(!transform || transform == 'none'){ if(!transform || transform == 'none'){
return {left: 0, top: 0} return {left: 0, top: 0}
} }
res = /(translate\(|matrix\([^,]*,[^,]*,[^,]*,[^,]*,)([^,]*),([^\)]*)\)/.exec(transform)
return { return {
left: parseFloat(/(translate\(|matrix\([^,]*,[^,]*,[^,]*,[^,]*,)([^,]*),/.exec(transform)[2]), left: parseFloat(res[2]),
top: null top: parseFloat(res[3])
} }
// using left... // using left...
} else { } else {
return { return {
left: elem.position().left, left: elem.position().left,
top: null top: elem.position().top
} }
} }
} }