Index: ui/file_manager/gallery/js/image_editor/viewport.js |
diff --git a/ui/file_manager/gallery/js/image_editor/viewport.js b/ui/file_manager/gallery/js/image_editor/viewport.js |
index 1250c179d614bde6c6e555e5eb43a301377fa6f7..c626486fcfac645905e95259f931c35b54bad927 100644 |
--- a/ui/file_manager/gallery/js/image_editor/viewport.js |
+++ b/ui/file_manager/gallery/js/image_editor/viewport.js |
@@ -3,6 +3,19 @@ |
// found in the LICENSE file. |
/** |
+ * Formats string by replacing place holder with actual values. |
+ * @param {string} str String includes placeholder '$n'. n starts from 1. |
+ * @param {...*} var_args Values inserted into the place holders. |
+ * @return {string} |
+ */ |
+function formatString(str, var_args) { |
+ var args = arguments; |
+ return str.replace(/\$[1-9]/g, function(placeHolder) { |
+ return args[placeHolder[1]]; |
+ }); |
+} |
+ |
+/** |
* Viewport class controls the way the image is displayed (scale, offset etc). |
* @constructor |
* @struct |
@@ -192,18 +205,24 @@ Viewport.prototype.getRotation = function() { |
}; |
/** |
- * Obtains the scale for the specified image size. |
+ * Returns image scale so that it matches screen size as long as it does not |
+ * exceed maximum size. |
* |
- * @param {number} width Width of the full resolution image. |
- * @param {number} height Height of the full resolution image. |
+ * @param {number} width Width of image. |
+ * @param {number} height Height of image. |
+ * @param {number} maxWidth Max width of image. |
+ * @param {number} maxHeight Max height of image. |
* @return {number} The ratio of the full resotion image size and the calculated |
* displayed image size. |
* @private |
*/ |
-Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) { |
- var scaleX = this.screenBounds_.width / width; |
- var scaleY = this.screenBounds_.height / height; |
- return Math.min(scaleX, scaleY, 1); |
+Viewport.prototype.getFittingScaleForImageSize_ = function( |
+ width, height, maxWidth, maxHeight) { |
+ return Math.min( |
+ maxWidth / width, |
+ maxHeight / height, |
+ this.screenBounds_.width / width, |
+ this.screenBounds_.height / height); |
}; |
/** |
@@ -248,10 +267,9 @@ Viewport.prototype.getScreenBounds = function() { return this.screenBounds_; }; |
* @return {!ImageRect} The size of screen cache canvas. |
*/ |
Viewport.prototype.getDeviceBounds = function() { |
- var size = this.getImageElementBoundsOnScreen(); |
return ImageRect.createFromWidthAndHeight( |
- size.width * window.devicePixelRatio, |
- size.height * window.devicePixelRatio); |
+ this.imageElementBoundsOnScreen_.width * window.devicePixelRatio, |
+ this.imageElementBoundsOnScreen_.height * window.devicePixelRatio); |
}; |
/** |
@@ -272,16 +290,6 @@ Viewport.prototype.getImageBoundsOnScreen = function() { |
}; |
/** |
- * The image bounds in screen coordinates. |
- * This returns the bounds of element before applying zoom and offset. |
- * @return {!ImageRect} |
- */ |
-Viewport.prototype.getImageElementBoundsOnScreen = function() { |
- assert(this.imageElementBoundsOnScreen_); |
- return this.imageElementBoundsOnScreen_; |
-}; |
- |
-/** |
* The image bounds on screen, which is clipped with the screen size. |
* @return {!ImageRect} |
*/ |
@@ -406,6 +414,7 @@ Viewport.prototype.resetView = function() { |
Viewport.prototype.update_ = function() { |
// Update scale. |
this.scale_ = this.getFittingScaleForImageSize_( |
+ this.imageBounds_.width, this.imageBounds_.height, |
this.imageBounds_.width, this.imageBounds_.height); |
// Limit offset values. |
@@ -416,6 +425,7 @@ Viewport.prototype.update_ = function() { |
zoomedHeight = ~~(this.imageBounds_.height * this.scale_ * this.zoom_); |
} else { |
var scale = this.getFittingScaleForImageSize_( |
+ this.imageBounds_.height, this.imageBounds_.width, |
this.imageBounds_.height, this.imageBounds_.width); |
zoomedWidht = ~~(this.imageBounds_.height * scale * this.zoom_); |
zoomedHeight = ~~(this.imageBounds_.width * scale * this.zoom_); |
@@ -472,31 +482,72 @@ Viewport.prototype.clone = function() { |
}; |
/** |
- * Obtains CSS transformation for the screen image. |
- * @return {string} Transformation description. |
- */ |
-Viewport.prototype.getTransformation = function() { |
- var rotationScaleAdjustment; |
- if (this.rotation_ % 2) { |
- rotationScaleAdjustment = this.getFittingScaleForImageSize_( |
- this.imageBounds_.height, this.imageBounds_.width) / this.scale_; |
- } else { |
- rotationScaleAdjustment = 1; |
- } |
- return [ |
- 'translate(' + this.offsetX_ + 'px, ' + this.offsetY_ + 'px) ', |
- 'rotate(' + (this.rotation_ * 90) + 'deg)', |
- 'scale(' + (this.zoom_ * rotationScaleAdjustment) + ')' |
- ].join(' '); |
+ * Obtains CSS transformation string that matches the image dimension with |
+ * |screenRect|. |
+ * @param {number} width Width of image. |
+ * @param {number} height Height of image. |
+ * @param {!ImageRect} screenRect Rectangle in window coordinate system. The |
+ * origin of the coordinate system at the left upper of the window. |
+ */ |
+Viewport.prototype.getScreenRectTransformation = function( |
+ width, height, screenRect) { |
+ var dx = screenRect.left + (screenRect.width - width) / 2; |
+ var dy = screenRect.top + (screenRect.height - height) / 2; |
+ |
+ return formatString( |
+ 'translate($1px,$2px) scale($3,$4)', |
+ dx, dy, screenRect.width / width, screenRect.height / height); |
+}; |
+ |
+/** |
+ * Obtains CSS transformation string that places the cropped image at the |
+ * original position in the whole image. |
+ * @param {number} width Width of cropped image. |
+ * @param {number} height Width of cropped image. |
+ * @param {number} wholeWidthMax Max width value that is used for layouting |
+ * whole image. |
+ * @param {number} wholeHeightMax Max height value that is used for layouting |
+ * whole image. |
+ * @param {!ImageRect} cropRect Crop rectangle in the whole image. The origin is |
+ * left upper of the whole image. |
+ */ |
+Viewport.prototype.getCroppingTransformation = function( |
+ width, |
+ height, |
+ wholeWidthMax, |
+ wholeHeightMax, |
+ cropRect) { |
+ var fittingScale = this.getFittingScaleForImageSize_( |
+ wholeWidthMax, wholeHeightMax, wholeWidthMax, wholeHeightMax); |
+ var wholeWidth = wholeWidthMax * fittingScale; |
+ var wholeHeight = wholeHeightMax * fittingScale; |
+ var wholeLeft = (this.screenBounds_.width - wholeWidth) / 2; |
+ var wholeTop = (this.screenBounds_.height - wholeHeight) / 2; |
+ return this.getScreenRectTransformation( |
+ width, |
+ height, |
+ new ImageRect( |
+ wholeLeft + cropRect.left * fittingScale, |
+ wholeTop + cropRect.top * fittingScale, |
+ cropRect.width * fittingScale, |
+ cropRect.height * fittingScale)); |
}; |
/** |
- * Obtains shift CSS transformation for the screen image. |
- * @param {number} dx Amount of shift. |
+ * Obtains CSS transformation for the screen image. |
+ * @param {number} width Width of image. |
+ * @param {number} height Height of image. |
+ * @param {number=} opt_dx Amount of horizontal shift. |
* @return {string} Transformation description. |
*/ |
-Viewport.prototype.getShiftTransformation = function(dx) { |
- return 'translateX(' + dx + 'px) ' + this.getTransformation(); |
+Viewport.prototype.getTransformation = function(width, height, opt_dx) { |
+ return this.getTransformationInternal_( |
+ width, |
+ height, |
+ this.rotation_, |
+ this.zoom_, |
+ this.offsetX_ + (opt_dx || 0), |
+ this.offsetY_); |
}; |
/** |
@@ -504,72 +555,57 @@ Viewport.prototype.getShiftTransformation = function(dx) { |
* image. The new rotated image that the transformation is applied to looks the |
* same with original image. |
* |
- * @param {boolean} orientation Orientation of the rotation from the original |
- * image to the rotated image. True is for clockwise and false is for |
- * counterclockwise. |
- * @return {string} Transformation description. |
- */ |
-Viewport.prototype.getInverseTransformForRotatedImage = function(orientation) { |
- var previousImageWidth = this.imageBounds_.height; |
- var previousImageHeight = this.imageBounds_.width; |
- var oldScale = this.getFittingScaleForImageSize_( |
- previousImageWidth, previousImageHeight); |
- var scaleRatio = oldScale / this.scale_; |
- var degree = orientation ? '-90deg' : '90deg'; |
- return [ |
- 'scale(' + scaleRatio + ')', |
- 'rotate(' + degree + ')', |
- this.getTransformation() |
- ].join(' '); |
-}; |
- |
-/** |
- * Obtains CSS transformation that makes the cropped image fit the original |
- * image. The new cropped image that the transformation is applied to fits to |
- * the cropped rectangle in the original image. |
- * |
- * @param {number} imageWidth Width of the original image. |
- * @param {number} imageHeight Height of the original image. |
- * @param {!ImageRect} imageCropRect Crop rectangle in the image's coordinate |
- * system. |
+ * @param {number} width Width of image. |
+ * @param {number} height Height of image. |
+ * @param {number} rotation Number of clockwise 90 degree rotation. The rotation |
+ * angle of the image is rotation * 90. |
* @return {string} Transformation description. |
*/ |
-Viewport.prototype.getInverseTransformForCroppedImage = |
- function(imageWidth, imageHeight, imageCropRect) { |
- var wholeScale = this.getFittingScaleForImageSize_( |
- imageWidth, imageHeight); |
- var croppedScale = this.getFittingScaleForImageSize_( |
- imageCropRect.width, imageCropRect.height); |
- var dx = |
- (imageCropRect.left + imageCropRect.width / 2 - imageWidth / 2) * |
- wholeScale; |
- var dy = |
- (imageCropRect.top + imageCropRect.height / 2 - imageHeight / 2) * |
- wholeScale; |
- return [ |
- 'translate(' + dx + 'px,' + dy + 'px)', |
- 'scale(' + wholeScale / croppedScale + ')', |
- this.getTransformation() |
- ].join(' '); |
+Viewport.prototype.getRotatingTransformation = function( |
+ width, height, rotation) { |
+ return this.getTransformationInternal_( |
+ width, height, rotation, 1, 0, 0); |
}; |
/** |
- * Obtains CSS transformation that makes the image fit to the screen rectangle. |
- * |
- * @param {!ImageRect} screenRect Screen rectangle. |
- * @return {string} Transformation description. |
+ * Obtains CSS transformation that placed the image in the application window. |
+ * @param {number} width Width of image. |
+ * @param {number} height Height of image. |
+ * @param {number} rotation Number of clockwise 90 degree rotation. The rotation |
+ * angle of the image is rotation * 90. |
+ * @param {number} zoom Zoom rate. |
+ * @param {number} offsetX Horizontal offset. |
+ * @param {number} offsetY Vertical offset. |
+ * @private |
*/ |
-Viewport.prototype.getScreenRectTransformForImage = function(screenRect) { |
- var imageBounds = this.getImageElementBoundsOnScreen(); |
- var scaleX = screenRect.width / imageBounds.width; |
- var scaleY = screenRect.height / imageBounds.height; |
- var screenWidth = this.screenBounds_.width; |
- var screenHeight = this.screenBounds_.height; |
- var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2; |
- var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2; |
- return [ |
- 'translate(' + dx + 'px,' + dy + 'px)', |
- 'scale(' + scaleX + ',' + scaleY + ')', |
- this.getTransformation() |
- ].join(' '); |
+Viewport.prototype.getTransformationInternal_ = function( |
+ width, |
+ height, |
+ rotation, |
+ zoom, |
+ offsetX, |
+ offsetY) { |
+ var rotatedWidth = rotation % 2 ? height : width; |
+ var rotatedHeight = rotation % 2 ? width : height; |
+ var rotatedMaxWidth = rotation % 2 ? |
+ this.imageBounds_.height : this.imageBounds_.width; |
+ var rotatedMaxHeight = rotation % 2 ? |
+ this.imageBounds_.width : this.imageBounds_.height; |
+ |
+ // Scale. |
+ var fittingScale = this.getFittingScaleForImageSize_( |
+ rotatedWidth, rotatedHeight, rotatedMaxWidth, rotatedMaxHeight); |
+ |
+ // Offset for centering. |
+ var dx = (this.screenBounds_.width - width) / 2; |
+ var dy = (this.screenBounds_.height - height) / 2; |
+ |
+ var d = formatString( |
mtomasz
2015/05/14 02:27:55
nit: Per our style guide abbreviations are discour
hirono
2015/05/14 03:08:03
Yes, I removed console.log, and let it return the
|
+ 'translate($1px,$2px) scale($3) rotate($4deg)', |
+ dx + offsetX, |
+ dy + offsetY, |
+ fittingScale * zoom, |
+ rotation * 90); |
+ console.log(d); |
mtomasz
2015/05/14 02:27:55
nit: Remove console.log?
hirono
2015/05/14 03:08:03
Done.
|
+ return d; |
}; |