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 |