15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)'use strict';
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Crop mode.
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @extends {ImageEditor.Mode}
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @constructor
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop = function() {
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ImageEditor.Mode.call(this, 'crop', 'GALLERY_CROP');
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype = {__proto__: ImageEditor.Mode.prototype};
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Sets the mode up.
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @override
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.setUp = function() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageEditor.Mode.prototype.setUp.apply(this, arguments);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var container = this.getImageView().container_;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var doc = container.ownerDocument;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_ = doc.createElement('div');
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.className = 'crop-overlay';
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  container.appendChild(this.domOverlay_);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowTop_ = doc.createElement('div');
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowTop_.className = 'shadow';
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.appendChild(this.shadowTop_);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.middleBox_ = doc.createElement('div');
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.middleBox_.className = 'middle-box';
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.appendChild(this.middleBox_);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowLeft_ = doc.createElement('div');
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowLeft_.className = 'shadow';
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.middleBox_.appendChild(this.shadowLeft_);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.cropFrame_ = doc.createElement('div');
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.cropFrame_.className = 'crop-frame';
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.middleBox_.appendChild(this.cropFrame_);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowRight_ = doc.createElement('div');
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowRight_.className = 'shadow';
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.middleBox_.appendChild(this.shadowRight_);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowBottom_ = doc.createElement('div');
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowBottom_.className = 'shadow';
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.appendChild(this.shadowBottom_);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  this.toolBar_ = null;
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var cropFrame = this.cropFrame_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  function addCropFrame(className) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var div = doc.createElement('div');
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    div.className = className;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cropFrame.appendChild(div);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('left top corner');
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('top horizontal');
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('right top corner');
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('left vertical');
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('right vertical');
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('left bottom corner');
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('bottom horizontal');
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addCropFrame('right bottom corner');
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.onResizedBound_ = this.onResized_.bind(this);
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  window.addEventListener('resize', this.onResizedBound_);
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.createDefaultCrop();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @override
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */
84116680a4aac90f2aa7413d9095a592090648e557Ben MurdochImageEditor.Mode.Crop.prototype.createTools = function(toolbar) {
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var aspects = {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GALLERY_ASPECT_RATIO_1_1: 1 / 1,
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GALLERY_ASPECT_RATIO_6_4: 6 / 4,
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GALLERY_ASPECT_RATIO_7_5: 7 / 5,
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GALLERY_ASPECT_RATIO_16_9: 16 / 9
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (name in aspects) {
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    toolbar.addButton(
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        name,
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        name,
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        function(aspect, event) {
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          var button = event.target;
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          if (button.classList.contains('selected')) {
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            button.classList.remove('selected');
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            this.cropRect_.fixedAspectRatio = null;
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          } else {
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            var selectedButtons =
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                toolbar.element.querySelectorAll('button.selected');
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            for (var i = 0; i < selectedButtons.length; i++) {
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              selectedButtons[i].classList.remove('selected');
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            }
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            button.classList.add('selected');
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            var clipRect = this.viewport_.screenToImageRect(
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                this.viewport_.getImageBoundsOnScreenClipped());
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            this.cropRect_.fixedAspectRatio = aspect;
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            this.cropRect_.forceAspectRatio(aspect, clipRect);
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            this.markUpdated();
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            this.positionDOM();
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            this.toolbar_.element.classList.remove('dimmable');
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            this.toolbar_.element.removeAttribute('dimmed');
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          }
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        }.bind(this, aspects[name]));
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  this.toolbar_ = toolbar;
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/**
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Handles resizing of the window and updates the crop rectangle.
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * @private
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ImageEditor.Mode.Crop.prototype.onResized_ = function() {
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.positionDOM();
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)/**
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Resets the mode.
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.reset = function() {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageEditor.Mode.prototype.reset.call(this);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.createDefaultCrop();
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (this.toolbar_) {
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    this.toolbar_.element.classList.add('dimmable');
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    this.toolbar_ = null;
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Updates the position of DOM elements.
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.positionDOM = function() {
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var screenClipped = this.viewport_.getImageBoundsOnScreenClipped();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var screenCrop = this.viewport_.imageToScreenRect(this.cropRect_.getRect());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var delta = ImageEditor.Mode.Crop.MOUSE_GRAB_RADIUS;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.editor_.hideOverlappingTools(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      screenCrop.inflate(delta, delta),
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      screenCrop.inflate(-delta, -delta));
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.style.left = screenClipped.left + 'px';
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.style.top = screenClipped.top + 'px';
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.style.width = screenClipped.width + 'px';
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.style.height = screenClipped.height + 'px';
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowLeft_.style.width = screenCrop.left - screenClipped.left + 'px';
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowTop_.style.height = screenCrop.top - screenClipped.top + 'px';
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowRight_.style.width = screenClipped.left + screenClipped.width -
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (screenCrop.left + screenCrop.width) + 'px';
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.shadowBottom_.style.height = screenClipped.top + screenClipped.height -
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (screenCrop.top + screenCrop.height) + 'px';
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Removes the overlay elements from the document.
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.cleanUpUI = function() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_.parentNode.removeChild(this.domOverlay_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.domOverlay_ = null;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.editor_.hideOverlappingTools();
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  window.removeEventListener('resize', this.onResizedBound_);
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  this.onResizedBound_ = null;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.MOUSE_GRAB_RADIUS = 6;
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {number}
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.TOUCH_GRAB_RADIUS = 20;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Gets command to do the crop depending on the current state.
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {Command.Crop} Crop command.
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.getCommand = function() {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var cropImageRect = this.cropRect_.getRect();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new Command.Crop(cropImageRect);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Creates default (initial) crop.
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.createDefaultCrop = function() {
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var rect = this.getViewport().screenToImageRect(
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new Rect(this.getViewport().getImageBoundsOnScreenClipped()));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rect = rect.inflate(
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -Math.round(rect.width / 6), -Math.round(rect.height / 6));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.cropRect_ = new DraggableRect(rect, this.getViewport());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.positionDOM();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the cursor style depending on the mouse state.
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} x X coordinate for cursor.
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} y Y coordinate for cursor.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} mouseDown If mouse button is down.
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} A value for style.cursor CSS property.
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.getCursorStyle = function(x, y, mouseDown) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this.cropRect_.getCursorStyle(x, y, mouseDown);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains handler function depending on the mouse state.
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} x Event X coordinate.
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} y Event Y coordinate.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} touch True if it's a touch event, false if mouse.
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {function(number,number,boolean)} A function to be called on mouse
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *     drag. It takes x coordinate value, y coordinate value, and shift key
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *     flag.
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.getDragHandler = function(x, y, touch) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var cropDragHandler = this.cropRect_.getDragHandler(x, y, touch);
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!cropDragHandler)
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return null;
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return function(x, y, shiftKey) {
2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (this.toolbar_)
2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      this.toolbar_.element.classList.add('dimmable');
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    cropDragHandler(x, y, shiftKey);
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    this.markUpdated();
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    this.positionDOM();
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }.bind(this);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the double tap action depending on the coordinate.
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} x X coordinate of the event.
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} y Y coordinate of the event.
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {ImageBuffer.DoubleTapAction} Action to perform as result.
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageEditor.Mode.Crop.prototype.getDoubleTapAction = function(x, y) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this.cropRect_.getDoubleTapAction(x, y);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/**
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A draggable rectangle over the image.
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param {Rect} rect Initial size of the image.
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param {Viewport} viewport Viewport.
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @constructor
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function DraggableRect(rect, viewport) {
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /**
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * The bounds are not held in a regular rectangle (with width/height).
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * left/top/right/bottom held instead for convenience.
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   *
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * @type {{left: number, right: number, top: number, bottom: number}}
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * @private
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   */
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.bounds_ = {};
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.bounds_[DraggableRect.LEFT] = rect.left;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.bounds_[DraggableRect.RIGHT] = rect.left + rect.width;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.bounds_[DraggableRect.TOP] = rect.top;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.bounds_[DraggableRect.BOTTOM] = rect.top + rect.height;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /**
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * Viewport.
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   *
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   * @type {Viewport}
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * @private
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   */
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this.viewport_ = viewport;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /**
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * Drag mode.
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   *
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * @type {Object}
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * @private
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   */
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.dragMode_ = null;
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  /**
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * Fixed aspect ratio.
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * The aspect ratio is not fixed when null.
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   * @type {?number}
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   */
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.fixedAspectRatio = null;
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Object.seal(this);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Static members to simplify reflective access to the bounds.
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {string}
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.LEFT = 'left';
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {string}
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.RIGHT = 'right';
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {string}
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.TOP = 'top';
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {string}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.BOTTOM = 'bottom';
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @const
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {string}
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.NONE = 'none';
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the left position.
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {number} Position.
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getLeft = function() {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this.bounds_[DraggableRect.LEFT];
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the right position.
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {number} Position.
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getRight = function() {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this.bounds_[DraggableRect.RIGHT];
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the top position.
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {number} Position.
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getTop = function() {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this.bounds_[DraggableRect.TOP];
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the bottom position.
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {number} Position.
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getBottom = function() {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this.bounds_[DraggableRect.BOTTOM];
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
3736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Obtains the geometry of the rectangle.
3746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @return {Rect} Geometry of the rectangle.
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DraggableRect.prototype.getRect = function() {
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new Rect(this.bounds_);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the drag mode depending on the coordinate.
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} x X coordinate for cursor.
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} y Y coordinate for cursor.
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param {boolean} touch  Whether the operation is done by touch or not.
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {Object} Drag mode.
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getDragMode = function(x, y, touch) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var result = {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xSide: DraggableRect.NONE,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ySide: DraggableRect.NONE
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var bounds = this.bounds_;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var R = this.viewport_.screenToImageSize(
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      touch ? ImageEditor.Mode.Crop.TOUCH_GRAB_RADIUS :
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              ImageEditor.Mode.Crop.MOUSE_GRAB_RADIUS);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var circle = new Circle(x, y, R);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var xBetween = ImageUtil.between(bounds.left, x, bounds.right);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var yBetween = ImageUtil.between(bounds.top, y, bounds.bottom);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (circle.inside(bounds.left, bounds.top)) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.LEFT;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.TOP;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (circle.inside(bounds.left, bounds.bottom)) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.LEFT;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.BOTTOM;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (circle.inside(bounds.right, bounds.top)) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.RIGHT;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.TOP;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (circle.inside(bounds.right, bounds.bottom)) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.RIGHT;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.BOTTOM;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (yBetween && Math.abs(x - bounds.left) <= R) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.LEFT;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (yBetween && Math.abs(x - bounds.right) <= R) {
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.RIGHT;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (xBetween && Math.abs(y - bounds.top) <= R) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.TOP;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (xBetween && Math.abs(y - bounds.bottom) <= R) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.BOTTOM;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (xBetween && yBetween) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.whole = true;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.newcrop = true;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.xSide = DraggableRect.RIGHT;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.ySide = DraggableRect.BOTTOM;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains the cursor style depending on the coordinate.
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} x X coordinate for cursor.
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} y Y coordinate for cursor.
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {boolean} mouseDown  If mouse button is down.
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {string} Cursor style.
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getCursorStyle = function(x, y, mouseDown) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var mode;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouseDown) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mode = this.dragMode_;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mode = this.getDragMode(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this.viewport_.screenToImageX(x), this.viewport_.screenToImageY(y));
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (mode.whole)
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return 'move';
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (mode.newcrop)
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return 'crop';
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var xSymbol = '';
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (mode.xSide) {
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'left': xSymbol = 'w'; break;
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'right': xSymbol = 'e'; break;
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var ySymbol = '';
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (mode.ySide) {
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'top': ySymbol = 'n'; break;
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'bottom': ySymbol = 's'; break;
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ySymbol + xSymbol + '-resize';
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
4706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Obtains the drag handler depending on the coordinate.
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {number} initialScreenX X coordinate for cursor in the screen.
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {number} initialScreenY Y coordinate for cursor in the screen.
4746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * @param {boolean} touch Whether the operation is done by touch or not.
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {function(number,number,boolean)} Drag handler that takes x
476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *     coordinate value, y coordinate value, and shift key flag.
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
478116680a4aac90f2aa7413d9095a592090648e557Ben MurdochDraggableRect.prototype.getDragHandler = function(
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    initialScreenX, initialScreenY, touch) {
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Check if the initial coordinate in the clip rect.
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var initialX = this.viewport_.screenToImageX(initialScreenX);
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var initialY = this.viewport_.screenToImageY(initialScreenY);
483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var initialWidth = this.bounds_.right - this.bounds_.left;
484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var initialHeight = this.bounds_.bottom - this.bounds_.top;
485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var clipRect = this.viewport_.screenToImageRect(
486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.viewport_.getImageBoundsOnScreenClipped());
487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!clipRect.inside(initialX, initialY))
488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return null;
489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Obtain the drag mode.
491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  this.dragMode_ = this.getDragMode(initialX, initialY, touch);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (this.dragMode_.whole) {
494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Calc constant values during the operation.
495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var mouseBiasX = this.bounds_.left - initialX;
496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var mouseBiasY = this.bounds_.top - initialY;
497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var maxX = clipRect.left + clipRect.width - initialWidth;
498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var maxY = clipRect.top + clipRect.height - initialHeight;
499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Returns a handler.
501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return function(newScreenX, newScreenY) {
502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      var newX = this.viewport_.screenToImageX(newScreenX);
503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      var newY = this.viewport_.screenToImageY(newScreenY);
504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      var clamppedX = ImageUtil.clamp(clipRect.left, newX + mouseBiasX, maxX);
505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      var clamppedY = ImageUtil.clamp(clipRect.top, newY + mouseBiasY, maxY);
506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.left = clamppedX;
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.right = clamppedX + initialWidth;
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.top = clamppedY;
509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.bottom = clamppedY + initialHeight;
510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }.bind(this);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Calc constant values during the operation.
513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var mouseBiasX = this.bounds_[this.dragMode_.xSide] - initialX;
514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var mouseBiasY = this.bounds_[this.dragMode_.ySide] - initialY;
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var maxX = clipRect.left + clipRect.width;
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    var maxY = clipRect.top + clipRect.height;
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Returns a handler.
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return function(newScreenX, newScreenY, shiftKey) {
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      var newX = this.viewport_.screenToImageX(newScreenX);
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      var newY = this.viewport_.screenToImageY(newScreenY);
522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Check new crop.
524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (this.dragMode_.newcrop) {
525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        this.dragMode_.newcrop = false;
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.bounds_.left = this.bounds_.right = initialX;
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        this.bounds_.top = this.bounds_.bottom = initialY;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouseBiasX = 0;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouseBiasY = 0;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Update X coordinate.
533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (this.dragMode_.xSide !== DraggableRect.NONE) {
534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        this.bounds_[this.dragMode_.xSide] =
535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            ImageUtil.clamp(clipRect.left, newX + mouseBiasX, maxX);
536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (this.bounds_.left > this.bounds_.right) {
537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          var left = this.bounds_.left;
538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          var right = this.bounds_.right;
539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this.bounds_.left = right - 1;
540116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this.bounds_.right = left + 1;
541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this.dragMode_.xSide =
542116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              this.dragMode_.xSide == 'left' ? 'right' : 'left';
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
544116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Update Y coordinate.
547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (this.dragMode_.ySide !== DraggableRect.NONE) {
548116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        this.bounds_[this.dragMode_.ySide] =
549116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            ImageUtil.clamp(clipRect.top, newY + mouseBiasY, maxY);
550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (this.bounds_.top > this.bounds_.bottom) {
551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          var top = this.bounds_.top;
552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          var bottom = this.bounds_.bottom;
553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this.bounds_.top = bottom - 1;
554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this.bounds_.bottom = top + 1;
555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          this.dragMode_.ySide =
556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              this.dragMode_.ySide === 'top' ? 'bottom' : 'top';
557116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        }
558116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Update aspect ratio.
561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (this.fixedAspectRatio)
562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        this.forceAspectRatio(this.fixedAspectRatio, clipRect);
563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      else if (shiftKey)
564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        this.forceAspectRatio(initialWidth / initialHeight, clipRect);
565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }.bind(this);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Obtains double tap action depending on the coordinate.
571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} x X coordinate for cursor.
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {number} y Y coordinate for cursor.
574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param {boolean} touch Whether the operation is done by touch or not.
575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @return {ImageBuffer.DoubleTapAction} Double tap action.
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DraggableRect.prototype.getDoubleTapAction = function(x, y, touch) {
578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var clipRect = this.viewport_.getImageBoundsOnScreenClipped();
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (clipRect.inside(x, y))
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ImageBuffer.DoubleTapAction.COMMIT;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ImageBuffer.DoubleTapAction.NOTHING;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
584116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
585116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/**
586116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * Forces the aspect ratio.
587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *
588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param {number} aspectRatio Aspect ratio.
589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch * @param {Object} clipRect Clip rect.
590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch */
591116680a4aac90f2aa7413d9095a592090648e557Ben MurdochDraggableRect.prototype.forceAspectRatio = function(aspectRatio, clipRect) {
592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Get current rectangle scale.
593116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var width = this.bounds_.right - this.bounds_.left;
594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var height = this.bounds_.bottom - this.bounds_.top;
595116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var currentScale;
5966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!this.dragMode_)
5976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    currentScale = ((width / aspectRatio) + height) / 2;
5986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else if (this.dragMode_.xSide === 'none')
599116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    currentScale = height;
600116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else if (this.dragMode_.ySide === 'none')
601116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    currentScale = width / aspectRatio;
602116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else
603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    currentScale = Math.max(width / aspectRatio, height);
604116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
605116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Get maximum width/height scale.
606116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var maxWidth;
607116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var maxHeight;
608116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var center = (this.bounds_.left + this.bounds_.right) / 2;
609116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var middle = (this.bounds_.top + this.bounds_.bottom) / 2;
6106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  var xSide = this.dragMode_ ? this.dragMode_.xSide : 'none';
6116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  var ySide = this.dragMode_ ? this.dragMode_.ySide : 'none';
6126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (xSide) {
613116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'left':
614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxWidth = this.bounds_.right - clipRect.left;
615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'right':
617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxWidth = clipRect.left + clipRect.width - this.bounds_.left;
618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'none':
620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxWidth = Math.min(
621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          clipRect.left + clipRect.width - center,
622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          center - clipRect.left) * 2;
623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
624116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
6256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (ySide) {
626116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'top':
627116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxHeight = this.bounds_.bottom - clipRect.top;
628116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'bottom':
630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxHeight = clipRect.top + clipRect.height - this.bounds_.top;
631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'none':
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxHeight = Math.min(
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          clipRect.top + clipRect.height - middle,
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          middle - clipRect.top) * 2;
636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Obtains target scale.
640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var targetScale = Math.min(
641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      currentScale,
642116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxWidth / aspectRatio,
643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      maxHeight);
644116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Update bounds.
646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var newWidth = targetScale * aspectRatio;
647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  var newHeight = targetScale;
6486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (xSide) {
649116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'left':
650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.left = this.bounds_.right - newWidth;
651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
652116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'right':
653116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.right = this.bounds_.left + newWidth;
654116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
655116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'none':
656116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.left = center - newWidth / 2;
657116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.right = center + newWidth / 2;
658116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
6606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (ySide) {
661116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'top':
662116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.top = this.bounds_.bottom - newHeight;
663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'bottom':
665116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.bottom = this.bounds_.top + newHeight;
666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
667116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case 'none':
668116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.top = middle - newHeight / 2;
669116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      this.bounds_.bottom = middle + newHeight / 2;
670116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
671116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
673