| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Returns the height of the intersection of two rectangles. | 6 * Returns the height of the intersection of two rectangles. |
| 7 * @param {Object} rect1 the first rect | 7 * @param {Object} rect1 the first rect |
| 8 * @param {Object} rect2 the second rect | 8 * @param {Object} rect2 the second rect |
| 9 * @return {number} the height of the intersection of the rects | 9 * @return {number} the height of the intersection of the rects |
| 10 */ | 10 */ |
| 11 function getIntersectionHeight(rect1, rect2) { | 11 function getIntersectionHeight(rect1, rect2) { |
| 12 return Math.max(0, | 12 return Math.max( |
| 13 0, |
| 13 Math.min(rect1.y + rect1.height, rect2.y + rect2.height) - | 14 Math.min(rect1.y + rect1.height, rect2.y + rect2.height) - |
| 14 Math.max(rect1.y, rect2.y)); | 15 Math.max(rect1.y, rect2.y)); |
| 15 } | 16 } |
| 16 | 17 |
| 17 /** | 18 /** |
| 18 * Makes sure that the scale level doesn't get out of the limits. | 19 * Makes sure that the scale level doesn't get out of the limits. |
| 19 * @param {number} scale The new scale level. | 20 * @param {number} scale The new scale level. |
| 20 * @return {number} The scale clamped within the limits. | 21 * @return {number} The scale clamped within the limits. |
| 21 */ | 22 */ |
| 22 function clampScale(scale) { | 23 function clampScale(scale) { |
| 23 return Math.min(5, Math.max(0.25, scale)); | 24 return Math.min(5, Math.max(0.25, scale)); |
| 24 } | 25 } |
| 25 | 26 |
| 26 /** | 27 /** |
| 27 * Computes vector between two points. | 28 * Computes vector between two points. |
| 28 * @param {!Object} p1 The first point. | 29 * @param {!Object} p1 The first point. |
| 29 * @param {!Object} p2 The second point. | 30 * @param {!Object} p2 The second point. |
| 30 * @return {!Object} The vector. | 31 * @return {!Object} The vector. |
| 31 */ | 32 */ |
| 32 function vectorDelta(p1, p2) { | 33 function vectorDelta(p1, p2) { |
| 33 return { | 34 return {x: p2.x - p1.x, y: p2.y - p1.y}; |
| 34 x: p2.x - p1.x, | |
| 35 y: p2.y - p1.y | |
| 36 }; | |
| 37 } | 35 } |
| 38 | 36 |
| 39 function frameToPluginCoordinate(coordinateInFrame) { | 37 function frameToPluginCoordinate(coordinateInFrame) { |
| 40 var container = $('plugin'); | 38 var container = $('plugin'); |
| 41 return { | 39 return { |
| 42 x: coordinateInFrame.x - container.getBoundingClientRect().left, | 40 x: coordinateInFrame.x - container.getBoundingClientRect().left, |
| 43 y: coordinateInFrame.y - container.getBoundingClientRect().top | 41 y: coordinateInFrame.y - container.getBoundingClientRect().top |
| 44 }; | 42 }; |
| 45 } | 43 } |
| 46 | 44 |
| 47 /** | 45 /** |
| 48 * Create a new viewport. | 46 * Create a new viewport. |
| 49 * @constructor | 47 * @constructor |
| 50 * @param {Window} window the window | 48 * @param {Window} window the window |
| 51 * @param {Object} sizer is the element which represents the size of the | 49 * @param {Object} sizer is the element which represents the size of the |
| 52 * document in the viewport | 50 * document in the viewport |
| 53 * @param {Function} viewportChangedCallback is run when the viewport changes | 51 * @param {Function} viewportChangedCallback is run when the viewport changes |
| 54 * @param {Function} beforeZoomCallback is run before a change in zoom | 52 * @param {Function} beforeZoomCallback is run before a change in zoom |
| 55 * @param {Function} afterZoomCallback is run after a change in zoom | 53 * @param {Function} afterZoomCallback is run after a change in zoom |
| 56 * @param {number} scrollbarWidth the width of scrollbars on the page | 54 * @param {number} scrollbarWidth the width of scrollbars on the page |
| 57 * @param {number} defaultZoom The default zoom level. | 55 * @param {number} defaultZoom The default zoom level. |
| 58 * @param {number} topToolbarHeight The number of pixels that should initially | 56 * @param {number} topToolbarHeight The number of pixels that should initially |
| 59 * be left blank above the document for the toolbar. | 57 * be left blank above the document for the toolbar. |
| 60 */ | 58 */ |
| 61 function Viewport(window, | 59 function Viewport( |
| 62 sizer, | 60 window, sizer, viewportChangedCallback, beforeZoomCallback, |
| 63 viewportChangedCallback, | 61 afterZoomCallback, scrollbarWidth, defaultZoom, topToolbarHeight) { |
| 64 beforeZoomCallback, | |
| 65 afterZoomCallback, | |
| 66 scrollbarWidth, | |
| 67 defaultZoom, | |
| 68 topToolbarHeight) { | |
| 69 this.window_ = window; | 62 this.window_ = window; |
| 70 this.sizer_ = sizer; | 63 this.sizer_ = sizer; |
| 71 this.viewportChangedCallback_ = viewportChangedCallback; | 64 this.viewportChangedCallback_ = viewportChangedCallback; |
| 72 this.beforeZoomCallback_ = beforeZoomCallback; | 65 this.beforeZoomCallback_ = beforeZoomCallback; |
| 73 this.afterZoomCallback_ = afterZoomCallback; | 66 this.afterZoomCallback_ = afterZoomCallback; |
| 74 this.allowedToChangeZoom_ = false; | 67 this.allowedToChangeZoom_ = false; |
| 75 this.internalZoom_ = 1; | 68 this.internalZoom_ = 1; |
| 76 this.zoomManager_ = new InactiveZoomManager(this, 1); | 69 this.zoomManager_ = new InactiveZoomManager(this, 1); |
| 77 this.documentDimensions_ = null; | 70 this.documentDimensions_ = null; |
| 78 this.pageDimensions_ = []; | 71 this.pageDimensions_ = []; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 * these events. | 113 * these events. |
| 121 */ | 114 */ |
| 122 Viewport.SCROLL_INCREMENT = 40; | 115 Viewport.SCROLL_INCREMENT = 40; |
| 123 | 116 |
| 124 /** | 117 /** |
| 125 * Predefined zoom factors to be used when zooming in/out. These are in | 118 * Predefined zoom factors to be used when zooming in/out. These are in |
| 126 * ascending order. This should match the lists in | 119 * ascending order. This should match the lists in |
| 127 * components/ui/zoom/page_zoom_constants.h and | 120 * components/ui/zoom/page_zoom_constants.h and |
| 128 * chrome/browser/resources/settings/appearance_page/appearance_page.js | 121 * chrome/browser/resources/settings/appearance_page/appearance_page.js |
| 129 */ | 122 */ |
| 130 Viewport.ZOOM_FACTORS = [0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, | 123 Viewport.ZOOM_FACTORS = [ |
| 131 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5]; | 124 0.25, 1 / 3, 0.5, 2 / 3, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, |
| 125 4, 5 |
| 126 ]; |
| 132 | 127 |
| 133 /** | 128 /** |
| 134 * The minimum and maximum range to be used to clip zoom factor. | 129 * The minimum and maximum range to be used to clip zoom factor. |
| 135 */ | 130 */ |
| 136 Viewport.ZOOM_FACTOR_RANGE = { | 131 Viewport.ZOOM_FACTOR_RANGE = { |
| 137 min: Viewport.ZOOM_FACTORS[0], | 132 min: Viewport.ZOOM_FACTORS[0], |
| 138 max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1] | 133 max: Viewport.ZOOM_FACTORS[Viewport.ZOOM_FACTORS.length - 1] |
| 139 }; | 134 }; |
| 140 | 135 |
| 141 /** | 136 /** |
| 142 * The width of the page shadow around pages in pixels. | 137 * The width of the page shadow around pages in pixels. |
| 143 */ | 138 */ |
| 144 Viewport.PAGE_SHADOW = {top: 3, bottom: 7, left: 5, right: 5}; | 139 Viewport.PAGE_SHADOW = { |
| 140 top: 3, |
| 141 bottom: 7, |
| 142 left: 5, |
| 143 right: 5 |
| 144 }; |
| 145 | 145 |
| 146 Viewport.prototype = { | 146 Viewport.prototype = { |
| 147 /** | 147 /** |
| 148 * Returns the zoomed and rounded document dimensions for the given zoom. | 148 * Returns the zoomed and rounded document dimensions for the given zoom. |
| 149 * Rounding is necessary when interacting with the renderer which tends to | 149 * Rounding is necessary when interacting with the renderer which tends to |
| 150 * operate in integral values (for example for determining if scrollbars | 150 * operate in integral values (for example for determining if scrollbars |
| 151 * should be shown). | 151 * should be shown). |
| 152 * @param {number} zoom The zoom to use to compute the scaled dimensions. | 152 * @param {number} zoom The zoom to use to compute the scaled dimensions. |
| 153 * @return {Object} A dictionary with scaled 'width'/'height' of the document. | 153 * @return {Object} A dictionary with scaled 'width'/'height' of the document. |
| 154 * @private | 154 * @private |
| (...skipping 11 matching lines...) Expand all Loading... |
| 166 * @private | 166 * @private |
| 167 * Returns true if the document needs scrollbars at the given zoom level. | 167 * Returns true if the document needs scrollbars at the given zoom level. |
| 168 * @param {number} zoom compute whether scrollbars are needed at this zoom | 168 * @param {number} zoom compute whether scrollbars are needed at this zoom |
| 169 * @return {Object} with 'horizontal' and 'vertical' keys which map to bool | 169 * @return {Object} with 'horizontal' and 'vertical' keys which map to bool |
| 170 * values indicating if the horizontal and vertical scrollbars are needed | 170 * values indicating if the horizontal and vertical scrollbars are needed |
| 171 * respectively. | 171 * respectively. |
| 172 */ | 172 */ |
| 173 documentNeedsScrollbars_: function(zoom) { | 173 documentNeedsScrollbars_: function(zoom) { |
| 174 var zoomedDimensions = this.getZoomedDocumentDimensions_(zoom); | 174 var zoomedDimensions = this.getZoomedDocumentDimensions_(zoom); |
| 175 if (!zoomedDimensions) { | 175 if (!zoomedDimensions) { |
| 176 return { | 176 return {horizontal: false, vertical: false}; |
| 177 horizontal: false, | |
| 178 vertical: false | |
| 179 }; | |
| 180 } | 177 } |
| 181 | 178 |
| 182 // If scrollbars are required for one direction, expand the document in the | 179 // If scrollbars are required for one direction, expand the document in the |
| 183 // other direction to take the width of the scrollbars into account when | 180 // other direction to take the width of the scrollbars into account when |
| 184 // deciding whether the other direction needs scrollbars. | 181 // deciding whether the other direction needs scrollbars. |
| 185 if (zoomedDimensions.width > this.window_.innerWidth) | 182 if (zoomedDimensions.width > this.window_.innerWidth) |
| 186 zoomedDimensions.height += this.scrollbarWidth_; | 183 zoomedDimensions.height += this.scrollbarWidth_; |
| 187 else if (zoomedDimensions.height > this.window_.innerHeight) | 184 else if (zoomedDimensions.height > this.window_.innerHeight) |
| 188 zoomedDimensions.width += this.scrollbarWidth_; | 185 zoomedDimensions.width += this.scrollbarWidth_; |
| 189 return { | 186 return { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 204 }, | 201 }, |
| 205 | 202 |
| 206 /** | 203 /** |
| 207 * @private | 204 * @private |
| 208 * Helper function called when the zoomed document size changes. | 205 * Helper function called when the zoomed document size changes. |
| 209 */ | 206 */ |
| 210 contentSizeChanged_: function() { | 207 contentSizeChanged_: function() { |
| 211 var zoomedDimensions = this.getZoomedDocumentDimensions_(this.zoom); | 208 var zoomedDimensions = this.getZoomedDocumentDimensions_(this.zoom); |
| 212 if (zoomedDimensions) { | 209 if (zoomedDimensions) { |
| 213 this.sizer_.style.width = zoomedDimensions.width + 'px'; | 210 this.sizer_.style.width = zoomedDimensions.width + 'px'; |
| 214 this.sizer_.style.height = zoomedDimensions.height + | 211 this.sizer_.style.height = |
| 215 this.topToolbarHeight_ + 'px'; | 212 zoomedDimensions.height + this.topToolbarHeight_ + 'px'; |
| 216 } | 213 } |
| 217 }, | 214 }, |
| 218 | 215 |
| 219 /** | 216 /** |
| 220 * @private | 217 * @private |
| 221 * Called when the viewport should be updated. | 218 * Called when the viewport should be updated. |
| 222 */ | 219 */ |
| 223 updateViewport_: function() { | 220 updateViewport_: function() { |
| 224 this.viewportChangedCallback_(); | 221 this.viewportChangedCallback_(); |
| 225 }, | 222 }, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 }, | 319 }, |
| 323 | 320 |
| 324 /** | 321 /** |
| 325 * @private | 322 * @private |
| 326 * Sets the zoom of the viewport. | 323 * Sets the zoom of the viewport. |
| 327 * @param {number} newZoom the zoom level to zoom to. | 324 * @param {number} newZoom the zoom level to zoom to. |
| 328 */ | 325 */ |
| 329 setZoomInternal_: function(newZoom) { | 326 setZoomInternal_: function(newZoom) { |
| 330 if (!this.allowedToChangeZoom_) { | 327 if (!this.allowedToChangeZoom_) { |
| 331 throw 'Called Viewport.setZoomInternal_ without calling ' + | 328 throw 'Called Viewport.setZoomInternal_ without calling ' + |
| 332 'Viewport.mightZoom_.'; | 329 'Viewport.mightZoom_.'; |
| 333 } | 330 } |
| 334 // Record the scroll position (relative to the top-left of the window). | 331 // Record the scroll position (relative to the top-left of the window). |
| 335 var currentScrollPos = { | 332 var currentScrollPos = { |
| 336 x: this.position.x / this.zoom, | 333 x: this.position.x / this.zoom, |
| 337 y: this.position.y / this.zoom | 334 y: this.position.y / this.zoom |
| 338 }; | 335 }; |
| 339 this.internalZoom_ = newZoom; | 336 this.internalZoom_ = newZoom; |
| 340 this.contentSizeChanged_(); | 337 this.contentSizeChanged_(); |
| 341 // Scroll to the scaled scroll position. | 338 // Scroll to the scaled scroll position. |
| 342 this.position = { | 339 this.position = { |
| 343 x: currentScrollPos.x * this.zoom, | 340 x: currentScrollPos.x * this.zoom, |
| 344 y: currentScrollPos.y * this.zoom | 341 y: currentScrollPos.y * this.zoom |
| 345 }; | 342 }; |
| 346 }, | 343 }, |
| 347 | 344 |
| 348 /** | 345 /** |
| 349 * @private | 346 * @private |
| 350 * Sets the zoom of the viewport. | 347 * Sets the zoom of the viewport. |
| 351 * Same as setZoomInternal_ but for pinch zoom we have some more operations. | 348 * Same as setZoomInternal_ but for pinch zoom we have some more operations. |
| 352 * @param {number} scaleDelta The zoom delta. | 349 * @param {number} scaleDelta The zoom delta. |
| 353 * @param {!Object} center The pinch center in content coordinates. | 350 * @param {!Object} center The pinch center in content coordinates. |
| 354 */ | 351 */ |
| 355 setPinchZoomInternal_: function(scaleDelta, center) { | 352 setPinchZoomInternal_: function(scaleDelta, center) { |
| 356 assert(this.allowedToChangeZoom_, | 353 assert( |
| 354 this.allowedToChangeZoom_, |
| 357 'Called Viewport.setPinchZoomInternal_ without calling ' + | 355 'Called Viewport.setPinchZoomInternal_ without calling ' + |
| 358 'Viewport.mightZoom_.'); | 356 'Viewport.mightZoom_.'); |
| 359 this.internalZoom_ = clampScale(this.internalZoom_ * scaleDelta); | 357 this.internalZoom_ = clampScale(this.internalZoom_ * scaleDelta); |
| 360 | 358 |
| 361 var newCenterInContent = this.frameToContent(center); | 359 var newCenterInContent = this.frameToContent(center); |
| 362 var delta = { | 360 var delta = { |
| 363 x: (newCenterInContent.x - this.oldCenterInContent.x), | 361 x: (newCenterInContent.x - this.oldCenterInContent.x), |
| 364 y: (newCenterInContent.y - this.oldCenterInContent.y) | 362 y: (newCenterInContent.y - this.oldCenterInContent.y) |
| 365 }; | 363 }; |
| 366 | 364 |
| 367 // Record the scroll position (relative to the pinch center). | 365 // Record the scroll position (relative to the pinch center). |
| 368 var currentScrollPos = { | 366 var currentScrollPos = { |
| 369 x: this.position.x - delta.x * this.zoom, | 367 x: this.position.x - delta.x * this.zoom, |
| 370 y: this.position.y - delta.y * this.zoom | 368 y: this.position.y - delta.y * this.zoom |
| 371 }; | 369 }; |
| 372 | 370 |
| 373 this.contentSizeChanged_(); | 371 this.contentSizeChanged_(); |
| 374 // Scroll to the scaled scroll position. | 372 // Scroll to the scaled scroll position. |
| 375 this.position = { | 373 this.position = {x: currentScrollPos.x, y: currentScrollPos.y}; |
| 376 x: currentScrollPos.x, | |
| 377 y: currentScrollPos.y | |
| 378 }; | |
| 379 }, | 374 }, |
| 380 | 375 |
| 381 /** | 376 /** |
| 382 * @private | 377 * @private |
| 383 * Converts a point from frame to content coordinates. | 378 * Converts a point from frame to content coordinates. |
| 384 * @param {!Object} framePoint The frame coordinates. | 379 * @param {!Object} framePoint The frame coordinates. |
| 385 * @return {!Object} The content coordinates. | 380 * @return {!Object} The content coordinates. |
| 386 */ | 381 */ |
| 387 frameToContent: function(framePoint) { | 382 frameToContent: function(framePoint) { |
| 388 // TODO(mcnee) Add a helper Point class to avoid duplicating operations | 383 // TODO(mcnee) Add a helper Point class to avoid duplicating operations |
| 389 // on plain {x,y} objects. | 384 // on plain {x,y} objects. |
| 390 return { | 385 return { |
| 391 x: (framePoint.x + this.position.x) / this.zoom, | 386 x: (framePoint.x + this.position.x) / this.zoom, |
| 392 y: (framePoint.y + this.position.y) / this.zoom | 387 y: (framePoint.y + this.position.y) / this.zoom |
| 393 }; | 388 }; |
| 394 }, | 389 }, |
| 395 | 390 |
| 396 /** | 391 /** |
| 397 * Sets the zoom to the given zoom level. | 392 * Sets the zoom to the given zoom level. |
| 398 * @param {number} newZoom the zoom level to zoom to. | 393 * @param {number} newZoom the zoom level to zoom to. |
| 399 */ | 394 */ |
| 400 setZoom: function(newZoom) { | 395 setZoom: function(newZoom) { |
| 401 this.fittingType_ = Viewport.FittingType.NONE; | 396 this.fittingType_ = Viewport.FittingType.NONE; |
| 402 newZoom = Math.max(Viewport.ZOOM_FACTOR_RANGE.min, | 397 newZoom = Math.max( |
| 403 Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); | 398 Viewport.ZOOM_FACTOR_RANGE.min, |
| 399 Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); |
| 404 this.mightZoom_(function() { | 400 this.mightZoom_(function() { |
| 405 this.setZoomInternal_(newZoom); | 401 this.setZoomInternal_(newZoom); |
| 406 this.updateViewport_(); | 402 this.updateViewport_(); |
| 407 }.bind(this)); | 403 }.bind(this)); |
| 408 }, | 404 }, |
| 409 | 405 |
| 410 /** | 406 /** |
| 411 * Gets notified of the browser zoom changing seperately from the | 407 * Gets notified of the browser zoom changing seperately from the |
| 412 * internal zoom. | 408 * internal zoom. |
| 413 * @param {number} oldBrowserZoom the previous value of the browser zoom. | 409 * @param {number} oldBrowserZoom the previous value of the browser zoom. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 var max = this.pageDimensions_.length - 1; | 450 var max = this.pageDimensions_.length - 1; |
| 455 while (max >= min) { | 451 while (max >= min) { |
| 456 var page = Math.floor(min + ((max - min) / 2)); | 452 var page = Math.floor(min + ((max - min) / 2)); |
| 457 // There might be a gap between the pages, in which case use the bottom | 453 // There might be a gap between the pages, in which case use the bottom |
| 458 // of the previous page as the top for finding the page. | 454 // of the previous page as the top for finding the page. |
| 459 var top = 0; | 455 var top = 0; |
| 460 if (page > 0) { | 456 if (page > 0) { |
| 461 top = this.pageDimensions_[page - 1].y + | 457 top = this.pageDimensions_[page - 1].y + |
| 462 this.pageDimensions_[page - 1].height; | 458 this.pageDimensions_[page - 1].height; |
| 463 } | 459 } |
| 464 var bottom = this.pageDimensions_[page].y + | 460 var bottom = |
| 465 this.pageDimensions_[page].height; | 461 this.pageDimensions_[page].y + this.pageDimensions_[page].height; |
| 466 | 462 |
| 467 if (top <= y && bottom > y) | 463 if (top <= y && bottom > y) |
| 468 return page; | 464 return page; |
| 469 else if (top > y) | 465 else if (top > y) |
| 470 max = page - 1; | 466 max = page - 1; |
| 471 else | 467 else |
| 472 min = page + 1; | 468 min = page + 1; |
| 473 } | 469 } |
| 474 return 0; | 470 return 0; |
| 475 }, | 471 }, |
| 476 | 472 |
| 477 /** | 473 /** |
| 478 * Returns the page with the greatest proportion of its height in the current | 474 * Returns the page with the greatest proportion of its height in the current |
| 479 * viewport. | 475 * viewport. |
| 480 * @return {number} the index of the most visible page. | 476 * @return {number} the index of the most visible page. |
| 481 */ | 477 */ |
| 482 getMostVisiblePage: function() { | 478 getMostVisiblePage: function() { |
| 483 var firstVisiblePage = this.getPageAtY_(this.position.y / this.zoom); | 479 var firstVisiblePage = this.getPageAtY_(this.position.y / this.zoom); |
| 484 if (firstVisiblePage == this.pageDimensions_.length - 1) | 480 if (firstVisiblePage == this.pageDimensions_.length - 1) |
| 485 return firstVisiblePage; | 481 return firstVisiblePage; |
| 486 | 482 |
| 487 var viewportRect = { | 483 var viewportRect = { |
| 488 x: this.position.x / this.zoom, | 484 x: this.position.x / this.zoom, |
| 489 y: this.position.y / this.zoom, | 485 y: this.position.y / this.zoom, |
| 490 width: this.size.width / this.zoom, | 486 width: this.size.width / this.zoom, |
| 491 height: this.size.height / this.zoom | 487 height: this.size.height / this.zoom |
| 492 }; | 488 }; |
| 493 var firstVisiblePageVisibility = getIntersectionHeight( | 489 var firstVisiblePageVisibility = |
| 494 this.pageDimensions_[firstVisiblePage], viewportRect) / | 490 getIntersectionHeight( |
| 491 this.pageDimensions_[firstVisiblePage], viewportRect) / |
| 495 this.pageDimensions_[firstVisiblePage].height; | 492 this.pageDimensions_[firstVisiblePage].height; |
| 496 var nextPageVisibility = getIntersectionHeight( | 493 var nextPageVisibility = |
| 497 this.pageDimensions_[firstVisiblePage + 1], viewportRect) / | 494 getIntersectionHeight( |
| 495 this.pageDimensions_[firstVisiblePage + 1], viewportRect) / |
| 498 this.pageDimensions_[firstVisiblePage + 1].height; | 496 this.pageDimensions_[firstVisiblePage + 1].height; |
| 499 if (nextPageVisibility > firstVisiblePageVisibility) | 497 if (nextPageVisibility > firstVisiblePageVisibility) |
| 500 return firstVisiblePage + 1; | 498 return firstVisiblePage + 1; |
| 501 return firstVisiblePage; | 499 return firstVisiblePage; |
| 502 }, | 500 }, |
| 503 | 501 |
| 504 /** | 502 /** |
| 505 * @private | 503 * @private |
| 506 * Compute the zoom level for fit-to-page or fit-to-width. |pageDimensions| is | 504 * Compute the zoom level for fit-to-page or fit-to-width. |pageDimensions| is |
| 507 * the dimensions for a given page and if |widthOnly| is true, it indicates | 505 * the dimensions for a given page and if |widthOnly| is true, it indicates |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 /** | 564 /** |
| 567 * Zoom the viewport so that the page-width consumes the entire viewport. | 565 * Zoom the viewport so that the page-width consumes the entire viewport. |
| 568 */ | 566 */ |
| 569 fitToWidth: function() { | 567 fitToWidth: function() { |
| 570 this.mightZoom_(function() { | 568 this.mightZoom_(function() { |
| 571 this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH; | 569 this.fittingType_ = Viewport.FittingType.FIT_TO_WIDTH; |
| 572 if (!this.documentDimensions_) | 570 if (!this.documentDimensions_) |
| 573 return; | 571 return; |
| 574 // When computing fit-to-width, the maximum width of a page in the | 572 // When computing fit-to-width, the maximum width of a page in the |
| 575 // document is used, which is equal to the size of the document width. | 573 // document is used, which is equal to the size of the document width. |
| 576 this.setZoomInternal_(this.computeFittingZoom_(this.documentDimensions_, | 574 this.setZoomInternal_( |
| 577 true)); | 575 this.computeFittingZoom_(this.documentDimensions_, true)); |
| 578 var page = this.getMostVisiblePage(); | 576 var page = this.getMostVisiblePage(); |
| 579 this.updateViewport_(); | 577 this.updateViewport_(); |
| 580 }.bind(this)); | 578 }.bind(this)); |
| 581 }, | 579 }, |
| 582 | 580 |
| 583 /** | 581 /** |
| 584 * @private | 582 * @private |
| 585 * Zoom the viewport so that a page consumes the entire viewport. | 583 * Zoom the viewport so that a page consumes the entire viewport. |
| 586 * @param {boolean} scrollToTopOfPage Set to true if the viewport should be | 584 * @param {boolean} scrollToTopOfPage Set to true if the viewport should be |
| 587 * scrolled to the top of the current page. Set to false if the viewport | 585 * scrolled to the top of the current page. Set to false if the viewport |
| 588 * should remain at the current scroll position. | 586 * should remain at the current scroll position. |
| 589 */ | 587 */ |
| 590 fitToPageInternal_: function(scrollToTopOfPage) { | 588 fitToPageInternal_: function(scrollToTopOfPage) { |
| 591 this.mightZoom_(function() { | 589 this.mightZoom_(function() { |
| 592 this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE; | 590 this.fittingType_ = Viewport.FittingType.FIT_TO_PAGE; |
| 593 if (!this.documentDimensions_) | 591 if (!this.documentDimensions_) |
| 594 return; | 592 return; |
| 595 var page = this.getMostVisiblePage(); | 593 var page = this.getMostVisiblePage(); |
| 596 // Fit to the current page's height and the widest page's width. | 594 // Fit to the current page's height and the widest page's width. |
| 597 var dimensions = { | 595 var dimensions = { |
| 598 width: this.documentDimensions_.width, | 596 width: this.documentDimensions_.width, |
| 599 height: this.pageDimensions_[page].height, | 597 height: this.pageDimensions_[page].height, |
| 600 }; | 598 }; |
| 601 this.setZoomInternal_(this.computeFittingZoom_(dimensions, false)); | 599 this.setZoomInternal_(this.computeFittingZoom_(dimensions, false)); |
| 602 if (scrollToTopOfPage) { | 600 if (scrollToTopOfPage) { |
| 603 this.position = { | 601 this.position = {x: 0, y: this.pageDimensions_[page].y * this.zoom}; |
| 604 x: 0, | |
| 605 y: this.pageDimensions_[page].y * this.zoom | |
| 606 }; | |
| 607 } | 602 } |
| 608 this.updateViewport_(); | 603 this.updateViewport_(); |
| 609 }.bind(this)); | 604 }.bind(this)); |
| 610 }, | 605 }, |
| 611 | 606 |
| 612 /** | 607 /** |
| 613 * Zoom the viewport so that a page consumes the entire viewport. Also scrolls | 608 * Zoom the viewport so that a page consumes the entire viewport. Also scrolls |
| 614 * the viewport to the top of the current page. | 609 * the viewport to the top of the current page. |
| 615 */ | 610 */ |
| 616 fitToPage: function() { | 611 fitToPage: function() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 }.bind(this)); | 644 }.bind(this)); |
| 650 }, | 645 }, |
| 651 | 646 |
| 652 /** | 647 /** |
| 653 * Pinch zoom event handler. | 648 * Pinch zoom event handler. |
| 654 * @param {!Object} e The pinch event. | 649 * @param {!Object} e The pinch event. |
| 655 */ | 650 */ |
| 656 pinchZoom: function(e) { | 651 pinchZoom: function(e) { |
| 657 this.mightZoom_(function() { | 652 this.mightZoom_(function() { |
| 658 this.pinchPhase_ = e.direction == 'out' ? | 653 this.pinchPhase_ = e.direction == 'out' ? |
| 659 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_OUT : | 654 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_OUT : |
| 660 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_IN; | 655 Viewport.PinchPhase.PINCH_UPDATE_ZOOM_IN; |
| 661 | 656 |
| 662 var scaleDelta = e.startScaleRatio / this.prevScale_; | 657 var scaleDelta = e.startScaleRatio / this.prevScale_; |
| 663 this.pinchPanVector_ = | 658 this.pinchPanVector_ = |
| 664 vectorDelta(e.center, this.firstPinchCenterInFrame_); | 659 vectorDelta(e.center, this.firstPinchCenterInFrame_); |
| 665 | 660 |
| 666 var needsScrollbars = this.documentNeedsScrollbars_( | 661 var needsScrollbars = |
| 667 this.zoomManager_.applyBrowserZoom( | 662 this.documentNeedsScrollbars_(this.zoomManager_.applyBrowserZoom( |
| 668 clampScale(this.internalZoom_ * scaleDelta))); | 663 clampScale(this.internalZoom_ * scaleDelta))); |
| 669 | 664 |
| 670 this.pinchCenter_ = e.center; | 665 this.pinchCenter_ = e.center; |
| 671 | 666 |
| 672 // If there's no horizontal scrolling, keep the content centered so the | 667 // If there's no horizontal scrolling, keep the content centered so the |
| 673 // user can't zoom in on the non-content area. | 668 // user can't zoom in on the non-content area. |
| 674 // TODO(mcnee) Investigate other ways of scaling when we don't have | 669 // TODO(mcnee) Investigate other ways of scaling when we don't have |
| 675 // horizontal scrolling. We want to keep the document centered, | 670 // horizontal scrolling. We want to keep the document centered, |
| 676 // but this causes a potentially awkward transition when we start | 671 // but this causes a potentially awkward transition when we start |
| 677 // using the gesture center. | 672 // using the gesture center. |
| 678 if (!needsScrollbars.horizontal) { | 673 if (!needsScrollbars.horizontal) { |
| 679 this.pinchCenter_ = { | 674 this.pinchCenter_ = { |
| 680 x: this.window_.innerWidth / 2, | 675 x: this.window_.innerWidth / 2, |
| 681 y: this.window_.innerHeight / 2 | 676 y: this.window_.innerHeight / 2 |
| 682 }; | 677 }; |
| 683 } else if (this.keepContentCentered_) { | 678 } else if (this.keepContentCentered_) { |
| 684 this.oldCenterInContent = | 679 this.oldCenterInContent = |
| 685 this.frameToContent(frameToPluginCoordinate(e.center)); | 680 this.frameToContent(frameToPluginCoordinate(e.center)); |
| 686 this.keepContentCentered_ = false; | 681 this.keepContentCentered_ = false; |
| 687 } | 682 } |
| 688 | 683 |
| 689 this.setPinchZoomInternal_( | 684 this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center)); |
| 690 scaleDelta, frameToPluginCoordinate(e.center)); | |
| 691 this.updateViewport_(); | 685 this.updateViewport_(); |
| 692 this.prevScale_ = e.startScaleRatio; | 686 this.prevScale_ = e.startScaleRatio; |
| 693 }.bind(this)); | 687 }.bind(this)); |
| 694 }, | 688 }, |
| 695 | 689 |
| 696 pinchZoomStart: function(e) { | 690 pinchZoomStart: function(e) { |
| 697 this.pinchPhase_ = Viewport.PinchPhase.PINCH_START; | 691 this.pinchPhase_ = Viewport.PinchPhase.PINCH_START; |
| 698 this.prevScale_ = 1; | 692 this.prevScale_ = 1; |
| 699 this.oldCenterInContent = | 693 this.oldCenterInContent = |
| 700 this.frameToContent(frameToPluginCoordinate(e.center)); | 694 this.frameToContent(frameToPluginCoordinate(e.center)); |
| 701 | 695 |
| 702 var needsScrollbars = this.documentNeedsScrollbars_(this.zoom); | 696 var needsScrollbars = this.documentNeedsScrollbars_(this.zoom); |
| 703 this.keepContentCentered_ = !needsScrollbars.horizontal; | 697 this.keepContentCentered_ = !needsScrollbars.horizontal; |
| 704 // We keep track of begining of the pinch. | 698 // We keep track of begining of the pinch. |
| 705 // By doing so we will be able to compute the pan distance. | 699 // By doing so we will be able to compute the pan distance. |
| 706 this.firstPinchCenterInFrame_ = e.center; | 700 this.firstPinchCenterInFrame_ = e.center; |
| 707 }, | 701 }, |
| 708 | 702 |
| 709 pinchZoomEnd: function(e) { | 703 pinchZoomEnd: function(e) { |
| 710 this.mightZoom_(function() { | 704 this.mightZoom_(function() { |
| 711 this.pinchPhase_ = Viewport.PinchPhase.PINCH_END; | 705 this.pinchPhase_ = Viewport.PinchPhase.PINCH_END; |
| 712 var scaleDelta = e.startScaleRatio / this.prevScale_; | 706 var scaleDelta = e.startScaleRatio / this.prevScale_; |
| 713 this.pinchCenter_ = e.center; | 707 this.pinchCenter_ = e.center; |
| 714 | 708 |
| 715 this.setPinchZoomInternal_( | 709 this.setPinchZoomInternal_(scaleDelta, frameToPluginCoordinate(e.center)); |
| 716 scaleDelta, frameToPluginCoordinate(e.center)); | |
| 717 this.updateViewport_(); | 710 this.updateViewport_(); |
| 718 }.bind(this)); | 711 }.bind(this)); |
| 719 | 712 |
| 720 this.pinchPhase_ = Viewport.PinchPhase.PINCH_NONE; | 713 this.pinchPhase_ = Viewport.PinchPhase.PINCH_NONE; |
| 721 this.pinchPanVector_ = null; | 714 this.pinchPanVector_ = null; |
| 722 this.pinchCenter_ = null; | 715 this.pinchCenter_ = null; |
| 723 this.firstPinchCenterInFrame_ = null; | 716 this.firstPinchCenterInFrame_ = null; |
| 724 }, | 717 }, |
| 725 | 718 |
| 726 /** | 719 /** |
| (...skipping 26 matching lines...) Expand all Loading... |
| 753 /** | 746 /** |
| 754 * Set the dimensions of the document. | 747 * Set the dimensions of the document. |
| 755 * @param {Object} documentDimensions the dimensions of the document | 748 * @param {Object} documentDimensions the dimensions of the document |
| 756 */ | 749 */ |
| 757 setDocumentDimensions: function(documentDimensions) { | 750 setDocumentDimensions: function(documentDimensions) { |
| 758 this.mightZoom_(function() { | 751 this.mightZoom_(function() { |
| 759 var initialDimensions = !this.documentDimensions_; | 752 var initialDimensions = !this.documentDimensions_; |
| 760 this.documentDimensions_ = documentDimensions; | 753 this.documentDimensions_ = documentDimensions; |
| 761 this.pageDimensions_ = this.documentDimensions_.pageDimensions; | 754 this.pageDimensions_ = this.documentDimensions_.pageDimensions; |
| 762 if (initialDimensions) { | 755 if (initialDimensions) { |
| 763 this.setZoomInternal_( | 756 this.setZoomInternal_(Math.min( |
| 764 Math.min(this.defaultZoom_, | 757 this.defaultZoom_, |
| 765 this.computeFittingZoom_(this.documentDimensions_, true))); | 758 this.computeFittingZoom_(this.documentDimensions_, true))); |
| 766 this.position = { | 759 this.position = {x: 0, y: -this.topToolbarHeight_}; |
| 767 x: 0, | |
| 768 y: -this.topToolbarHeight_ | |
| 769 }; | |
| 770 } | 760 } |
| 771 this.contentSizeChanged_(); | 761 this.contentSizeChanged_(); |
| 772 this.resize_(); | 762 this.resize_(); |
| 773 }.bind(this)); | 763 }.bind(this)); |
| 774 }, | 764 }, |
| 775 | 765 |
| 776 /** | 766 /** |
| 777 * Get the coordinates of the page contents (excluding the page shadow) | 767 * Get the coordinates of the page contents (excluding the page shadow) |
| 778 * relative to the screen. | 768 * relative to the screen. |
| 779 * @param {number} page the index of the page to get the rect for. | 769 * @param {number} page the index of the page to get the rect for. |
| 780 * @return {Object} a rect representing the page in screen coordinates. | 770 * @return {Object} a rect representing the page in screen coordinates. |
| 781 */ | 771 */ |
| 782 getPageScreenRect: function(page) { | 772 getPageScreenRect: function(page) { |
| 783 if (!this.documentDimensions_) { | 773 if (!this.documentDimensions_) { |
| 784 return { | 774 return {x: 0, y: 0, width: 0, height: 0}; |
| 785 x: 0, | |
| 786 y: 0, | |
| 787 width: 0, | |
| 788 height: 0 | |
| 789 }; | |
| 790 } | 775 } |
| 791 if (page >= this.pageDimensions_.length) | 776 if (page >= this.pageDimensions_.length) |
| 792 page = this.pageDimensions_.length - 1; | 777 page = this.pageDimensions_.length - 1; |
| 793 | 778 |
| 794 var pageDimensions = this.pageDimensions_[page]; | 779 var pageDimensions = this.pageDimensions_[page]; |
| 795 | 780 |
| 796 // Compute the page dimensions minus the shadows. | 781 // Compute the page dimensions minus the shadows. |
| 797 var insetDimensions = { | 782 var insetDimensions = { |
| 798 x: pageDimensions.x + Viewport.PAGE_SHADOW.left, | 783 x: pageDimensions.x + Viewport.PAGE_SHADOW.left, |
| 799 y: pageDimensions.y + Viewport.PAGE_SHADOW.top, | 784 y: pageDimensions.y + Viewport.PAGE_SHADOW.top, |
| 800 width: pageDimensions.width - Viewport.PAGE_SHADOW.left - | 785 width: pageDimensions.width - Viewport.PAGE_SHADOW.left - |
| 801 Viewport.PAGE_SHADOW.right, | 786 Viewport.PAGE_SHADOW.right, |
| 802 height: pageDimensions.height - Viewport.PAGE_SHADOW.top - | 787 height: pageDimensions.height - Viewport.PAGE_SHADOW.top - |
| 803 Viewport.PAGE_SHADOW.bottom | 788 Viewport.PAGE_SHADOW.bottom |
| 804 }; | 789 }; |
| 805 | 790 |
| 806 // Compute the x-coordinate of the page within the document. | 791 // Compute the x-coordinate of the page within the document. |
| 807 // TODO(raymes): This should really be set when the PDF plugin passes the | 792 // TODO(raymes): This should really be set when the PDF plugin passes the |
| 808 // page coordinates, but it isn't yet. | 793 // page coordinates, but it isn't yet. |
| 809 var x = (this.documentDimensions_.width - pageDimensions.width) / 2 + | 794 var x = (this.documentDimensions_.width - pageDimensions.width) / 2 + |
| 810 Viewport.PAGE_SHADOW.left; | 795 Viewport.PAGE_SHADOW.left; |
| 811 // Compute the space on the left of the document if the document fits | 796 // Compute the space on the left of the document if the document fits |
| 812 // completely in the screen. | 797 // completely in the screen. |
| 813 var spaceOnLeft = (this.size.width - | 798 var spaceOnLeft = |
| 814 this.documentDimensions_.width * this.zoom) / 2; | 799 (this.size.width - this.documentDimensions_.width * this.zoom) / 2; |
| 815 spaceOnLeft = Math.max(spaceOnLeft, 0); | 800 spaceOnLeft = Math.max(spaceOnLeft, 0); |
| 816 | 801 |
| 817 return { | 802 return { |
| 818 x: x * this.zoom + spaceOnLeft - this.window_.pageXOffset, | 803 x: x * this.zoom + spaceOnLeft - this.window_.pageXOffset, |
| 819 y: insetDimensions.y * this.zoom - this.window_.pageYOffset, | 804 y: insetDimensions.y * this.zoom - this.window_.pageYOffset, |
| 820 width: insetDimensions.width * this.zoom, | 805 width: insetDimensions.width * this.zoom, |
| 821 height: insetDimensions.height * this.zoom | 806 height: insetDimensions.height * this.zoom |
| 822 }; | 807 }; |
| 823 } | 808 } |
| 824 }; | 809 }; |
| OLD | NEW |