From edf3163fa6ca3f2bf73b2fd10bdf40b7d24c2d29 Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 31 Jul 2013 19:43:03 +0200 Subject: [PATCH] Keep current scroll position when zooming the document --- web/viewer.js | 86 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/web/viewer.js b/web/viewer.js index fd10930eb..141a092c6 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -251,28 +251,45 @@ var PDFView = { }, true); }, - setScale: function pdfViewSetScale(val, resetAutoSettings, noScroll) { - if (val == this.currentScale) + getPageTop: function pdfViewGetPageTop(id) { + return (this.pages[id - 1].el.offsetTop + this.pages[id - 1].el.clientTop); + }, + + setScale: function pdfViewSetScale(value, resetAutoSettings, noScroll) { + if (this.currentScale === value) { return; + } - var pages = this.pages; - for (var i = 0; i < pages.length; i++) - pages[i].update(val * CSS_UNITS); + var pages = this.pages, page = this.page; + var currentPage = pages[page - 1], dest = null; + if (!noScroll && !this.isPresentationMode) { + // Obtain the current scroll position before resizing the pages. + var topLeft = currentPage.getPagePoint(this.container.scrollLeft, + (this.container.scrollTop - this.getPageTop(page))); + dest = [null, { name: 'XYZ' }, Math.round(topLeft[0]), + Math.round(topLeft[1]), null]; + } - if (!noScroll && this.currentScale != val) - this.pages[this.page - 1].scrollIntoView(); - this.currentScale = val; + for (var i = 0; i < pages.length; i++) { + pages[i].update(value * CSS_UNITS); + } + this.currentScale = value; + + if (!noScroll) { + currentPage.scrollIntoView(dest); + } var event = document.createEvent('UIEvents'); event.initUIEvent('scalechange', false, false, window, 0); - event.scale = val; + event.scale = value; event.resetAutoSettings = resetAutoSettings; window.dispatchEvent(event); }, parseScale: function pdfViewParseScale(value, resetAutoSettings, noScroll) { - if ('custom' == value) + if ('custom' === value) { return; + } var scale = parseFloat(value); this.currentScaleValue = value; @@ -1040,14 +1057,14 @@ var PDFView = { } else if (storedHash) { this.setHash(storedHash); } else if (scale) { - this.parseScale(scale, true); + this.parseScale(scale, true, true); this.page = 1; } if (PDFView.currentScale === UNKNOWN_SCALE) { // Scale was not initialized: invalid bookmark or scale was not specified. // Setting the default one. - this.parseScale(DEFAULT_SCALE, true); + this.parseScale(DEFAULT_SCALE, true, true); } }, @@ -1372,15 +1389,28 @@ var PDFView = { enterPresentationMode: function pdfViewEnterPresentationMode() { this.isPresentationMode = true; - this.page = this.presentationModeArgs.page; this.parseScale('page-fit', true); + // Since 'resize' events are fired when entering presentation mode, + // add this call to the end of the rendering queue to prevent + // the page from being scrolled partially out of view. + setTimeout(function() { + this.page = this.presentationModeArgs.page; + }.bind(this), 0); + this.showPresentationControls(); }, exitPresentationMode: function pdfViewExitPresentationMode() { this.isPresentationMode = false; - this.parseScale(this.presentationModeArgs.previousScale); - this.page = this.page; + var currentPage = this.pages[this.page - 1]; + this.parseScale(this.presentationModeArgs.previousScale, true, true); + // Since 'resize' events are fired when exiting from presentation mode, + // add this call to the end of the rendering queue to make sure + // that the current page is scrolled into view properly. + setTimeout(function() { + currentPage.scrollIntoView(); + }, 0); + this.clearMouseScrollState(); this.hidePresentationControls(); this.presentationModeArgs = null; @@ -1434,14 +1464,9 @@ var PDFView = { this.renderHighestPriority(); var currentPage = this.pages[this.page - 1]; - if (!currentPage) { - return; - } - - // Wait for presentation mode to take effect - setTimeout(function() { + if (currentPage) { currentPage.scrollIntoView(); - }, 0); + } }, /** @@ -2490,9 +2515,10 @@ function updateViewarea() { window.addEventListener('resize', function webViewerResize(evt) { if (PDFView.initialized && (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected || - document.getElementById('pageAutoOption').selected)) - PDFView.parseScale(document.getElementById('scaleSelect').value); + document.getElementById('pageFitOption').selected || + document.getElementById('pageAutoOption').selected)) { + PDFView.parseScale(document.getElementById('scaleSelect').value); + } updateViewarea(); }); @@ -2567,11 +2593,11 @@ window.addEventListener('scalechange', function scalechange(evt) { customScaleOption.selected = false; if (!evt.resetAutoSettings && - (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected || - document.getElementById('pageAutoOption').selected)) { - updateViewarea(); - return; + (document.getElementById('pageWidthOption').selected || + document.getElementById('pageFitOption').selected || + document.getElementById('pageAutoOption').selected)) { + updateViewarea(); + return; } var predefinedValueFound = selectScaleOption('' + evt.scale);