X-Git-Url: http://git.rot13.org/?p=bookreader.git;a=blobdiff_plain;f=BookReader%2FBookReader.js;h=1e2eabdac1c2dda2ecfcfdf9987fd32f83eedd93;hp=8d7963c532281aae37ce7a444b03f1d6d5c089ef;hb=067dbeedbf050f83f8473fca9f09b88c1551a086;hpb=0e67838f781bc36f70ebdefbe3200f4ebcefb00d diff --git a/BookReader/BookReader.js b/BookReader/BookReader.js index 8d7963c..1e2eabd 100644 --- a/BookReader/BookReader.js +++ b/BookReader/BookReader.js @@ -83,6 +83,7 @@ function BookReader() { this.constModeThumb = 3; // Zoom levels + // $$$ provide finer grained zooming this.reductionFactors = [0.5, 1, 2, 4, 8, 16]; // Object to hold parameters related to 2up mode @@ -140,6 +141,7 @@ BookReader.prototype.init = function() { } $("#BookReader").empty(); + this.initToolbar(this.mode, this.ui); // Build inside of toolbar div $("#BookReader").append("
"); $("#BRcontainer").append("
"); @@ -147,7 +149,7 @@ BookReader.prototype.init = function() { $("#BRcontainer").bind('scroll', this, function(e) { e.data.loadLeafs(); }); - + this.setupKeyListeners(); this.startLocationPolling(); @@ -196,8 +198,8 @@ BookReader.prototype.init = function() { // $$$ refactor this so it's enough to set the first index and call preparePageView // (get rid of mode-specific logic at this point) if (1 == this.mode) { - this.resizePageView(); this.firstIndex = startIndex; + this.prepareOnePageView(); this.jumpToIndex(startIndex); } else if (3 == this.mode) { this.firstIndex = startIndex; @@ -290,162 +292,27 @@ BookReader.prototype.drawLeafs = function() { } -// setDragHandler() +// bindGestures(jElement) //______________________________________________________________________________ -BookReader.prototype.setDragHandler = function(div) { - div.dragging = false; - - $(div).unbind('mousedown').bind('mousedown', function(e) { - e.preventDefault(); - - //console.log('mousedown at ' + e.pageY); - - this.dragging = true; - this.prevMouseX = e.pageX; - this.prevMouseY = e.pageY; - - var startX = e.pageX; - var startY = e.pageY; - var startTop = $('#BRcontainer').attr('scrollTop'); - var startLeft = $('#BRcontainer').attr('scrollLeft'); - - }); - - $(div).unbind('mousemove').bind('mousemove', function(ee) { - ee.preventDefault(); - - // console.log('mousemove ' + ee.pageX + ',' + ee.pageY); - - var offsetX = ee.pageX - this.prevMouseX; - var offsetY = ee.pageY - this.prevMouseY; - - if (this.dragging) { - $('#BRcontainer').attr('scrollTop', $('#BRcontainer').attr('scrollTop') - offsetY); - $('#BRcontainer').attr('scrollLeft', $('#BRcontainer').attr('scrollLeft') - offsetX); - } - - this.prevMouseX = ee.pageX; - this.prevMouseY = ee.pageY; - - }); - - $(div).unbind('mouseup').bind('mouseup', function(ee) { - ee.preventDefault(); - //console.log('mouseup'); - - this.dragging = false; - }); - - $(div).unbind('mouseleave').bind('mouseleave', function(e) { - e.preventDefault(); - //console.log('mouseleave'); - - this.dragging = false; - }); - - $(div).unbind('mouseenter').bind('mouseenter', function(e) { - e.preventDefault(); - //console.log('mouseenter'); - - this.dragging = false; - }); -} +BookReader.prototype.bindGestures = function(jElement) { -// setDragHandler2UP() -//______________________________________________________________________________ -BookReader.prototype.setDragHandler2UP = function(div) { - div.dragging = false; - - $(div).unbind('mousedown').bind('mousedown', function(e) { + jElement.unbind('gesturechange').bind('gesturechange', function(e) { e.preventDefault(); - - //console.log('mousedown at ' + e.pageY); - - this.dragStart = {x: e.pageX, y: e.pageY }; - this.mouseDown = true; - this.dragging = false; // wait until drag distance - this.prevMouseX = e.pageX; - this.prevMouseY = e.pageY; - - var startX = e.pageX; - var startY = e.pageY; - var startTop = $('#BRcontainer').attr('scrollTop'); - var startLeft = $('#BRcontainer').attr('scrollLeft'); - - }); - - $(div).unbind('mousemove').bind('mousemove', function(ee) { - ee.preventDefault(); - - // console.log('mousemove ' + ee.pageX + ',' + ee.pageY); - - var offsetX = ee.pageX - this.prevMouseX; - var offsetY = ee.pageY - this.prevMouseY; - - var minDragDistance = 5; // $$$ constant - - var distance = Math.max(Math.abs(offsetX), Math.abs(offsetY)); - - if (this.mouseDown && (distance > minDragDistance)) { - //console.log('drag start!'); - - this.dragging = true; + if (e.originalEvent.scale > 1.5) { + br.zoom(1); + } else if (e.originalEvent.scale < 0.6) { + br.zoom(-1); } - - if (this.dragging) { - $('#BRcontainer').attr('scrollTop', $('#BRcontainer').attr('scrollTop') - offsetY); - $('#BRcontainer').attr('scrollLeft', $('#BRcontainer').attr('scrollLeft') - offsetX); - this.prevMouseX = ee.pageX; - this.prevMouseY = ee.pageY; - } - - - }); - - /* - $(div).unbind('mouseup').bind('mouseup', function(ee) { - ee.preventDefault(); - //console.log('mouseup'); - - this.dragging = false; - this.mouseDown = false; }); - */ - - - $(div).unbind('mouseleave').bind('mouseleave', function(e) { - e.preventDefault(); - //console.log('mouseleave'); - - this.dragging = false; - this.mouseDown = false; - }); - - $(div).unbind('mouseenter').bind('mouseenter', function(e) { - e.preventDefault(); - //console.log('mouseenter'); - this.dragging = false; - this.mouseDown = false; - }); } BookReader.prototype.setClickHandler2UP = function( element, data, handler) { //console.log('setting handler'); //console.log(element.tagName); - $(element).unbind('click').bind('click', data, function(e) { - e.preventDefault(); - - //console.log('click!'); - - if (this.mouseDown && (!this.dragging)) { - //console.log('click not dragging!'); - handler(e); - } - - this.dragging = false; - this.mouseDown = false; + $(element).unbind('tap').bind('tap', data, function(e) { + handler(e); }); } @@ -530,8 +397,6 @@ BookReader.prototype.drawLeafsOnePage = function() { $(div).css('height', height+'px'); //$(div).text('loading...'); - this.setDragHandler(div); - $('#BRpageview').append(div); var img = document.createElement("img"); @@ -574,10 +439,12 @@ BookReader.prototype.drawLeafsOnePage = function() { // drawLeafsThumbnail() //______________________________________________________________________________ -BookReader.prototype.drawLeafsThumbnail = function() { +// If seekIndex is defined, the view will be drawn with that page visible (without any +// animated scrolling) +BookReader.prototype.drawLeafsThumbnail = function( seekIndex ) { //alert('drawing leafs!'); this.timer = null; - + var viewWidth = $('#BRcontainer').attr('scrollWidth') - 20; // width minus buffer //console.log('top=' + scrollTop + ' bottom='+scrollBottom); @@ -593,6 +460,9 @@ BookReader.prototype.drawLeafsThumbnail = function() { var leafMap = []; var self = this; + + // Will be set to top of requested seek index, if set + var seekTop; // Calculate the position of every thumbnail. $$$ cache instead of calculating on every draw for (i=0; i maxRight) { maxRight = rightPos; } leafIndex++; + + if (i == seekIndex) { + seekTop = bottomPos - this.padding - leafMap[currentRow].height; + } } // reset the bottom position based on thumbnails $('#BRpageview').height(bottomPos); var pageViewBuffer = Math.floor(($('#BRcontainer').attr('scrollWidth') - maxRight) / 2) - 14; + + // If seekTop is defined, seeking was requested and target found + if (typeof(seekTop) != 'undefined') { + $('#BRcontainer').scrollTop( seekTop ); + } + var scrollTop = $('#BRcontainer').attr('scrollTop'); var scrollBottom = scrollTop + $('#BRcontainer').height(); @@ -708,7 +588,7 @@ BookReader.prototype.drawLeafsThumbnail = function() { // link to page in single page mode link = document.createElement("a"); $(link).data('leaf', leaf); - $(link).bind('click', function(event) { + $(link).bind('tap', function(event) { self.firstIndex = $(this).data('leaf'); self.switchMode(self.constMode1up); event.preventDefault(); @@ -1004,6 +884,20 @@ BookReader.prototype.resizePageView = function() { // e.g. does not preserve position in thumbnail mode // See http://bugs.launchpad.net/bookreader/+bug/552972 + switch (this.mode) { + case this.constMode1up: + case this.constMode2up: + this.resizePageView1up(); + break; + case this.constModeThumb: + this.prepareThumbnailView( this.currentIndex() ); + break; + default: + alert('Resize not implemented for this mode'); + } +} + +BookReader.prototype.resizePageView1up = function() { var i; var viewHeight = 0; //var viewWidth = $('#BRcontainer').width(); //includes scrollBar @@ -1029,7 +923,7 @@ BookReader.prototype.resizePageView = function() { if (width>viewWidth) viewWidth=width; } $('#BRpageview').height(viewHeight); - $('#BRpageview').width(viewWidth); + $('#BRpageview').width(viewWidth); var newCenterY = scrollRatio*viewHeight; var newTop = Math.max(0, Math.floor( newCenterY - $('#BRcontainer').height()/2 )); @@ -1044,14 +938,12 @@ BookReader.prototype.resizePageView = function() { //this.centerPageView(); this.loadLeafs(); - - // $$$ jump to index here? index is not preserved when resizing in thumb mode - - // Not really needed until there is 1up autofit + this.removeSearchHilites(); this.updateSearchHilites(); } + // centerX1up() //______________________________________________________________________________ // Returns the current offset of the viewport center in scaled document coordinates. @@ -1138,7 +1030,6 @@ BookReader.prototype.zoomThumb = function(direction) { if (this.thumbColumns != oldColumns) { this.prepareThumbnailView(); - this.jumpToIndex(this.currentIndex()); } } @@ -1273,8 +1164,7 @@ BookReader.prototype.jumpToIndex = function(index, pageX, pageY) { leafIndex = 0; } - // $$$ leaf is not defined in this function -- leaking in from somewhere else - leafHeight = parseInt((this.getPageHeight(leaf)*this.thumbWidth)/this.getPageWidth(leaf), 10); + leafHeight = parseInt((this.getPageHeight(leafIndex)*this.thumbWidth)/this.getPageWidth(leafIndex), 10); if (leafHeight > rowHeight) { rowHeight = leafHeight; } if (leafIndex==0) { leafTop = bottomPos; } if (leafIndex==0) { bottomPos += this.padding + rowHeight; } @@ -1351,7 +1241,6 @@ BookReader.prototype.switchMode = function(mode) { } else if (3 == mode) { this.reduce = this.quantizeReduce(this.reduce); this.prepareThumbnailView(); - this.jumpToIndex(this.currentIndex()); } else { // $$$ why don't we save autofit? this.twoPage.autofit = false; // Take zoom level from other mode @@ -1368,19 +1257,24 @@ BookReader.prototype.prepareOnePageView = function() { // var startLeaf = this.displayedIndices[0]; var startLeaf = this.currentIndex(); - + $('#BRcontainer').empty(); $('#BRcontainer').css({ overflowY: 'scroll', overflowX: 'auto' }); - + $("#BRcontainer").append("
"); + + // Attaches to first child - child must be present + $('#BRcontainer').dragscrollable(); + this.bindGestures($('#BRcontainer')); + // $$$ keep select enabled for now since disabling it breaks keyboard // nav in FF 3.6 (https://bugs.edge.launchpad.net/bookreader/+bug/544666) // BookReader.util.disableSelect($('#BRpageview')); - this.resizePageView(); + this.resizePageView(); this.jumpToIndex(startLeaf); this.displayedIndices = []; @@ -1397,23 +1291,24 @@ BookReader.prototype.prepareThumbnailView = function() { overflowY: 'scroll', overflowX: 'auto' }); - + $("#BRcontainer").append("
"); + + $('#BRcontainer').dragscrollable(); + this.bindGestures($('#BRcontainer')); // $$$ keep select enabled for now since disabling it breaks keyboard // nav in FF 3.6 (https://bugs.edge.launchpad.net/bookreader/+bug/544666) // BookReader.util.disableSelect($('#BRpageview')); - var startLeaf = this.currentIndex(); this.thumbWidth = this.getThumbnailWidth(this.thumbColumns); this.reduce = this.getPageWidth(0)/this.thumbWidth; - this.resizePageView(); - this.displayedRows = []; + + // Draw leafs with current index directly in view (no animating to the index) + this.drawLeafsThumbnail( this.currentIndex() ); - // $$$ resizePageView will do a delayed load -- this will make it happen faster - this.drawLeafsThumbnail(); } // prepareTwoPageView() @@ -1466,6 +1361,10 @@ BookReader.prototype.prepareTwoPageView = function(centerPercentageX, centerPerc // Add the two page view // $$$ Can we get everything set up and then append? $('#BRcontainer').append('
'); + + // Attaches to first child, so must come after we add the page view + $('#BRcontainer').dragscrollable(); + this.bindGestures($('#BRcontainer')); // $$$ calculate first then set $('#BRtwopageview').css( { @@ -1863,27 +1762,6 @@ BookReader.prototype.setCurrentIndex = function(index) { this.firstIndex = index; } -/* -// Returns the current index if visible, or the logically current visible -// thumbnail -BookReader.prototype.currentIndexOrVisibleThumb = function() { - // XXX finish implementation - var index = this.currentIndex(); - if (!this.indexIsVisbleThumb(this.currentIndex()) { - // XXX search for visible - } - return index; -} - -// Returns true if the given index is visible -BookReader.prototype.indexIsVisibleThumb = function(index, onlyCompletelyVisible = true) { - // XXX implement - // $$$ I'd prefer to go through a stored leaf map instead of DOM - - -} -*/ - // right() //______________________________________________________________________________ @@ -2322,32 +2200,19 @@ BookReader.prototype.flipRightToLeft = function(newIndexL, newIndexR) { // setMouseHandlers2UP //______________________________________________________________________________ BookReader.prototype.setMouseHandlers2UP = function() { - /* - $(this.prefetchedImgs[this.twoPage.currentIndexL]).bind('dblclick', function() { - //self.prevPage(); - self.autoStop(); - self.left(); - }); - $(this.prefetchedImgs[this.twoPage.currentIndexR]).bind('dblclick', function() { - //self.nextPage();' - self.autoStop(); - self.right(); - }); - */ - - this.setDragHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexL] ); this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexL], { self: this }, function(e) { e.data.self.left(); + e.preventDefault(); } ); - this.setDragHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexR] ); this.setClickHandler2UP( this.prefetchedImgs[this.twoPage.currentIndexR], { self: this }, function(e) { e.data.self.right(); + e.preventDefault(); } ); } @@ -3256,7 +3121,7 @@ BookReader.prototype.initToolbar = function(mode, ui) { this.updateToolbarZoom(this.reduce); // Pretty format - if (ui == "embed") { + if (ui == "embed" || ui == "touch") { $("#BookReader a.logo").attr("target","_blank"); }