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

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
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 */
mtomasz 2014/07/10 07:26:52 optional: // for normal comments, /** ... */ for j
hirono 2014/07/10 08:16:06 Done.
15 this.scale_ = 1; 30 this.scale_ = 1;
16 this.offsetX_ = 0; 31 this.offsetX_ = 0;
17 this.offsetY_ = 0; 32 this.offsetY_ = 0;
18 33
19 this.generation_ = 0; 34 this.generation_ = 0;
20 35
21 this.scaleControl_ = null;
22 this.repaintCallbacks_ = []; 36 this.repaintCallbacks_ = [];
23 this.update(); 37 this.update();
24 } 38 }
25 39
26 /*
27 * Viewport modification.
28 */
29
30 /**
31 * @param {Object} scaleControl The UI object responsible for scaling.
32 */
33 Viewport.prototype.setScaleControl = function(scaleControl) {
34 this.scaleControl_ = scaleControl;
35 };
36
37 /** 40 /**
38 * @param {number} width Image width. 41 * @param {number} width Image width.
39 * @param {number} height Image height. 42 * @param {number} height Image height.
40 */ 43 */
41 Viewport.prototype.setImageSize = function(width, height) { 44 Viewport.prototype.setImageSize = function(width, height) {
42 this.imageBounds_ = new Rect(width, height); 45 this.imageBounds_ = new Rect(width, height);
43 if (this.scaleControl_) this.scaleControl_.displayImageSize(width, height);
44 this.invalidateCaches(); 46 this.invalidateCaches();
45 }; 47 };
46 48
47 /** 49 /**
48 * @param {number} width Screen width. 50 * @param {number} width Screen width.
49 * @param {number} height Screen height. 51 * @param {number} height Screen height.
50 */ 52 */
51 Viewport.prototype.setScreenSize = function(width, height) { 53 Viewport.prototype.setScreenSize = function(width, height) {
52 this.screenBounds_ = new Rect(width, height); 54 this.screenBounds_ = new Rect(width, height);
53 if (this.scaleControl_)
54 this.scaleControl_.setMinScale(this.getFittingScale());
55 this.invalidateCaches(); 55 this.invalidateCaches();
56 }; 56 };
57 57
58 /** 58 /**
59 * Set the size by an HTML element. 59 * Set the size by an HTML element.
60 * 60 *
61 * @param {HTMLElement} frame The element acting as the "screen". 61 * @param {HTMLElement} frame The element acting as the "screen".
62 */ 62 */
63 Viewport.prototype.sizeByFrame = function(frame) { 63 Viewport.prototype.sizeByFrame = function(frame) {
64 this.setScreenSize(frame.clientWidth, frame.clientHeight); 64 this.setScreenSize(frame.clientWidth, frame.clientHeight);
(...skipping 18 matching lines...) Expand all
83 */ 83 */
84 Viewport.prototype.getScale = function() { return this.scale_; }; 84 Viewport.prototype.getScale = function() { return this.scale_; };
85 85
86 /** 86 /**
87 * @param {number} scale The new scale. 87 * @param {number} scale The new scale.
88 * @param {boolean} notify True if the change should be reflected in the UI. 88 * @param {boolean} notify True if the change should be reflected in the UI.
89 */ 89 */
90 Viewport.prototype.setScale = function(scale, notify) { 90 Viewport.prototype.setScale = function(scale, notify) {
91 if (this.scale_ == scale) return; 91 if (this.scale_ == scale) return;
92 this.scale_ = scale; 92 this.scale_ = scale;
93 if (notify && this.scaleControl_) this.scaleControl_.displayScale(scale);
94 this.invalidateCaches(); 93 this.invalidateCaches();
95 }; 94 };
96 95
97 /** 96 /**
98 * @return {number} Best scale to fit the current image into the current screen. 97 * @return {number} Best scale to fit the current image into the current screen.
99 */ 98 */
100 Viewport.prototype.getFittingScale = function() { 99 Viewport.prototype.getFittingScale = function() {
101 var scaleX = this.screenBounds_.width / this.imageBounds_.width; 100 return this.getFittingScaleForImageSize_(
102 var scaleY = this.screenBounds_.height / this.imageBounds_.height; 101 this.imageBounds_.width, this.imageBounds_.height);
102 };
103
104 Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) {
mtomasz 2014/07/10 07:26:52 nit: Please add jsdoc.
hirono 2014/07/10 08:16:05 Done.
105 var scaleX = this.screenBounds_.width / width;
106 var scaleY = this.screenBounds_.height / height;
103 // Scales > (1 / this.getDevicePixelRatio()) do not look good. Also they are 107 // Scales > (1 / this.getDevicePixelRatio()) do not look good. Also they are
mtomasz 2014/07/10 07:26:52 Please update the comment (this.getDevicePixelRati
hirono 2014/07/10 08:16:06 Done.
104 // not really useful as we do not have any pixel-level operations. 108 // not really useful as we do not have any pixel-level operations.
105 return Math.min(1 / Viewport.getDevicePixelRatio(), scaleX, scaleY); 109 return Math.min(1 / devicePixelRatio, scaleX, scaleY);
mtomasz 2014/07/10 07:26:52 nit: devicePixelRatio looks undefined. How about:
hirono 2014/07/10 08:16:06 Done.
106 }; 110 }
107 111
108 /** 112 /**
109 * Set the scale to fit the image into the screen. 113 * Set the scale to fit the image into the screen.
110 */ 114 */
111 Viewport.prototype.fitImage = function() { 115 Viewport.prototype.fitImage = function() {
112 var scale = this.getFittingScale(); 116 var scale = this.getFittingScale();
113 if (this.scaleControl_) this.scaleControl_.setMinScale(scale);
114 this.setScale(scale, true); 117 this.setScale(scale, true);
115 }; 118 };
116 119
117 /** 120 /**
118 * @return {number} X-offset of the viewport. 121 * @return {number} X-offset of the viewport.
119 */ 122 */
120 Viewport.prototype.getOffsetX = function() { return this.offsetX_; }; 123 Viewport.prototype.getOffsetX = function() { return this.offsetX_; };
121 124
122 /** 125 /**
123 * @return {number} Y-offset of the viewport. 126 * @return {number} Y-offset of the viewport.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 */ 291 */
289 Viewport.prototype.imageToScreenRect = function(rect) { 292 Viewport.prototype.imageToScreenRect = function(rect) {
290 return new Rect( 293 return new Rect(
291 this.imageToScreenX(rect.left), 294 this.imageToScreenX(rect.left),
292 this.imageToScreenY(rect.top), 295 this.imageToScreenY(rect.top),
293 Math.round(this.imageToScreenSize(rect.width)), 296 Math.round(this.imageToScreenSize(rect.width)),
294 Math.round(this.imageToScreenSize(rect.height))); 297 Math.round(this.imageToScreenSize(rect.height)));
295 }; 298 };
296 299
297 /** 300 /**
298 * @return {number} The number of physical pixels in one CSS pixel.
299 */
300 Viewport.getDevicePixelRatio = function() { return window.devicePixelRatio; };
301
302 /**
303 * Convert a rectangle from screen coordinates to 'device' coordinates. 301 * Convert a rectangle from screen coordinates to 'device' coordinates.
304 * 302 *
305 * This conversion enlarges the original rectangle devicePixelRatio times 303 * This conversion enlarges the original rectangle devicePixelRatio times
306 * with the screen center as a fixed point. 304 * with the screen center as a fixed point.
307 * 305 *
308 * @param {Rect} rect Rectangle in screen coordinates. 306 * @param {Rect} rect Rectangle in screen coordinates.
309 * @return {Rect} Rectangle in device coordinates. 307 * @return {Rect} Rectangle in device coordinates.
310 */ 308 */
311 Viewport.prototype.screenToDeviceRect = function(rect) { 309 Viewport.prototype.screenToDeviceRect = function(rect) {
312 var ratio = Viewport.getDevicePixelRatio(); 310 var ratio = devicePixelRatio;
313 var screenCenterX = Math.round( 311 var screenCenterX = Math.round(
314 this.screenBounds_.left + this.screenBounds_.width / 2); 312 this.screenBounds_.left + this.screenBounds_.width / 2);
315 var screenCenterY = Math.round( 313 var screenCenterY = Math.round(
316 this.screenBounds_.top + this.screenBounds_.height / 2); 314 this.screenBounds_.top + this.screenBounds_.height / 2);
317 return new Rect(screenCenterX + (rect.left - screenCenterX) * ratio, 315 return new Rect(screenCenterX + (rect.left - screenCenterX) * ratio,
318 screenCenterY + (rect.top - screenCenterY) * ratio, 316 screenCenterY + (rect.top - screenCenterY) * ratio,
319 rect.width * ratio, 317 rect.width * ratio,
320 rect.height * ratio); 318 rect.height * ratio);
321 }; 319 };
322 320
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 }; 421 };
424 422
425 /** 423 /**
426 * Repaint all clients. 424 * Repaint all clients.
427 */ 425 */
428 Viewport.prototype.repaint = function() { 426 Viewport.prototype.repaint = function() {
429 this.update(); 427 this.update();
430 for (var i = 0; i != this.repaintCallbacks_.length; i++) 428 for (var i = 0; i != this.repaintCallbacks_.length; i++)
431 this.repaintCallbacks_[i](); 429 this.repaintCallbacks_[i]();
432 }; 430 };
431
432 /**
433 * Obtains CSS transformation for the screen image.
434 * @return {string} Transformation description.
435 */
436 Viewport.prototype.getTransformation = function() {
437 return 'scale(' + (1 / devicePixelRatio) + ')';
438 };
439
440 /**
441 * Obtains shift CSS transformation for the screen image.
442 * @param {number} dx Amount of shift.
443 * @return {string} Transformation description.
444 */
445 Viewport.prototype.getShiftTransformation = function(dx) {
446 return 'translateX(' + dx + 'px) ' + this.getTransformation();
447 };
448
449 /**
450 * Obtains CSS transformation that makes the rotated image fit the original
451 * image. The new rotated image that the transformation is applied to looks the
452 * same with original image.
453 *
454 * @param {boolean} orientation Orientation of the rotation from the original
455 * image to the rotated image. True is for clockwise and false is for
456 * counterclockwise.
457 * @return {string} Transformation description.
458 */
459 Viewport.prototype.getInverseTransformForRotatedImage = function(orientation) {
460 var previousImageWidth = this.imageBounds_.height;
461 var previousImageHeight = this.imageBounds_.width;
462 var oldScale = this.getFittingScaleForImageSize_(
463 previousImageWidth, previousImageHeight);
464 var scaleRatio = oldScale / this.getScale();
465 var degree = orientation ? '-90deg' : '90deg';
466 return [
467 'scale(' + (scaleRatio) + ')',
mtomasz 2014/07/10 07:26:52 nit: inner () redundant?
hirono 2014/07/10 08:16:06 Done.
468 'rotate(' + degree + ')',
469 this.getTransformation()
470 ].join(' ');
471 };
472
473 /**
474 * Obtains CSS transformation that makes the cropped image fit the original
475 * image. The new cropped image that the transformaton is applied to fits to the
476 * the cropped rectangle in the original image.
477 *
478 * @param {number} imageWidth Width of the original image.
479 * @param {number} imageHeight Height of the origianl image.
480 * @param {Rect} imageCropRect Crop rectangle in the image's coordinate system.
481 * @return {string} Transformation description.
482 */
483 Viewport.prototype.getInverseTransformForCroppedImage =
484 function(imageWidth, imageHeight, imageCropRect) {
485 var wholeScale = this.getFittingScaleForImageSize_(
486 imageWidth, imageHeight);
487 var croppedScale = this.getFittingScaleForImageSize_(
488 imageCropRect.width, imageCropRect.height);
489 var dx =
490 (imageCropRect.left + imageCropRect.width / 2 - imageWidth / 2) *
491 wholeScale;
492 var dy =
493 (imageCropRect.top + imageCropRect.height / 2 - imageHeight / 2) *
494 wholeScale;
495 return [
496 'translate(' + dx + 'px,' + dy + 'px)',
497 'scale(' + wholeScale / croppedScale + ')',
498 this.getTransformation()
499 ].join(' ');
500 };
501
502 /**
503 * Obtains CSS transformaton that makes the image fit to the screen rectangle.
504 *
505 * @param {Rect} screenRect Screen rectangle.
506 * @return {string} Transformation description.
507 */
508 Viewport.prototype.getScreenRectTransformForImage = function(screenRect) {
509 var screenImageWidth = this.imageBounds_.width * this.getScale();
510 var screenImageHeight = this.imageBounds_.height * this.getScale();
511 var scaleX = screenRect.width / screenImageWidth;
512 var scaleY = screenRect.height /screenImageHeight;
mtomasz 2014/07/10 07:26:52 nit: space after '/'.
hirono 2014/07/10 08:16:06 Done.
513 var screenWidth = this.screenBounds_.width;
514 var screenHeight = this.screenBounds_.height;
515 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2;
516 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2;
517 return [
518 'translate(' + dx + 'px,' + dy + 'px)',
519 'scale(' + scaleX + ',' + scaleY + ')',
520 this.getTransformation()
521 ].join(' ');
522 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698