diff options
author | hirono@chromium.org <hirono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-18 08:13:27 +0000 |
---|---|---|
committer | hirono@chromium.org <hirono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-18 08:13:27 +0000 |
commit | b989df73881b20a2dc885b85d82e8b609e7549fb (patch) | |
tree | a7c4647718172f196a1d92597ac0c7054aadb938 /ui/file_manager | |
parent | d460a7bc14844dc4a353b1a22d4f7ccd57708f4f (diff) | |
download | chromium_src-b989df73881b20a2dc885b85d82e8b609e7549fb.zip chromium_src-b989df73881b20a2dc885b85d82e8b609e7549fb.tar.gz chromium_src-b989df73881b20a2dc885b85d82e8b609e7549fb.tar.bz2 |
Gallery: Add the offset feature in the slide mode.
* Add the keyboard handler to modify the viewport's offset values.
* Make the viewport class generate CSS transform expressions including the
offset value.
BUG=245926
TEST=manually
R=mtomasz@chromium.org
Review URL: https://codereview.chromium.org/398283002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284033 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/file_manager')
-rw-r--r-- | ui/file_manager/gallery/js/image_editor/image_view.js | 8 | ||||
-rw-r--r-- | ui/file_manager/gallery/js/image_editor/viewport.js | 120 | ||||
-rw-r--r-- | ui/file_manager/gallery/js/slide_mode.js | 64 |
3 files changed, 110 insertions, 82 deletions
diff --git a/ui/file_manager/gallery/js/image_editor/image_view.js b/ui/file_manager/gallery/js/image_editor/image_view.js index 312fe72..3f49c95 100644 --- a/ui/file_manager/gallery/js/image_editor/image_view.js +++ b/ui/file_manager/gallery/js/image_editor/image_view.js @@ -493,8 +493,6 @@ ImageView.prototype.replaceContent_ = function( this.viewport_.setImageSize( opt_width || this.contentCanvas_.width, opt_height || this.contentCanvas_.height); - this.viewport_.fitImage(); - this.viewport_.update(); this.draw(); this.container_.appendChild(this.screenImage_); @@ -846,7 +844,7 @@ ImageView.Effect.prototype.transform = function(element, viewport) { * @extends {ImageView.Effect} */ ImageView.Effect.None = function() { - ImageView.Effect.call(this, 0); + ImageView.Effect.call(this, 0, 'easy-out'); }; /** @@ -873,7 +871,7 @@ ImageView.Effect.None.prototype.transform = function(element, viewport) { */ ImageView.Effect.Slide = function Slide(direction, opt_slow) { ImageView.Effect.call(this, - opt_slow ? 800 : ImageView.Effect.DEFAULT_DURATION, 'ease-in-out'); + opt_slow ? 800 : ImageView.Effect.DEFAULT_DURATION, 'ease-out'); this.direction_ = direction; this.slow_ = opt_slow; this.shift_ = opt_slow ? 100 : 40; @@ -913,7 +911,7 @@ ImageView.Effect.Slide.prototype.transform = function(element, viewport) { ImageView.Effect.Zoom = function( previousImageWidth, previousImageHeight, imageCropRect, opt_duration) { ImageView.Effect.call(this, - opt_duration || ImageView.Effect.DEFAULT_DURATION); + opt_duration || ImageView.Effect.DEFAULT_DURATION, 'ease-out'); this.previousImageWidth_ = previousImageWidth; this.previousImageHeight_ = previousImageHeight; this.imageCropRect_ = imageCropRect; diff --git a/ui/file_manager/gallery/js/image_editor/viewport.js b/ui/file_manager/gallery/js/image_editor/viewport.js index 5f63d1b..56f7aa2 100644 --- a/ui/file_manager/gallery/js/image_editor/viewport.js +++ b/ui/file_manager/gallery/js/image_editor/viewport.js @@ -86,7 +86,7 @@ function Viewport() { */ this.generation_ = 0; - this.update(); + this.update_(); Object.seal(this); } @@ -112,8 +112,7 @@ Viewport.ZOOM_RATIOS = Object.freeze({ */ Viewport.prototype.setImageSize = function(width, height) { this.imageBounds_ = new Rect(width, height); - this.update(); - this.invalidateCaches(); + this.update_(); }; /** @@ -122,8 +121,7 @@ Viewport.prototype.setImageSize = function(width, height) { */ Viewport.prototype.setScreenSize = function(width, height) { this.screenBounds_ = new Rect(width, height); - this.update(); - this.invalidateCaches(); + this.update_(); }; /** @@ -136,7 +134,7 @@ Viewport.prototype.setZoomIndex = function(zoomIndex) { return; this.zoomIndex_ = zoomIndex; this.zoom_ = Viewport.ZOOM_RATIOS[zoomIndex]; - this.update(); + this.update_(); }; /** @@ -148,27 +146,11 @@ Viewport.prototype.getZoomIndex = function() { }; /** - * @return {number} Scale. + * Returns the value of zoom. + * @return {number} Zoom value. */ -Viewport.prototype.getScale = function() { return this.scale_; }; - -/** - * @param {number} scale The new scale. - */ -Viewport.prototype.setScale = function(scale) { - if (this.scale_ == scale) - return; - this.scale_ = scale; - this.update(); - this.invalidateCaches(); -}; - -/** - * @return {number} Best scale to fit the current image into the current screen. - */ -Viewport.prototype.getFittingScale = function() { - return this.getFittingScaleForImageSize_( - this.imageBounds_.width, this.imageBounds_.height); +Viewport.prototype.getZoom = function() { + return this.zoomIndex_; }; /** @@ -188,13 +170,6 @@ Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) { }; /** - * Set the scale to fit the image into the screen. - */ -Viewport.prototype.fitImage = function() { - this.setScale(this.getFittingScale()); -}; - -/** * @return {number} X-offset of the viewport. */ Viewport.prototype.getOffsetX = function() { return this.offsetX_; }; @@ -208,17 +183,13 @@ Viewport.prototype.getOffsetY = function() { return this.offsetY_; }; * Set the image offset in the viewport. * @param {number} x X-offset. * @param {number} y Y-offset. - * @param {boolean} ignoreClipping True if no clipping should be applied. */ -Viewport.prototype.setOffset = function(x, y, ignoreClipping) { - if (!ignoreClipping) { - x = this.clampOffsetX_(x); - y = this.clampOffsetY_(y); - } - if (this.offsetX_ == x && this.offsetY_ == y) return; +Viewport.prototype.setOffset = function(x, y) { + if (this.offsetX_ == x && this.offsetY_ == y) + return; this.offsetX_ = x; this.offsetY_ = y; - this.invalidateCaches(); + this.update_(); }; /** @@ -250,11 +221,6 @@ Viewport.prototype.getDeviceBounds = function() { Viewport.prototype.getCacheGeneration = function() { return this.generation_; }; /** - * Called on event view port state change. - */ -Viewport.prototype.invalidateCaches = function() { this.generation_++; }; - -/** * @return {Rect} The image bounds in screen coordinates. */ Viewport.prototype.getImageBoundsOnScreen = function() { @@ -283,7 +249,7 @@ Viewport.prototype.getImageBoundsOnScreenClipped = function() { * @return {number} Size in image coordinates. */ Viewport.prototype.screenToImageSize = function(size) { - return size / this.getScale(); + return size / this.scale_; }; /** @@ -291,7 +257,7 @@ Viewport.prototype.screenToImageSize = function(size) { * @return {number} X in image coordinates. */ Viewport.prototype.screenToImageX = function(x) { - return Math.round((x - this.imageBoundsOnScreen_.left) / this.getScale()); + return Math.round((x - this.imageBoundsOnScreen_.left) / this.scale_); }; /** @@ -299,7 +265,7 @@ Viewport.prototype.screenToImageX = function(x) { * @return {number} Y in image coordinates. */ Viewport.prototype.screenToImageY = function(y) { - return Math.round((y - this.imageBoundsOnScreen_.top) / this.getScale()); + return Math.round((y - this.imageBoundsOnScreen_.top) / this.scale_); }; /** @@ -319,7 +285,7 @@ Viewport.prototype.screenToImageRect = function(rect) { * @return {number} Size in screen coordinates. */ Viewport.prototype.imageToScreenSize = function(size) { - return size * this.getScale(); + return size * this.scale_; }; /** @@ -327,7 +293,7 @@ Viewport.prototype.imageToScreenSize = function(size) { * @return {number} X in screen coordinates. */ Viewport.prototype.imageToScreenX = function(x) { - return Math.round(this.imageBoundsOnScreen_.left + x * this.getScale()); + return Math.round(this.imageBoundsOnScreen_.left + x * this.scale_); }; /** @@ -335,7 +301,7 @@ Viewport.prototype.imageToScreenX = function(x) { * @return {number} Y in screen coordinates. */ Viewport.prototype.imageToScreenY = function(y) { - return Math.round(this.imageBoundsOnScreen_.top + y * this.getScale()); + return Math.round(this.imageBoundsOnScreen_.top + y * this.scale_); }; /** @@ -383,7 +349,7 @@ Viewport.prototype.getMarginY_ = function() { * @private */ Viewport.prototype.clampOffsetX_ = function(x) { - var limit = Math.round(Math.max(0, -this.getMarginX_() / this.getScale())); + var limit = Math.round(Math.max(0, -this.getMarginX_() / this.scale_)); return ImageUtil.clamp(-limit, x, limit); }; @@ -393,7 +359,7 @@ Viewport.prototype.clampOffsetX_ = function(x) { * @private */ Viewport.prototype.clampOffsetY_ = function(y) { - var limit = Math.round(Math.max(0, -this.getMarginY_() / this.getScale())); + var limit = Math.round(Math.max(0, -this.getMarginY_() / this.scale_)); return ImageUtil.clamp(-limit, y, limit); }; @@ -410,24 +376,49 @@ Viewport.prototype.getCenteredRect_ = function( }; /** + * Resets zoom and offset. + */ +Viewport.prototype.resetView = function() { + this.zoomIndex_ = 0; + this.zoom_ = 1; + this.offsetX_ = 0; + this.offsetY_ = 0; + this.update_(); +}; + +/** * Recalculate the viewport parameters. + * @private */ -Viewport.prototype.update = function() { - var scale = this.getScale(); +Viewport.prototype.update_ = function() { + // Update scale. + this.scale_ = this.getFittingScaleForImageSize_( + this.imageBounds_.width, this.imageBounds_.height); + + // Limit offset values. + var zoomedWidht = ~~(this.imageBounds_.width * this.scale_ * this.zoom_); + var zoomedHeight = ~~(this.imageBounds_.height * this.scale_ * this.zoom_); + var dx = Math.max(zoomedWidht - this.screenBounds_.width, 0) / 2; + var dy = Math.max(zoomedHeight - this.screenBounds_.height, 0) /2; + this.offsetX_ = ImageUtil.clamp(-dx, this.offsetX_, dx); + this.offsetY_ = ImageUtil.clamp(-dy, this.offsetY_, dy); // Image bounds on screen. this.imageBoundsOnScreen_ = this.getCenteredRect_( - ~~(this.imageBounds_.width * scale * this.zoom_), - ~~(this.imageBounds_.height * scale * this.zoom_), - this.offsetX_, - this.offsetY_); + zoomedWidht, zoomedHeight, this.offsetX_, this.offsetY_); // Image bounds of element (that is not applied zoom and offset) on screen. + var oldBounds = this.imageElementBoundsOnScreen_; this.imageElementBoundsOnScreen_ = this.getCenteredRect_( - ~~(this.imageBounds_.width * scale), - ~~(this.imageBounds_.height * scale), + ~~(this.imageBounds_.width * this.scale_), + ~~(this.imageBounds_.height * this.scale_), 0, 0); + if (!oldBounds || + this.imageElementBoundsOnScreen_.width != oldBounds.width || + this.imageElementBoundsOnScreen_.height != oldBounds.height) { + this.generation_++; + } // Image bounds on screen cliped with the screen bounds. var left = Math.max(this.imageBoundsOnScreen_.left, 0); @@ -445,7 +436,8 @@ Viewport.prototype.update = function() { * @return {string} Transformation description. */ Viewport.prototype.getTransformation = function() { - return 'scale(' + (1 / window.devicePixelRatio * this.zoom_) + ')'; + return 'translate(' + this.offsetX_ + 'px, ' + this.offsetY_ + 'px) ' + + 'scale(' + (1 / window.devicePixelRatio * this.zoom_) + ')'; }; /** @@ -472,7 +464,7 @@ Viewport.prototype.getInverseTransformForRotatedImage = function(orientation) { var previousImageHeight = this.imageBounds_.width; var oldScale = this.getFittingScaleForImageSize_( previousImageWidth, previousImageHeight); - var scaleRatio = oldScale / this.getScale(); + var scaleRatio = oldScale / this.scale_; var degree = orientation ? '-90deg' : '90deg'; return [ 'scale(' + scaleRatio + ')', diff --git a/ui/file_manager/gallery/js/slide_mode.js b/ui/file_manager/gallery/js/slide_mode.js index 836cfda..b2794e7 100644 --- a/ui/file_manager/gallery/js/slide_mode.js +++ b/ui/file_manager/gallery/js/slide_mode.js @@ -49,15 +49,11 @@ function SlideMode(container, content, toolbar, prompt, } /** - * SlideMode extends cr.EventTarget. - */ -SlideMode.prototype.__proto__ = cr.EventTarget.prototype; - -/** * List of available editor modes. * @type {Array.<ImageEditor.Mode>} + * @const */ -SlideMode.editorModes = [ +SlideMode.EDITOR_MODES = Object.freeze([ new ImageEditor.Mode.InstantAutofix(), new ImageEditor.Mode.Crop(), new ImageEditor.Mode.Exposure(), @@ -65,7 +61,24 @@ SlideMode.editorModes = [ 'rotate_left', 'GALLERY_ROTATE_LEFT', new Command.Rotate(-1)), new ImageEditor.Mode.OneClick( 'rotate_right', 'GALLERY_ROTATE_RIGHT', new Command.Rotate(1)) -]; +]); + +/** + * Map of the key identifier and offset delta. + * @type {Object.<string, Array.<number>}) + * @const + */ +SlideMode.KEY_OFFSET_MAP = Object.freeze({ + 'Up': Object.freeze([0, 20]), + 'Down': Object.freeze([0, -20]), + 'Left': Object.freeze([20, 0]), + 'Right': Object.freeze([-20, 0]) +}); + +/** + * SlideMode extends cr.EventTarget. + */ +SlideMode.prototype.__proto__ = cr.EventTarget.prototype; /** * @return {string} Mode name. @@ -216,7 +229,7 @@ SlideMode.prototype.initDom_ = function() { toolbar: this.editBarMain_, mode: this.editBarModeWrapper_ }, - SlideMode.editorModes, + SlideMode.EDITOR_MODES, this.displayStringFunction_, this.onToolsVisibilityChanged_.bind(this)); @@ -334,7 +347,7 @@ SlideMode.prototype.leave = function(zoomToRect, callback) { callback(); }.bind(this); - this.viewport_.setZoomIndex(0); + this.viewport_.resetView(); if (this.getItemCount_() === 0) { this.showErrorBanner_(false); commitDone(); @@ -846,9 +859,14 @@ SlideMode.prototype.onKeyDown = function(event) { break; case 'U+001B': // Escape - if (!this.isEditing()) + if (this.isEditing()) { + this.toggleEditor(event); + } else if (this.viewport_.getZoomIndex() !== 0) { + this.viewport_.resetView(); + this.imageView_.applyViewportChange(); + } else { return false; // Not handled. - this.toggleEditor(event); + } break; case 'Home': @@ -861,6 +879,19 @@ SlideMode.prototype.onKeyDown = function(event) { case 'Down': case 'Left': case 'Right': + if (!this.isEditing() && this.viewport_.getZoomIndex() !== 0) { + var delta = SlideMode.KEY_OFFSET_MAP[keyID]; + this.viewport_.setOffset( + ~~(this.viewport_.getOffsetX() + + delta[0] * this.viewport_.getZoom()), + ~~(this.viewport_.getOffsetY() + + delta[1] * this.viewport_.getZoom()), + true); + this.imageView_.applyViewportChange(); + } else { + this.advanceWithKeyboard(keyID); + } + break; case 'MediaNextTrack': case 'MediaPreviousTrack': this.advanceWithKeyboard(keyID); @@ -879,6 +910,13 @@ SlideMode.prototype.onKeyDown = function(event) { this.imageView_.applyViewportChange(); } break; + + case 'Ctrl-U+0030': // Ctrl+'0' zoom reset. + if (!this.isEditing()) { + this.viewport_.resetView(); + this.imageView_.applyViewportChange(); + } + break; } return true; @@ -1046,7 +1084,7 @@ SlideMode.prototype.isSlideshowOn_ = function() { */ SlideMode.prototype.startSlideshow = function(opt_interval, opt_event) { // Reset zoom. - this.viewport_.setZoomIndex(0); + this.viewport_.resetView(); this.imageView_.applyViewportChange(); // Set the attribute early to prevent the toolbar from flashing when @@ -1201,7 +1239,7 @@ SlideMode.prototype.toggleEditor = function(opt_event) { if (this.isEditing()) { // isEditing has just been flipped to a new value. // Reset zoom. - this.viewport_.setZoomIndex(0); + this.viewport_.resetView(); this.imageView_.applyViewportChange(); if (this.context_.readonlyDirName) { this.editor_.getPrompt().showAt( |