diff --git a/web/images/zoom-in.svg b/web/images/zoom-in.svg new file mode 100644 index 000000000..6eaed4481 --- /dev/null +++ b/web/images/zoom-in.svg @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Add + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + add + plus + + + + + + + + + + + + + + + + + + diff --git a/web/images/zoom-out.svg b/web/images/zoom-out.svg new file mode 100644 index 000000000..5f109a05c --- /dev/null +++ b/web/images/zoom-out.svg @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Remove + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + remove + delete + + + + + + + + + + + + + + + + + diff --git a/web/viewer.css b/web/viewer.css index ae00efd01..d1f725a02 100755 --- a/web/viewer.css +++ b/web/viewer.css @@ -21,6 +21,8 @@ body { height: 40px; width: 100%; z-index: 1; + white-space:nowrap; + overflow: hidden; } .separator { @@ -230,6 +232,14 @@ canvas { -webkit-box-shadow: 0px 2px 10px #ff0; } +#pageWidthOption { + border-top: 1px solid black; +} + +#customScaleOption { + display: none; +} + /* === Printed media overrides === */ @media print { #sidebar { diff --git a/web/viewer.html b/web/viewer.html index e02b3b9a1..d37270661 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -33,13 +33,25 @@
- + + + + + + + + +
diff --git a/web/viewer.js b/web/viewer.js index 974b88f76..811cfcbcc 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -4,8 +4,10 @@ 'use strict'; var kDefaultURL = 'compressed.tracemonkey-pldi-09.pdf'; -var kDefaultScale = 150; +var kDefaultScale = 1.5; +var kDefaultScaleDelta = 1.1; var kCacheSize = 20; +var kCssUnits = 96.0 / 72.0; var Cache = function(size) { var data = []; @@ -21,12 +23,13 @@ var cache = new Cache(kCacheSize); var PDFView = { pages: [], thumbnails: [], + currentScale: kDefaultScale, - set scale(val) { + setScale: function(val, resetAutoSettings) { var pages = this.pages; - var cssUnits = 96.0 / 72.0; for (var i = 0; i < pages.length; i++) - pages[i].update(val / 100 * cssUnits); + pages[i].update(val * kCssUnits); + this.currentScale = val; if (document.location.hash == '#' + this.page) this.pages[this.page - 1].draw(); @@ -35,10 +38,42 @@ var PDFView = { document.location.hash = this.page; var event = document.createEvent('UIEvents'); - event.initUIEvent('scalechange', false, false, window, val); + event.initUIEvent('scalechange', false, false, window, 0); + event.scale = val; + event.resetAutoSettings = resetAutoSettings; window.dispatchEvent(event); }, + parseScale: function(value) { + if ('custom' == value) + return; + + var scale = parseFloat(value); + if (scale) { + this.setScale(scale, true); + return; + } + + var currentPage = this.pages[this.page - 1]; + var scrollbarPadding = 40; + var pageWidthScale = (window.innerWidth - scrollbarPadding) / + currentPage.width / kCssUnits; + var pageHeightScale = (window.innerHeight - scrollbarPadding) / + currentPage.height / kCssUnits; + if ('page-width' == value) + this.setScale(pageWidthScale); + else if ('page-fit' == value) + this.setScale(Math.min(pageWidthScale, pageHeightScale)); + }, + + zoomIn: function() { + this.setScale(this.currentScale * kDefaultScaleDelta, true); + }, + + zoomOut: function() { + this.setScale(this.currentScale / kDefaultScaleDelta, true); + }, + set page(val) { var pages = this.pages; var input = document.getElementById('pageNumber'); @@ -129,7 +164,7 @@ var PDFView = { pagesRefMap[pageRef.num + ' ' + pageRef.gen + ' R'] = i; } - this.scale = (scale || kDefaultScale); + this.setScale(scale || kDefaultScale, true); this.page = parseInt(document.location.hash.substring(1)) || 1; this.pagesRefMap = pagesRefMap; this.destinations = pdf.catalog.destinations; @@ -355,7 +390,7 @@ window.addEventListener('load', function(evt) { params[unescape(param[0])] = unescape(param[1]); } - PDFView.open(params.file || kDefaultURL, parseInt(params.scale)); + PDFView.open(params.file || kDefaultURL, parseFloat(params.scale)); if (!window.File || !window.FileReader || !window.FileList || !window.Blob) document.getElementById('fileInput').style.display = 'none'; @@ -367,7 +402,7 @@ window.addEventListener('pdfloaded', function(evt) { PDFView.load(evt.detail); }, true); -window.addEventListener('scroll', function onscroll(evt) { +function updateViewarea() { var visiblePages = PDFView.getVisiblePages(); for (var i = 0; i < visiblePages.length; i++) { var page = visiblePages[i]; @@ -385,8 +420,19 @@ window.addEventListener('scroll', function onscroll(evt) { PDFView.page = lastPage.id; else if (currentId < firstPage.id) PDFView.page = firstPage.id; +} + +window.addEventListener('scroll', function onscroll(evt) { + updateViewarea(); }, true); +window.addEventListener('resize', function onscroll(evt) { + if (document.getElementById('pageWidthOption').selected || + document.getElementById('pageFitOption').selected) + PDFView.parseScale(document.getElementById('scaleSelect').value); + updateViewarea(); +}); + window.addEventListener('hashchange', function(evt) { PDFView.page = PDFView.page; }); @@ -432,13 +478,36 @@ window.addEventListener('transitionend', function(evt) { }, 500); }, true); - window.addEventListener('scalechange', function scalechange(evt) { + var customScaleOption = document.getElementById('customScaleOption'); + customScaleOption.selected = false; + + if (!evt.resetAutoSettings && + (document.getElementById('pageWidthOption').selected || + document.getElementById('pageFitOption').selected)) { + updateViewarea(); + return; + } + var options = document.getElementById('scaleSelect').options; + var predefinedValueFound = false; + var value = '' + evt.scale; for (var i = 0; i < options.length; i++) { var option = options[i]; - option.selected = (option.value == evt.detail); + if (option.value != value) { + option.selected = false; + continue; + } + option.selected = true; + predefinedValueFound = true; } + + if (!predefinedValueFound) { + customScaleOption.textContent = Math.round(evt.scale * 10000) / 100 + '%'; + customScaleOption.selected = true; + } + + updateViewarea(); }, true); window.addEventListener('pagechange', function pagechange(evt) { @@ -448,3 +517,20 @@ window.addEventListener('pagechange', function pagechange(evt) { document.getElementById('previous').disabled = (page == 1); document.getElementById('next').disabled = (page == PDFView.pages.length); }, true); + +window.addEventListener('keydown', function keydown(evt) { + switch(evt.keyCode) { + case 61: // FF/Mac '=' + case 107: // FF '+' and '=' + case 187: // Chrome '+' + PDFView.zoomIn(); + break; + case 109: // FF '-' + case 189: // Chrome '-' + PDFView.zoomOut(); + break; + case 48: // '0' + PDFView.setScale(kDefaultScale, true); + break; + } +});