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 * Viewport class controls the way the image is displayed (scale, offset etc). | 6 * Viewport class controls the way the image is displayed (scale, offset etc). |
7 * @constructor | 7 * @constructor |
8 * @struct | 8 * @struct |
9 */ | 9 */ |
10 function Viewport() { | 10 function Viewport() { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 /** | 186 /** |
187 * Obtains the rotation value. | 187 * Obtains the rotation value. |
188 * @return {number} Current rotation value. | 188 * @return {number} Current rotation value. |
189 */ | 189 */ |
190 Viewport.prototype.getRotation = function() { | 190 Viewport.prototype.getRotation = function() { |
191 return this.rotation_; | 191 return this.rotation_; |
192 }; | 192 }; |
193 | 193 |
194 /** | 194 /** |
195 * Obtains the scale for the specified image size. | 195 * Obtains the scale for the specified image size. |
196 * | 196 * |
mtomasz
2015/05/14 00:32:32
ni: Please update jsdoc.
hirono
2015/05/14 01:57:21
Done.
| |
197 * @param {number} width Width of the full resolution image. | 197 * @param {number} width Width of the full resolution image. |
198 * @param {number} height Height of the full resolution image. | 198 * @param {number} height Height of the full resolution image. |
199 * @return {number} The ratio of the full resotion image size and the calculated | 199 * @return {number} The ratio of the full resotion image size and the calculated |
200 * displayed image size. | 200 * displayed image size. |
201 * @private | 201 * @private |
202 */ | 202 */ |
203 Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) { | 203 Viewport.prototype.getFittingScaleForImageSize_ = function( |
204 var scaleX = this.screenBounds_.width / width; | 204 width, height, maxWidth, maxHeight) { |
205 var scaleY = this.screenBounds_.height / height; | 205 return Math.min( |
206 return Math.min(scaleX, scaleY, 1); | 206 maxWidth / width, |
207 maxHeight / height, | |
208 this.screenBounds_.width / width, | |
209 this.screenBounds_.height / height); | |
207 }; | 210 }; |
208 | 211 |
209 /** | 212 /** |
210 * Returns offset X. | 213 * Returns offset X. |
211 * @return {number} X-offset of the viewport. | 214 * @return {number} X-offset of the viewport. |
212 */ | 215 */ |
213 Viewport.prototype.getOffsetX = function() { return this.offsetX_; }; | 216 Viewport.prototype.getOffsetX = function() { return this.offsetX_; }; |
214 | 217 |
215 /** | 218 /** |
216 * Returns offset Y. | 219 * Returns offset Y. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 assert(this.imageBoundsOnScreen_); | 273 assert(this.imageBoundsOnScreen_); |
271 return this.imageBoundsOnScreen_; | 274 return this.imageBoundsOnScreen_; |
272 }; | 275 }; |
273 | 276 |
274 /** | 277 /** |
275 * The image bounds in screen coordinates. | 278 * The image bounds in screen coordinates. |
276 * This returns the bounds of element before applying zoom and offset. | 279 * This returns the bounds of element before applying zoom and offset. |
277 * @return {!ImageRect} | 280 * @return {!ImageRect} |
278 */ | 281 */ |
279 Viewport.prototype.getImageElementBoundsOnScreen = function() { | 282 Viewport.prototype.getImageElementBoundsOnScreen = function() { |
280 assert(this.imageElementBoundsOnScreen_); | 283 assert(this.imageElementBoundsOnScreen_); |
mtomasz
2015/05/13 10:27:10
nit: This seems to be used only in this.getDeviceB
hirono
2015/05/14 01:57:21
Done.
| |
281 return this.imageElementBoundsOnScreen_; | 284 return this.imageElementBoundsOnScreen_; |
282 }; | 285 }; |
283 | 286 |
284 /** | 287 /** |
285 * The image bounds on screen, which is clipped with the screen size. | 288 * The image bounds on screen, which is clipped with the screen size. |
286 * @return {!ImageRect} | 289 * @return {!ImageRect} |
287 */ | 290 */ |
288 Viewport.prototype.getImageBoundsOnScreenClipped = function() { | 291 Viewport.prototype.getImageBoundsOnScreenClipped = function() { |
289 assert(this.imageBoundsOnScreenClipped_); | 292 assert(this.imageBoundsOnScreenClipped_); |
290 return this.imageBoundsOnScreenClipped_; | 293 return this.imageBoundsOnScreenClipped_; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
399 this.update_(); | 402 this.update_(); |
400 }; | 403 }; |
401 | 404 |
402 /** | 405 /** |
403 * Recalculate the viewport parameters. | 406 * Recalculate the viewport parameters. |
404 * @private | 407 * @private |
405 */ | 408 */ |
406 Viewport.prototype.update_ = function() { | 409 Viewport.prototype.update_ = function() { |
407 // Update scale. | 410 // Update scale. |
408 this.scale_ = this.getFittingScaleForImageSize_( | 411 this.scale_ = this.getFittingScaleForImageSize_( |
412 this.imageBounds_.width, this.imageBounds_.height, | |
409 this.imageBounds_.width, this.imageBounds_.height); | 413 this.imageBounds_.width, this.imageBounds_.height); |
410 | 414 |
411 // Limit offset values. | 415 // Limit offset values. |
412 var zoomedWidht; | 416 var zoomedWidht; |
413 var zoomedHeight; | 417 var zoomedHeight; |
414 if (this.rotation_ % 2 == 0) { | 418 if (this.rotation_ % 2 == 0) { |
415 zoomedWidht = ~~(this.imageBounds_.width * this.scale_ * this.zoom_); | 419 zoomedWidht = ~~(this.imageBounds_.width * this.scale_ * this.zoom_); |
416 zoomedHeight = ~~(this.imageBounds_.height * this.scale_ * this.zoom_); | 420 zoomedHeight = ~~(this.imageBounds_.height * this.scale_ * this.zoom_); |
417 } else { | 421 } else { |
418 var scale = this.getFittingScaleForImageSize_( | 422 var scale = this.getFittingScaleForImageSize_( |
423 this.imageBounds_.height, this.imageBounds_.width, | |
419 this.imageBounds_.height, this.imageBounds_.width); | 424 this.imageBounds_.height, this.imageBounds_.width); |
420 zoomedWidht = ~~(this.imageBounds_.height * scale * this.zoom_); | 425 zoomedWidht = ~~(this.imageBounds_.height * scale * this.zoom_); |
421 zoomedHeight = ~~(this.imageBounds_.width * scale * this.zoom_); | 426 zoomedHeight = ~~(this.imageBounds_.width * scale * this.zoom_); |
422 } | 427 } |
423 var dx = Math.max(zoomedWidht - this.screenBounds_.width, 0) / 2; | 428 var dx = Math.max(zoomedWidht - this.screenBounds_.width, 0) / 2; |
424 var dy = Math.max(zoomedHeight - this.screenBounds_.height, 0) / 2; | 429 var dy = Math.max(zoomedHeight - this.screenBounds_.height, 0) / 2; |
425 this.offsetX_ = ImageUtil.clamp(-dx, this.offsetX_, dx); | 430 this.offsetX_ = ImageUtil.clamp(-dx, this.offsetX_, dx); |
426 this.offsetY_ = ImageUtil.clamp(-dy, this.offsetY_, dy); | 431 this.offsetY_ = ImageUtil.clamp(-dy, this.offsetY_, dy); |
427 | 432 |
428 // Image bounds on screen. | 433 // Image bounds on screen. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 viewport.scale_ = this.scale_; | 469 viewport.scale_ = this.scale_; |
465 viewport.zoom_ = this.zoom_; | 470 viewport.zoom_ = this.zoom_; |
466 viewport.offsetX_ = this.offsetX_; | 471 viewport.offsetX_ = this.offsetX_; |
467 viewport.offsetY_ = this.offsetY_; | 472 viewport.offsetY_ = this.offsetY_; |
468 viewport.rotation_ = this.rotation_; | 473 viewport.rotation_ = this.rotation_; |
469 viewport.generation_ = this.generation_; | 474 viewport.generation_ = this.generation_; |
470 viewport.update_(); | 475 viewport.update_(); |
471 return viewport; | 476 return viewport; |
472 }; | 477 }; |
473 | 478 |
479 Viewport.prototype.getScreenRectTransformation = function( | |
mtomasz
2015/05/14 00:32:32
nit: jsdoc missing
hirono
2015/05/14 01:57:21
Done.
| |
480 width, height, screenRect) { | |
481 var dx = screenRect.left + (screenRect.width - width) / 2; | |
482 var dy = screenRect.top + (screenRect.height - height) / 2; | |
483 | |
484 return [ | |
mtomasz
2015/05/14 00:32:32
optional: I think simply concatenating is easier t
hirono
2015/05/14 01:57:21
I tries to create stringFormat helper function. Do
| |
485 'translate(', dx, 'px,', dy, 'px) ', | |
486 'scale(', screenRect.width / width, ',', screenRect.height / height, ') ' | |
487 ].join(''); | |
488 }; | |
489 | |
490 Viewport.prototype.getCroppingTransformation = function( | |
mtomasz
2015/05/14 00:32:32
nit: jsdoc missing
hirono
2015/05/14 01:57:21
Done.
| |
491 width, | |
492 height, | |
493 wholeWidthMax, | |
494 wholeHeightMax, | |
495 cropRect) { | |
496 var fittingScale = this.getFittingScaleForImageSize_( | |
497 wholeWidthMax, wholeHeightMax, wholeWidthMax, wholeHeightMax); | |
498 var wholeWidth = wholeWidthMax * fittingScale; | |
499 var wholeHeight = wholeHeightMax * fittingScale; | |
500 var wholeLeft = (this.screenBounds_.width - wholeWidth) / 2; | |
501 var wholeTop = (this.screenBounds_.height - wholeHeight) / 2; | |
502 return this.getScreenRectTransformation( | |
503 width, | |
504 height, | |
505 new ImageRect( | |
506 wholeLeft + cropRect.left * fittingScale, | |
507 wholeTop + cropRect.top * fittingScale, | |
508 cropRect.width * fittingScale, | |
509 cropRect.height * fittingScale)); | |
510 }; | |
511 | |
474 /** | 512 /** |
475 * Obtains CSS transformation for the screen image. | 513 * Obtains CSS transformation for the screen image. |
514 * @param {number} width Width of image. | |
515 * @param {number} height Height of image. | |
516 * @param {number=} opt_dx Amount of horizontal shift. | |
476 * @return {string} Transformation description. | 517 * @return {string} Transformation description. |
477 */ | 518 */ |
478 Viewport.prototype.getTransformation = function() { | 519 Viewport.prototype.getTransformation = function(width, height, opt_dx) { |
479 var rotationScaleAdjustment; | 520 return this.getTransformationInternal_( |
480 if (this.rotation_ % 2) { | 521 width, |
481 rotationScaleAdjustment = this.getFittingScaleForImageSize_( | 522 height, |
482 this.imageBounds_.height, this.imageBounds_.width) / this.scale_; | 523 this.rotation_, |
483 } else { | 524 this.zoom_, |
484 rotationScaleAdjustment = 1; | 525 this.offsetX_ + (opt_dx || 0), |
485 } | 526 this.offsetY_, |
486 return [ | 527 null); |
487 'translate(' + this.offsetX_ + 'px, ' + this.offsetY_ + 'px) ', | |
488 'rotate(' + (this.rotation_ * 90) + 'deg)', | |
489 'scale(' + (this.zoom_ * rotationScaleAdjustment) + ')' | |
490 ].join(' '); | |
491 }; | 528 }; |
492 | 529 |
493 /** | 530 /** |
494 * Obtains shift CSS transformation for the screen image. | |
495 * @param {number} dx Amount of shift. | |
496 * @return {string} Transformation description. | |
497 */ | |
498 Viewport.prototype.getShiftTransformation = function(dx) { | |
499 return 'translateX(' + dx + 'px) ' + this.getTransformation(); | |
500 }; | |
501 | |
502 /** | |
503 * Obtains CSS transformation that makes the rotated image fit the original | 531 * Obtains CSS transformation that makes the rotated image fit the original |
504 * image. The new rotated image that the transformation is applied to looks the | 532 * image. The new rotated image that the transformation is applied to looks the |
505 * same with original image. | 533 * same with original image. |
506 * | 534 * |
507 * @param {boolean} orientation Orientation of the rotation from the original | 535 * @param {number} rotation90 Orientation of the rotation from the original |
mtomasz
2015/05/14 00:32:32
nit: Why the name is rotation90? It's hard for me
hirono
2015/05/14 01:57:21
It was number of times for 90 degrees. e.g. 180 de
| |
508 * image to the rotated image. True is for clockwise and false is for | 536 * image to the rotated image. True is for clockwise and false is for |
mtomasz
2015/05/14 00:32:32
nit: Please update the comment, it's not bool anym
hirono
2015/05/14 01:57:21
Done.
| |
509 * counterclockwise. | 537 * counterclockwise. |
510 * @return {string} Transformation description. | 538 * @return {string} Transformation description. |
511 */ | 539 */ |
512 Viewport.prototype.getInverseTransformForRotatedImage = function(orientation) { | 540 Viewport.prototype.getRotatingTransformation = function( |
513 var previousImageWidth = this.imageBounds_.height; | 541 width, height, rotation90) { |
514 var previousImageHeight = this.imageBounds_.width; | 542 return this.getTransformationInternal_( |
515 var oldScale = this.getFittingScaleForImageSize_( | 543 width, height, rotation90, 1, 0, 0, null); |
516 previousImageWidth, previousImageHeight); | |
517 var scaleRatio = oldScale / this.scale_; | |
518 var degree = orientation ? '-90deg' : '90deg'; | |
519 return [ | |
520 'scale(' + scaleRatio + ')', | |
521 'rotate(' + degree + ')', | |
522 this.getTransformation() | |
523 ].join(' '); | |
524 }; | 544 }; |
525 | 545 |
526 /** | 546 /** |
527 * Obtains CSS transformation that makes the cropped image fit the original | 547 * @private |
mtomasz
2015/05/14 00:32:32
nit: @jsdoc missing
hirono
2015/05/14 01:57:21
Done.
| |
528 * image. The new cropped image that the transformation is applied to fits to | |
529 * the cropped rectangle in the original image. | |
530 * | |
531 * @param {number} imageWidth Width of the original image. | |
532 * @param {number} imageHeight Height of the original image. | |
533 * @param {!ImageRect} imageCropRect Crop rectangle in the image's coordinate | |
534 * system. | |
535 * @return {string} Transformation description. | |
536 */ | 548 */ |
537 Viewport.prototype.getInverseTransformForCroppedImage = | 549 Viewport.prototype.getTransformationInternal_ = function( |
538 function(imageWidth, imageHeight, imageCropRect) { | 550 width, |
539 var wholeScale = this.getFittingScaleForImageSize_( | 551 height, |
540 imageWidth, imageHeight); | 552 rotation90, |
541 var croppedScale = this.getFittingScaleForImageSize_( | 553 zoom, |
542 imageCropRect.width, imageCropRect.height); | 554 offsetX, |
543 var dx = | 555 offsetY, |
544 (imageCropRect.left + imageCropRect.width / 2 - imageWidth / 2) * | 556 cropRect) { |
545 wholeScale; | 557 var rotatedWidth = rotation90 % 2 ? height : width; |
546 var dy = | 558 var rotatedHeight = rotation90 % 2 ? width : height; |
547 (imageCropRect.top + imageCropRect.height / 2 - imageHeight / 2) * | 559 var rotatedMaxWidth = rotation90 % 2 ? |
548 wholeScale; | 560 this.imageBounds_.height : this.imageBounds_.width; |
561 var rotatedMaxHeight = rotation90 % 2 ? | |
562 this.imageBounds_.width : this.imageBounds_.height; | |
563 | |
564 // Scale. | |
565 var fittingScale = this.getFittingScaleForImageSize_( | |
566 rotatedWidth, rotatedHeight, rotatedMaxWidth, rotatedMaxHeight); | |
567 | |
568 // Offset for centering. | |
569 var dx = (this.screenBounds_.width - width) / 2; | |
570 var dy = (this.screenBounds_.height - height) / 2; | |
571 | |
549 return [ | 572 return [ |
550 'translate(' + dx + 'px,' + dy + 'px)', | 573 'translate(', dx + offsetX, 'px,', dy + offsetY, 'px) ', |
551 'scale(' + wholeScale / croppedScale + ')', | 574 'scale(', fittingScale * zoom, ') ', |
552 this.getTransformation() | 575 'rotate(', rotation90 * 90, 'deg) ' |
553 ].join(' '); | 576 ].join(''); |
554 }; | 577 }; |
555 | |
556 /** | |
557 * Obtains CSS transformation that makes the image fit to the screen rectangle. | |
558 * | |
559 * @param {!ImageRect} screenRect Screen rectangle. | |
560 * @return {string} Transformation description. | |
561 */ | |
562 Viewport.prototype.getScreenRectTransformForImage = function(screenRect) { | |
563 var imageBounds = this.getImageElementBoundsOnScreen(); | |
564 var scaleX = screenRect.width / imageBounds.width; | |
565 var scaleY = screenRect.height / imageBounds.height; | |
566 var screenWidth = this.screenBounds_.width; | |
567 var screenHeight = this.screenBounds_.height; | |
568 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2; | |
569 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2; | |
570 return [ | |
571 'translate(' + dx + 'px,' + dy + 'px)', | |
572 'scale(' + scaleX + ',' + scaleY + ')', | |
573 this.getTransformation() | |
574 ].join(' '); | |
575 }; | |
OLD | NEW |