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

Side by Side Diff: ui/file_manager/gallery/js/image_editor/viewport.js

Issue 384573002: Gallery.app: Move geometry calculation for the slide image to Viewport class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/file_manager/gallery/js/image_editor/image_view.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 'use strict'; 5 'use strict';
6 6
7 /** 7 /**
8 * Viewport class controls the way the image is displayed (scale, offset etc). 8 * Viewport class controls the way the image is displayed (scale, offset etc).
9 * @constructor 9 * @constructor
10 */ 10 */
11 function Viewport() { 11 function Viewport() {
12 /**
13 * Size of the full resolution image.
14 * @type {Rect}
15 * @private
16 */
12 this.imageBounds_ = new Rect(); 17 this.imageBounds_ = new Rect();
18
19 /**
20 * Size of the application window.
21 * @type {Rect}
22 * @private
23 */
13 this.screenBounds_ = new Rect(); 24 this.screenBounds_ = new Rect();
14 25
26 /**
27 * Scale from the full resolution image to the screen displayed image. This is
28 * not zoom operated by users.
29 * @type {number}
30 * @private
31 */
15 this.scale_ = 1; 32 this.scale_ = 1;
16 this.offsetX_ = 0; 33 this.offsetX_ = 0;
17 this.offsetY_ = 0; 34 this.offsetY_ = 0;
18 35
19 this.generation_ = 0; 36 this.generation_ = 0;
20 37
21 this.repaintCallbacks_ = []; 38 this.repaintCallbacks_ = [];
22 this.update(); 39 this.update();
23 } 40 }
24 41
25 /*
26 * Viewport modification.
27 */
28
29 /** 42 /**
30 * @param {number} width Image width. 43 * @param {number} width Image width.
31 * @param {number} height Image height. 44 * @param {number} height Image height.
32 */ 45 */
33 Viewport.prototype.setImageSize = function(width, height) { 46 Viewport.prototype.setImageSize = function(width, height) {
34 this.imageBounds_ = new Rect(width, height); 47 this.imageBounds_ = new Rect(width, height);
35 this.invalidateCaches(); 48 this.invalidateCaches();
36 }; 49 };
37 50
38 /** 51 /**
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 Viewport.prototype.setScale = function(scale, notify) { 92 Viewport.prototype.setScale = function(scale, notify) {
80 if (this.scale_ == scale) return; 93 if (this.scale_ == scale) return;
81 this.scale_ = scale; 94 this.scale_ = scale;
82 this.invalidateCaches(); 95 this.invalidateCaches();
83 }; 96 };
84 97
85 /** 98 /**
86 * @return {number} Best scale to fit the current image into the current screen. 99 * @return {number} Best scale to fit the current image into the current screen.
87 */ 100 */
88 Viewport.prototype.getFittingScale = function() { 101 Viewport.prototype.getFittingScale = function() {
89 var scaleX = this.screenBounds_.width / this.imageBounds_.width; 102 return this.getFittingScaleForImageSize_(
90 var scaleY = this.screenBounds_.height / this.imageBounds_.height; 103 this.imageBounds_.width, this.imageBounds_.height);
91 // Scales > (1 / this.getDevicePixelRatio()) do not look good. Also they are
92 // not really useful as we do not have any pixel-level operations.
93 return Math.min(1 / Viewport.getDevicePixelRatio(), scaleX, scaleY);
94 }; 104 };
95 105
96 /** 106 /**
107 * Obtains the scale for the specified image size.
108 *
109 * @param {number} width Width of the full resolution image.
110 * @param {number} height Height of the full resolution image.
111 * @return {number} The ratio of the fullresotion image size and the calculated
112 * displayed image size.
113 */
114 Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) {
115 var scaleX = this.screenBounds_.width / width;
116 var scaleY = this.screenBounds_.height / height;
117 // Scales > (1 / devicePixelRatio) do not look good. Also they are
118 // not really useful as we do not have any pixel-level operations.
119 return Math.min(1 / window.devicePixelRatio, scaleX, scaleY);
120 };
121
122 /**
97 * Set the scale to fit the image into the screen. 123 * Set the scale to fit the image into the screen.
98 */ 124 */
99 Viewport.prototype.fitImage = function() { 125 Viewport.prototype.fitImage = function() {
100 var scale = this.getFittingScale(); 126 var scale = this.getFittingScale();
101 this.setScale(scale, true); 127 this.setScale(scale, true);
102 }; 128 };
103 129
104 /** 130 /**
105 * @return {number} X-offset of the viewport. 131 * @return {number} X-offset of the viewport.
106 */ 132 */
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 */ 301 */
276 Viewport.prototype.imageToScreenRect = function(rect) { 302 Viewport.prototype.imageToScreenRect = function(rect) {
277 return new Rect( 303 return new Rect(
278 this.imageToScreenX(rect.left), 304 this.imageToScreenX(rect.left),
279 this.imageToScreenY(rect.top), 305 this.imageToScreenY(rect.top),
280 Math.round(this.imageToScreenSize(rect.width)), 306 Math.round(this.imageToScreenSize(rect.width)),
281 Math.round(this.imageToScreenSize(rect.height))); 307 Math.round(this.imageToScreenSize(rect.height)));
282 }; 308 };
283 309
284 /** 310 /**
285 * @return {number} The number of physical pixels in one CSS pixel.
286 */
287 Viewport.getDevicePixelRatio = function() { return window.devicePixelRatio; };
288
289 /**
290 * Convert a rectangle from screen coordinates to 'device' coordinates. 311 * Convert a rectangle from screen coordinates to 'device' coordinates.
291 * 312 *
292 * This conversion enlarges the original rectangle devicePixelRatio times 313 * This conversion enlarges the original rectangle devicePixelRatio times
293 * with the screen center as a fixed point. 314 * with the screen center as a fixed point.
294 * 315 *
295 * @param {Rect} rect Rectangle in screen coordinates. 316 * @param {Rect} rect Rectangle in screen coordinates.
296 * @return {Rect} Rectangle in device coordinates. 317 * @return {Rect} Rectangle in device coordinates.
297 */ 318 */
298 Viewport.prototype.screenToDeviceRect = function(rect) { 319 Viewport.prototype.screenToDeviceRect = function(rect) {
299 var ratio = Viewport.getDevicePixelRatio(); 320 var ratio = window.devicePixelRatio;
300 var screenCenterX = Math.round( 321 var screenCenterX = Math.round(
301 this.screenBounds_.left + this.screenBounds_.width / 2); 322 this.screenBounds_.left + this.screenBounds_.width / 2);
302 var screenCenterY = Math.round( 323 var screenCenterY = Math.round(
303 this.screenBounds_.top + this.screenBounds_.height / 2); 324 this.screenBounds_.top + this.screenBounds_.height / 2);
304 return new Rect(screenCenterX + (rect.left - screenCenterX) * ratio, 325 return new Rect(screenCenterX + (rect.left - screenCenterX) * ratio,
305 screenCenterY + (rect.top - screenCenterY) * ratio, 326 screenCenterY + (rect.top - screenCenterY) * ratio,
306 rect.width * ratio, 327 rect.width * ratio,
307 rect.height * ratio); 328 rect.height * ratio);
308 }; 329 };
309 330
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 }; 431 };
411 432
412 /** 433 /**
413 * Repaint all clients. 434 * Repaint all clients.
414 */ 435 */
415 Viewport.prototype.repaint = function() { 436 Viewport.prototype.repaint = function() {
416 this.update(); 437 this.update();
417 for (var i = 0; i != this.repaintCallbacks_.length; i++) 438 for (var i = 0; i != this.repaintCallbacks_.length; i++)
418 this.repaintCallbacks_[i](); 439 this.repaintCallbacks_[i]();
419 }; 440 };
441
442 /**
443 * Obtains CSS transformation for the screen image.
444 * @return {string} Transformation description.
445 */
446 Viewport.prototype.getTransformation = function() {
447 return 'scale(' + (1 / window.devicePixelRatio) + ')';
448 };
449
450 /**
451 * Obtains shift CSS transformation for the screen image.
452 * @param {number} dx Amount of shift.
453 * @return {string} Transformation description.
454 */
455 Viewport.prototype.getShiftTransformation = function(dx) {
456 return 'translateX(' + dx + 'px) ' + this.getTransformation();
457 };
458
459 /**
460 * Obtains CSS transformation that makes the rotated image fit the original
461 * image. The new rotated image that the transformation is applied to looks the
462 * same with original image.
463 *
464 * @param {boolean} orientation Orientation of the rotation from the original
465 * image to the rotated image. True is for clockwise and false is for
466 * counterclockwise.
467 * @return {string} Transformation description.
468 */
469 Viewport.prototype.getInverseTransformForRotatedImage = function(orientation) {
470 var previousImageWidth = this.imageBounds_.height;
471 var previousImageHeight = this.imageBounds_.width;
472 var oldScale = this.getFittingScaleForImageSize_(
473 previousImageWidth, previousImageHeight);
474 var scaleRatio = oldScale / this.getScale();
475 var degree = orientation ? '-90deg' : '90deg';
476 return [
477 'scale(' + scaleRatio + ')',
478 'rotate(' + degree + ')',
479 this.getTransformation()
480 ].join(' ');
481 };
482
483 /**
484 * Obtains CSS transformation that makes the cropped image fit the original
485 * image. The new cropped image that the transformaton is applied to fits to the
486 * the cropped rectangle in the original image.
487 *
488 * @param {number} imageWidth Width of the original image.
489 * @param {number} imageHeight Height of the origianl image.
490 * @param {Rect} imageCropRect Crop rectangle in the image's coordinate system.
491 * @return {string} Transformation description.
492 */
493 Viewport.prototype.getInverseTransformForCroppedImage =
494 function(imageWidth, imageHeight, imageCropRect) {
495 var wholeScale = this.getFittingScaleForImageSize_(
496 imageWidth, imageHeight);
497 var croppedScale = this.getFittingScaleForImageSize_(
498 imageCropRect.width, imageCropRect.height);
499 var dx =
500 (imageCropRect.left + imageCropRect.width / 2 - imageWidth / 2) *
501 wholeScale;
502 var dy =
503 (imageCropRect.top + imageCropRect.height / 2 - imageHeight / 2) *
504 wholeScale;
505 return [
506 'translate(' + dx + 'px,' + dy + 'px)',
507 'scale(' + wholeScale / croppedScale + ')',
508 this.getTransformation()
509 ].join(' ');
510 };
511
512 /**
513 * Obtains CSS transformaton that makes the image fit to the screen rectangle.
514 *
515 * @param {Rect} screenRect Screen rectangle.
516 * @return {string} Transformation description.
517 */
518 Viewport.prototype.getScreenRectTransformForImage = function(screenRect) {
519 var screenImageWidth = this.imageBounds_.width * this.getScale();
520 var screenImageHeight = this.imageBounds_.height * this.getScale();
521 var scaleX = screenRect.width / screenImageWidth;
522 var scaleY = screenRect.height / screenImageHeight;
523 var screenWidth = this.screenBounds_.width;
524 var screenHeight = this.screenBounds_.height;
525 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2;
526 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2;
527 return [
528 'translate(' + dx + 'px,' + dy + 'px)',
529 'scale(' + scaleX + ',' + scaleY + ')',
530 this.getTransformation()
531 ].join(' ');
532 };
OLDNEW
« no previous file with comments | « ui/file_manager/gallery/js/image_editor/image_view.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698