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 */ |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 this.beforeZoomCallback_ = beforeZoomCallback; | 42 this.beforeZoomCallback_ = beforeZoomCallback; |
43 this.afterZoomCallback_ = afterZoomCallback; | 43 this.afterZoomCallback_ = afterZoomCallback; |
44 this.allowedToChangeZoom_ = false; | 44 this.allowedToChangeZoom_ = false; |
45 this.zoom_ = 1; | 45 this.zoom_ = 1; |
46 this.documentDimensions_ = null; | 46 this.documentDimensions_ = null; |
47 this.pageDimensions_ = []; | 47 this.pageDimensions_ = []; |
48 this.scrollbarWidth_ = scrollbarWidth; | 48 this.scrollbarWidth_ = scrollbarWidth; |
49 this.fittingType_ = Viewport.FittingType.NONE; | 49 this.fittingType_ = Viewport.FittingType.NONE; |
50 this.defaultZoom_ = defaultZoom; | 50 this.defaultZoom_ = defaultZoom; |
51 this.topToolbarHeight_ = topToolbarHeight; | 51 this.topToolbarHeight_ = topToolbarHeight; |
52 this.prevScale = 1; | |
53 this.doRender_ = 1; | |
52 | 54 |
53 window.addEventListener('scroll', this.updateViewport_.bind(this)); | 55 window.addEventListener('scroll', this.updateViewport_.bind(this)); |
54 window.addEventListener('resize', this.resize_.bind(this)); | 56 window.addEventListener('resize', this.resize_.bind(this)); |
55 } | 57 } |
56 | 58 |
57 /** | 59 /** |
58 * Enumeration of page fitting types. | 60 * Enumeration of page fitting types. |
59 * @enum {string} | 61 * @enum {string} |
60 */ | 62 */ |
61 Viewport.FittingType = { | 63 Viewport.FittingType = { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 this.sizer_.style.width = zoomedDimensions.width + 'px'; | 165 this.sizer_.style.width = zoomedDimensions.width + 'px'; |
164 this.sizer_.style.height = zoomedDimensions.height + | 166 this.sizer_.style.height = zoomedDimensions.height + |
165 this.topToolbarHeight_ + 'px'; | 167 this.topToolbarHeight_ + 'px'; |
166 } | 168 } |
167 }, | 169 }, |
168 | 170 |
169 /** | 171 /** |
170 * @private | 172 * @private |
171 * Called when the viewport should be updated. | 173 * Called when the viewport should be updated. |
172 */ | 174 */ |
173 updateViewport_: function() { | 175 updateViewport_: function() { this.viewportChangedCallback_(); }, |
174 this.viewportChangedCallback_(); | |
175 }, | |
176 | 176 |
177 /** | 177 /** |
178 * @private | 178 * @private |
179 * Called when the viewport size changes. | 179 * Called when the viewport size changes. |
180 */ | 180 */ |
181 resize_: function() { | 181 resize_: function() { |
182 if (this.fittingType_ == Viewport.FittingType.FIT_TO_PAGE) | 182 if (this.fittingType_ == Viewport.FittingType.FIT_TO_PAGE) |
183 this.fitToPageInternal_(false); | 183 this.fitToPageInternal_(false); |
184 else if (this.fittingType_ == Viewport.FittingType.FIT_TO_WIDTH) | 184 else if (this.fittingType_ == Viewport.FittingType.FIT_TO_WIDTH) |
185 this.fitToWidth(); | 185 this.fitToWidth(); |
(...skipping 28 matching lines...) Expand all Loading... | |
214 var scrollbarHeight = needsScrollbars.horizontal ? this.scrollbarWidth_ : 0; | 214 var scrollbarHeight = needsScrollbars.horizontal ? this.scrollbarWidth_ : 0; |
215 return { | 215 return { |
216 width: this.window_.innerWidth - scrollbarWidth, | 216 width: this.window_.innerWidth - scrollbarWidth, |
217 height: this.window_.innerHeight - scrollbarHeight | 217 height: this.window_.innerHeight - scrollbarHeight |
218 }; | 218 }; |
219 }, | 219 }, |
220 | 220 |
221 /** | 221 /** |
222 * @type {number} the zoom level of the viewport. | 222 * @type {number} the zoom level of the viewport. |
223 */ | 223 */ |
224 get zoom() { | 224 get zoom() { return this.zoom_; }, |
225 return this.zoom_; | |
226 }, | |
227 | 225 |
228 /** | 226 /** |
229 * @private | 227 * @private |
230 * Used to wrap a function that might perform zooming on the viewport. This is | 228 * Used to wrap a function that might perform zooming on the viewport. This is |
231 * required so that we can notify the plugin that zooming is in progress | 229 * required so that we can notify the plugin that zooming is in progress |
232 * so that while zooming is taking place it can stop reacting to scroll events | 230 * so that while zooming is taking place it can stop reacting to scroll events |
233 * from the viewport. This is to avoid flickering. | 231 * from the viewport. This is to avoid flickering. |
234 */ | 232 */ |
235 mightZoom_: function(f) { | 233 mightZoom_: function(f) { |
236 this.beforeZoomCallback_(); | 234 this.beforeZoomCallback_(); |
237 this.allowedToChangeZoom_ = true; | 235 this.allowedToChangeZoom_ = true; |
238 f(); | 236 f(); |
237 var needsScrollbars = this.documentNeedsScrollbars_(this.zoom_); | |
238 if (!needsScrollbars.horizontal) { | |
239 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
| |
240 x: this.window_.innerWidth / 2, | |
241 y: this.window_.innerHeight / 2 | |
242 }; | |
243 } | |
239 this.allowedToChangeZoom_ = false; | 244 this.allowedToChangeZoom_ = false; |
240 this.afterZoomCallback_(); | 245 this.afterZoomCallback_(); |
241 }, | 246 }, |
242 | 247 |
243 /** | 248 /** |
244 * @private | 249 * @private |
245 * Sets the zoom of the viewport. | 250 * Sets the zoom of the viewport. |
246 * @param {number} newZoom the zoom level to zoom to. | 251 * @param {number} newZoom the zoom level to zoom to. |
247 */ | 252 */ |
248 setZoomInternal_: function(newZoom) { | 253 setZoomInternal_: function(newZoom) { |
249 if (!this.allowedToChangeZoom_) { | 254 if (!this.allowedToChangeZoom_) { |
250 throw 'Called Viewport.setZoomInternal_ without calling ' + | 255 throw 'Called Viewport.setZoomInternal_ without calling ' + |
251 'Viewport.mightZoom_.'; | 256 'Viewport.mightZoom_.'; |
252 } | 257 } |
253 // Record the scroll position (relative to the top-left of the window). | 258 // Record the scroll position (relative to the top-left of the window). |
254 var currentScrollPos = { | 259 var currentScrollPos = { |
255 x: this.position.x / this.zoom_, | 260 x: this.position.x / this.zoom_, |
256 y: this.position.y / this.zoom_ | 261 y: this.position.y / this.zoom_ |
257 }; | 262 }; |
258 this.zoom_ = newZoom; | 263 this.zoom_ = newZoom; |
259 this.contentSizeChanged_(); | 264 this.contentSizeChanged_(); |
260 // Scroll to the scaled scroll position. | 265 // Scroll to the scaled scroll position. |
261 this.position = { | 266 this.position = { |
262 x: currentScrollPos.x * newZoom, | 267 x: currentScrollPos.x * newZoom, |
263 y: currentScrollPos.y * newZoom | 268 y: currentScrollPos.y * newZoom |
264 }; | 269 }; |
265 }, | 270 }, |
266 | 271 |
267 /** | 272 /** |
273 * @private | |
274 * Sets the cusotm zoom of the viewport. | |
bokan
2016/04/21 02:24:01
"cusotm" -> "custom"
alessandroa
2016/04/21 20:39:39
Acknowledged.
| |
275 * Same function as below but for pinch zoom we have some more operations. | |
276 * @param {number} scaleDelta the zoom delta. | |
277 * @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.
| |
278 */ | |
279 setPinchZoomInternal_: function(scaleDelta, center) { | |
280 if (!this.allowedToChangeZoom_) { | |
281 throw 'Called Viewport.setZoomInternal_ without calling ' + | |
282 'Viewport.mightZoom_.'; | |
283 } | |
284 this.zoom_ = this.clampScale(this.zoom_ * scaleDelta); | |
285 | |
286 var newCenterInContent = this.frameToContent(center, this.zoom_); | |
287 var delta = { | |
288 x: (newCenterInContent.x - this.oldCenterInContent.x), | |
289 y: (newCenterInContent.y - this.oldCenterInContent.y) | |
290 }; | |
291 | |
292 // Record the scroll position (relative to the pinch center). | |
293 var currentScrollPos = { | |
294 x: this.position.x - delta.x * this.zoom_, | |
295 y: this.position.y - delta.y * this.zoom_ | |
296 }; | |
297 | |
298 this.contentSizeChanged_(); | |
299 // Scroll to the scaled scroll position. | |
300 this.position = {x: currentScrollPos.x, y: currentScrollPos.y}; | |
301 //Update last scale for the current pinch event | |
302 this.prevScale *= scaleDelta; | |
bokan
2016/04/21 15:22:06
prevScale is used entirely in the handlers to calc
| |
303 }, | |
304 | |
305 /** | |
306 * @private | |
307 * Makes sure that the scale level doesn't get out of the limits. | |
308 * @param {number} scale the new scale level | |
309 * @return {number} the scale clamped in the limit | |
310 */ | |
311 clampScale: function(scale) { return Math.min(5, Math.max(0.25, scale)); }, | |
312 | |
313 /** | |
314 * @private | |
315 * Gets the new center in content. | |
316 * @param {Object} pinch center | |
317 * @param {Object} zoom level | |
318 * @return {Objet} the new center in content | |
319 */ | |
320 frameToContent: function(framePoint, scale) { | |
321 return { | |
322 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.
| |
323 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
| |
324 }; | |
325 }, | |
326 | |
327 /** | |
268 * Sets the zoom to the given zoom level. | 328 * Sets the zoom to the given zoom level. |
269 * @param {number} newZoom the zoom level to zoom to. | 329 * @param {number} newZoom the zoom level to zoom to. |
270 */ | 330 */ |
271 setZoom: function(newZoom) { | 331 setZoom: function(newZoom) { |
272 this.fittingType_ = Viewport.FittingType.NONE; | 332 this.fittingType_ = Viewport.FittingType.NONE; |
273 newZoom = Math.max(Viewport.ZOOM_FACTOR_RANGE.min, | 333 newZoom = Math.max(Viewport.ZOOM_FACTOR_RANGE.min, |
274 Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); | 334 Math.min(newZoom, Viewport.ZOOM_FACTOR_RANGE.max)); |
275 this.mightZoom_(function() { | 335 this.mightZoom_(function() { |
276 this.setZoomInternal_(newZoom); | 336 this.setZoomInternal_(newZoom); |
277 this.updateViewport_(); | 337 this.updateViewport_(); |
278 }.bind(this)); | 338 }.bind(this)); |
279 }, | 339 }, |
280 | 340 |
281 /** | 341 /** |
282 * @type {number} the width of scrollbars in the viewport in pixels. | 342 * @type {number} the width of scrollbars in the viewport in pixels. |
283 */ | 343 */ |
284 get scrollbarWidth() { | 344 get scrollbarWidth() { return this.scrollbarWidth_; }, |
285 return this.scrollbarWidth_; | |
286 }, | |
287 | 345 |
288 /** | 346 /** |
289 * @type {Viewport.FittingType} the fitting type the viewport is currently in. | 347 * @type {Viewport.FittingType} the fitting type the viewport is currently in. |
290 */ | 348 */ |
291 get fittingType() { | 349 get fittingType() { return this.fittingType_; }, |
292 return this.fittingType_; | |
293 }, | |
294 | 350 |
295 /** | 351 /** |
296 * @private | 352 * @private |
297 * @param {integer} y the y-coordinate to get the page at. | 353 * @param {integer} y the y-coordinate to get the page at. |
298 * @return {integer} the index of a page overlapping the given y-coordinate. | 354 * @return {integer} the index of a page overlapping the given y-coordinate. |
299 */ | 355 */ |
300 getPageAtY_: function(y) { | 356 getPageAtY_: function(y) { |
301 var min = 0; | 357 var min = 0; |
302 var max = this.pageDimensions_.length - 1; | 358 var max = this.pageDimensions_.length - 1; |
303 while (max >= min) { | 359 while (max >= min) { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
449 this.setZoomInternal_(this.computeFittingZoom_(dimensions, false)); | 505 this.setZoomInternal_(this.computeFittingZoom_(dimensions, false)); |
450 if (scrollToTopOfPage) { | 506 if (scrollToTopOfPage) { |
451 this.position = { | 507 this.position = { |
452 x: 0, | 508 x: 0, |
453 y: this.pageDimensions_[page].y * this.zoom_ | 509 y: this.pageDimensions_[page].y * this.zoom_ |
454 }; | 510 }; |
455 } | 511 } |
456 this.updateViewport_(); | 512 this.updateViewport_(); |
457 }.bind(this)); | 513 }.bind(this)); |
458 }, | 514 }, |
515 /** | |
516 * @private | |
517 * Computes vector between two points. | |
518 * @param {Object} First Point | |
519 * @param {Object} Second Point | |
520 * @return {Object} The vector | |
521 */ | |
522 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.
| |
523 var vector = { | |
524 x: p2.x - p1.x, | |
525 y: p2.y - p1.y | |
526 }; | |
527 return vector; | |
528 }, | |
459 | 529 |
460 /** | 530 /** |
461 * Zoom the viewport so that a page consumes the entire viewport. Also scrolls | 531 * Zoom the viewport so that a page consumes the entire viewport. Also scrolls |
462 * the viewport to the top of the current page. | 532 * the viewport to the top of the current page. |
463 */ | 533 */ |
464 fitToPage: function() { | 534 fitToPage: function() { this.fitToPageInternal_(true); }, |
465 this.fitToPageInternal_(true); | |
466 }, | |
467 | 535 |
468 /** | 536 /** |
469 * Zoom out to the next predefined zoom level. | 537 * Zoom out to the next predefined zoom level. |
470 */ | 538 */ |
471 zoomOut: function() { | 539 zoomOut: function() { |
472 this.mightZoom_(function() { | 540 this.mightZoom_(function() { |
473 this.fittingType_ = Viewport.FittingType.NONE; | 541 this.fittingType_ = Viewport.FittingType.NONE; |
474 var nextZoom = Viewport.ZOOM_FACTORS[0]; | 542 var nextZoom = Viewport.ZOOM_FACTORS[0]; |
475 for (var i = 0; i < Viewport.ZOOM_FACTORS.length; i++) { | 543 for (var i = 0; i < Viewport.ZOOM_FACTORS.length; i++) { |
476 if (Viewport.ZOOM_FACTORS[i] < this.zoom_) | 544 if (Viewport.ZOOM_FACTORS[i] < this.zoom_) |
(...skipping 14 matching lines...) Expand all Loading... | |
491 for (var i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) { | 559 for (var i = Viewport.ZOOM_FACTORS.length - 1; i >= 0; i--) { |
492 if (Viewport.ZOOM_FACTORS[i] > this.zoom_) | 560 if (Viewport.ZOOM_FACTORS[i] > this.zoom_) |
493 nextZoom = Viewport.ZOOM_FACTORS[i]; | 561 nextZoom = Viewport.ZOOM_FACTORS[i]; |
494 } | 562 } |
495 this.setZoomInternal_(nextZoom); | 563 this.setZoomInternal_(nextZoom); |
496 this.updateViewport_(); | 564 this.updateViewport_(); |
497 }.bind(this)); | 565 }.bind(this)); |
498 }, | 566 }, |
499 | 567 |
500 /** | 568 /** |
569 * Pinch zoom event handler | |
570 * @param {ev} the pinch event | |
571 */ | |
572 pinchZoom: function(ev) { | |
573 this.mightZoom_(function() { | |
574 if (ev.additionalEvent == 'pinchin') | |
bokan
2016/04/21 15:22:06
Add a comment explaining why we render only on pin
| |
575 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 :)
| |
576 else | |
577 this.doRender_ = 0; | |
578 | |
579 var scaleDelta = ev.scale / this.prevScale; | |
580 this.pinchPanVector_ = this.vectorDistance(ev.center, this.pinch_start_); | |
581 | |
582 var needsScrollbars = this.documentNeedsScrollbars_( | |
583 this.clampScale(this.zoom_ * scaleDelta)); | |
584 // 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 ..
| |
585 // 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.
| |
586 if (this.changeCenter_ && needsScrollbars.horizontal) { | |
587 this.oldCenterInContent = | |
588 this.frameToContent(this.containerCenter(ev.center), this.zoom_); | |
589 this.changeCenter_ = false; | |
590 } | |
591 | |
592 this.pinchCenter_ = ev.center; | |
593 this.setPinchZoomInternal_(scaleDelta, this.containerCenter(ev.center)); | |
594 this.updateViewport_(); | |
595 }.bind(this)); | |
596 }, | |
597 | |
598 pinchZoomStart: function(ev) { | |
599 //We render the document once before pinch. | |
600 //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!
| |
601 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
| |
602 this.prevScale = 1; | |
603 this.oldCenterInContent = | |
604 this.frameToContent(this.containerCenter(ev.center), this.zoom_); | |
605 | |
606 var needsScrollbars = this.documentNeedsScrollbars_(this.zoom_); | |
607 if (!needsScrollbars.horizontal) | |
608 this.changeCenter_ = true; | |
609 else | |
610 this.changeCenter_ = false; | |
611 // We keep track of begining of the pinch. | |
612 // By doing so we will be able to compute the pan distance. | |
613 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.
| |
614 }, | |
615 | |
616 pinchZoomEnd: function(ev) { | |
617 this.mightZoom_(function() { | |
618 // We want to render the document on pinch end | |
619 this.doRender_ = 1; | |
620 var scaleDelta = ev.scale / this.prevScale; | |
621 this.pinchCenter_ = ev.center; | |
622 | |
623 this.setPinchZoomInternal_(scaleDelta, this.containerCenter(ev.center)); | |
624 this.updateViewport_(); | |
625 }.bind(this)); | |
626 }, | |
627 | |
628 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.
| |
629 var container = $('plugin'); | |
630 return { | |
631 x: pageCenter.x - container.getBoundingClientRect().left, | |
632 y: pageCenter.y - container.getBoundingClientRect().top | |
633 }; | |
634 }, | |
635 | |
636 /** | |
501 * Go to the given page index. | 637 * Go to the given page index. |
502 * @param {number} page the index of the page to go to. zero-based. | 638 * @param {number} page the index of the page to go to. zero-based. |
503 */ | 639 */ |
504 goToPage: function(page) { | 640 goToPage: function(page) { |
505 this.mightZoom_(function() { | 641 this.mightZoom_(function() { |
506 if (this.pageDimensions_.length === 0) | 642 if (this.pageDimensions_.length === 0) |
507 return; | 643 return; |
508 if (page < 0) | 644 if (page < 0) |
509 page = 0; | 645 page = 0; |
510 if (page >= this.pageDimensions_.length) | 646 if (page >= this.pageDimensions_.length) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
589 spaceOnLeft = Math.max(spaceOnLeft, 0); | 725 spaceOnLeft = Math.max(spaceOnLeft, 0); |
590 | 726 |
591 return { | 727 return { |
592 x: x * this.zoom_ + spaceOnLeft - this.window_.pageXOffset, | 728 x: x * this.zoom_ + spaceOnLeft - this.window_.pageXOffset, |
593 y: insetDimensions.y * this.zoom_ - this.window_.pageYOffset, | 729 y: insetDimensions.y * this.zoom_ - this.window_.pageYOffset, |
594 width: insetDimensions.width * this.zoom_, | 730 width: insetDimensions.width * this.zoom_, |
595 height: insetDimensions.height * this.zoom_ | 731 height: insetDimensions.height * this.zoom_ |
596 }; | 732 }; |
597 } | 733 } |
598 }; | 734 }; |
OLD | NEW |