Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1262)

Unified Diff: chrome/browser/resources/pdf/viewport.js

Issue 1901903002: Improved Pinch-Zoom for PDF (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pepper_add_set_layer_transform
Patch Set: Clean code part 2 Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/pdf/viewport.js
diff --git a/chrome/browser/resources/pdf/viewport.js b/chrome/browser/resources/pdf/viewport.js
index 4cb8fee0f66a994dd1959295b0ab8483d191890b..c83ff1ec13c02d3407e81042e4ae6d3931b31a3f 100644
--- a/chrome/browser/resources/pdf/viewport.js
+++ b/chrome/browser/resources/pdf/viewport.js
@@ -49,6 +49,8 @@ function Viewport(window,
this.fittingType_ = Viewport.FittingType.NONE;
this.defaultZoom_ = defaultZoom;
this.topToolbarHeight_ = topToolbarHeight;
+ this.prevScale = 1;
+ this.doRender_ = 1;
window.addEventListener('scroll', this.updateViewport_.bind(this));
window.addEventListener('resize', this.resize_.bind(this));
@@ -170,9 +172,7 @@ Viewport.prototype = {
* @private
* Called when the viewport should be updated.
*/
- updateViewport_: function() {
- this.viewportChangedCallback_();
- },
+ updateViewport_: function() { this.viewportChangedCallback_(); },
/**
* @private
@@ -221,9 +221,7 @@ Viewport.prototype = {
/**
* @type {number} the zoom level of the viewport.
*/
- get zoom() {
- return this.zoom_;
- },
+ get zoom() { return this.zoom_; },
/**
* @private
@@ -236,6 +234,13 @@ Viewport.prototype = {
this.beforeZoomCallback_();
this.allowedToChangeZoom_ = true;
f();
+ var needsScrollbars = this.documentNeedsScrollbars_(this.zoom_);
+ if (!needsScrollbars.horizontal) {
+ this.pinchCenter_ = {
wjmaclean 2016/04/21 14:11:01 Perhaps add a TODO here: at present the transition
bokan 2016/04/21 15:27:04 This is the case where we don't have horizontal sc
alessandroa 2016/04/21 20:39:40 I've explained today to David how by having the po
+ x: this.window_.innerWidth / 2,
+ y: this.window_.innerHeight / 2
+ };
+ }
this.allowedToChangeZoom_ = false;
this.afterZoomCallback_();
},
@@ -265,6 +270,61 @@ Viewport.prototype = {
},
/**
+ * @private
+ * Sets the cusotm zoom of the viewport.
bokan 2016/04/21 02:24:01 "cusotm" -> "custom"
alessandroa 2016/04/21 20:39:39 Acknowledged.
+ * Same function as below but for pinch zoom we have some more operations.
+ * @param {number} scaleDelta the zoom delta.
+ * @param {Object} center the pinch center
bokan 2016/04/21 18:20:17 Describe the coordinates of the center value. i.e.
alessandroa 2016/04/21 20:39:39 Done.
+ */
+ setPinchZoomInternal_: function(scaleDelta, center) {
+ if (!this.allowedToChangeZoom_) {
+ throw 'Called Viewport.setZoomInternal_ without calling ' +
+ 'Viewport.mightZoom_.';
+ }
+ this.zoom_ = this.clampScale(this.zoom_ * scaleDelta);
+
+ var newCenterInContent = this.frameToContent(center, this.zoom_);
+ var delta = {
+ x: (newCenterInContent.x - this.oldCenterInContent.x),
+ y: (newCenterInContent.y - this.oldCenterInContent.y)
+ };
+
+ // Record the scroll position (relative to the pinch center).
+ var currentScrollPos = {
+ x: this.position.x - delta.x * this.zoom_,
+ y: this.position.y - delta.y * this.zoom_
+ };
+
+ this.contentSizeChanged_();
+ // Scroll to the scaled scroll position.
+ this.position = {x: currentScrollPos.x, y: currentScrollPos.y};
+ //Update last scale for the current pinch event
+ this.prevScale *= scaleDelta;
bokan 2016/04/21 15:22:06 prevScale is used entirely in the handlers to calc
+ },
+
+ /**
+ * @private
+ * Makes sure that the scale level doesn't get out of the limits.
+ * @param {number} scale the new scale level
+ * @return {number} the scale clamped in the limit
+ */
+ clampScale: function(scale) { return Math.min(5, Math.max(0.25, scale)); },
+
+ /**
+ * @private
+ * Gets the new center in content.
+ * @param {Object} pinch center
+ * @param {Object} zoom level
+ * @return {Objet} the new center in content
+ */
+ frameToContent: function(framePoint, scale) {
+ return {
+ x: (framePoint.x + this.position.x) / scale,
bokan 2016/04/21 15:22:06 scale is always this.zoom_ so remove the argument
alessandroa 2016/04/21 20:39:40 Done.
+ y: (framePoint.y + this.position.y) / scale
bokan 2016/04/21 15:22:06 This doesn't really get you into the content since
bokan 2016/04/21 15:59:02 You can disregard this comment. While strange, the
+ };
+ },
+
+ /**
* Sets the zoom to the given zoom level.
* @param {number} newZoom the zoom level to zoom to.
*/
@@ -281,16 +341,12 @@ Viewport.prototype = {
/**
* @type {number} the width of scrollbars in the viewport in pixels.
*/
- get scrollbarWidth() {
- return this.scrollbarWidth_;
- },
+ get scrollbarWidth() { return this.scrollbarWidth_; },
/**
* @type {Viewport.FittingType} the fitting type the viewport is currently in.
*/
- get fittingType() {
- return this.fittingType_;
- },
+ get fittingType() { return this.fittingType_; },
/**
* @private
@@ -456,14 +512,26 @@ Viewport.prototype = {
this.updateViewport_();
}.bind(this));
},
+ /**
+ * @private
+ * Computes vector between two points.
+ * @param {Object} First Point
+ * @param {Object} Second Point
+ * @return {Object} The vector
+ */
+ vectorDistance: function(p1, p2) {
wjmaclean 2016/04/21 14:11:01 Maybe call the vectorDelta instead of invoking the
alessandroa 2016/04/21 20:39:40 Done.
+ var vector = {
+ x: p2.x - p1.x,
+ y: p2.y - p1.y
+ };
+ return vector;
+ },
/**
* Zoom the viewport so that a page consumes the entire viewport. Also scrolls
* the viewport to the top of the current page.
*/
- fitToPage: function() {
- this.fitToPageInternal_(true);
- },
+ fitToPage: function() { this.fitToPageInternal_(true); },
/**
* Zoom out to the next predefined zoom level.
@@ -498,6 +566,74 @@ Viewport.prototype = {
},
/**
+ * Pinch zoom event handler
+ * @param {ev} the pinch event
+ */
+ pinchZoom: function(ev) {
+ this.mightZoom_(function() {
+ if (ev.additionalEvent == 'pinchin')
bokan 2016/04/21 15:22:06 Add a comment explaining why we render only on pin
+ this.doRender_ = 1;
bokan 2016/04/21 02:24:01 Should doRender be true/false rather than a numeri
wjmaclean 2016/04/21 14:11:01 Agreed, seems like doRender should be a Boolean.
alessandroa 2016/04/21 20:39:40 True :)
+ else
+ this.doRender_ = 0;
+
+ var scaleDelta = ev.scale / this.prevScale;
+ this.pinchPanVector_ = this.vectorDistance(ev.center, this.pinch_start_);
+
+ var needsScrollbars = this.documentNeedsScrollbars_(
+ this.clampScale(this.zoom_ * scaleDelta));
+ // We must change the new content in center because now we have fake
wjmaclean 2016/04/21 14:11:01 I'm never comfortable with this term 'fake scrollb
bokan 2016/04/21 15:27:04 Unrelated to this, but fun anecdote anyway, did yo
alessandroa 2016/04/21 20:39:40 That's pretty much my definition of fake ..
+ // scrollbars
bokan 2016/04/21 15:22:06 This comment should elaborate on what we're doing
alessandroa 2016/04/21 20:39:40 Acknowledged.
+ if (this.changeCenter_ && needsScrollbars.horizontal) {
+ this.oldCenterInContent =
+ this.frameToContent(this.containerCenter(ev.center), this.zoom_);
+ this.changeCenter_ = false;
+ }
+
+ this.pinchCenter_ = ev.center;
+ this.setPinchZoomInternal_(scaleDelta, this.containerCenter(ev.center));
+ this.updateViewport_();
+ }.bind(this));
+ },
+
+ pinchZoomStart: function(ev) {
+ //We render the document once before pinch.
+ //By doing so we ensure the image_data_ in the plugin is the correct one
bokan 2016/04/21 02:24:01 Shouldn't doRender_ be = 1 then? Or I'm misunderst
wjmaclean 2016/04/21 14:11:01 I would have thought that we are continuing to use
bokan 2016/04/21 15:27:04 If so, this comment is misleading.
alessandroa 2016/04/21 20:39:40 Yes. We are using the texture from before the pinc
alessandroa 2016/04/21 20:39:40 Old comment. Sorry!
+ this.doRender_ = 0;
bokan 2016/04/21 18:20:17 This isn't inside a mightZoom though so we won't s
alessandroa 2016/04/21 20:39:40 True. I removed the doRender_ as we don't send the
+ this.prevScale = 1;
+ this.oldCenterInContent =
+ this.frameToContent(this.containerCenter(ev.center), this.zoom_);
+
+ var needsScrollbars = this.documentNeedsScrollbars_(this.zoom_);
+ if (!needsScrollbars.horizontal)
+ this.changeCenter_ = true;
+ else
+ this.changeCenter_ = false;
+ // We keep track of begining of the pinch.
+ // By doing so we will be able to compute the pan distance.
+ this.pinch_start_ = ev.center;
bokan 2016/04/21 15:22:06 More descriptive name please. pinch_start_ -> firs
alessandroa 2016/04/21 20:39:40 Acknowledged.
+ },
+
+ pinchZoomEnd: function(ev) {
+ this.mightZoom_(function() {
+ // We want to render the document on pinch end
+ this.doRender_ = 1;
+ var scaleDelta = ev.scale / this.prevScale;
+ this.pinchCenter_ = ev.center;
+
+ this.setPinchZoomInternal_(scaleDelta, this.containerCenter(ev.center));
+ this.updateViewport_();
+ }.bind(this));
+ },
+
+ containerCenter: function(pageCenter) {
bokan 2016/04/21 15:22:06 This function would be better described as "frameT
alessandroa 2016/04/21 20:39:40 Acknowledged.
+ var container = $('plugin');
+ return {
+ x: pageCenter.x - container.getBoundingClientRect().left,
+ y: pageCenter.y - container.getBoundingClientRect().top
+ };
+ },
+
+ /**
* Go to the given page index.
* @param {number} page the index of the page to go to. zero-based.
*/

Powered by Google App Engine
This is Rietveld 408576698