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

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

Issue 416023002: Gallery.app: Add touch operation to rotate images. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed. 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 */
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 */ 65 */
66 this.offsetX_ = 0; 66 this.offsetX_ = 0;
67 67
68 /** 68 /**
69 * Offset specified by user operations. 69 * Offset specified by user operations.
70 * @type {number} 70 * @type {number}
71 */ 71 */
72 this.offsetY_ = 0; 72 this.offsetY_ = 0;
73 73
74 /** 74 /**
75 * Integer Rotation value.
76 * The rotation angle is this.rotation_ * 90.
77 * @type {number}
78 */
79 this.rotation_ = 0;
80
81 /**
75 * Generation of the screen size image cache. 82 * Generation of the screen size image cache.
76 * This is incremented every time when the size of image cache is changed. 83 * This is incremented every time when the size of image cache is changed.
77 * @type {number} 84 * @type {number}
78 * @private 85 * @private
79 */ 86 */
80 this.generation_ = 0; 87 this.generation_ = 0;
81 88
82 this.update_(); 89 this.update_();
83 Object.seal(this); 90 Object.seal(this);
84 } 91 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 164
158 /** 165 /**
159 * Obtains whether the picture is zoomed or not. 166 * Obtains whether the picture is zoomed or not.
160 * @return {boolean} 167 * @return {boolean}
161 */ 168 */
162 Viewport.prototype.isZoomed = function() { 169 Viewport.prototype.isZoomed = function() {
163 return this.zoom_ !== 1; 170 return this.zoom_ !== 1;
164 }; 171 };
165 172
166 /** 173 /**
174 * Sets the rotation value.
175 * @param {number} rotation New rotation value.
176 */
177 Viewport.prototype.setRotation = function(rotation) {
178 this.rotation_ = rotation;
179 this.update_();
180 };
181
182
183 /**
184 * Obtains the rotation value.
185 * @return {number} Current rotation value.
186 */
187 Viewport.prototype.getRotation = function() {
188 return this.rotation_;
189 };
190
191 /**
167 * Obtains the scale for the specified image size. 192 * Obtains the scale for the specified image size.
168 * 193 *
169 * @param {number} width Width of the full resolution image. 194 * @param {number} width Width of the full resolution image.
170 * @param {number} height Height of the full resolution image. 195 * @param {number} height Height of the full resolution image.
171 * @return {number} The ratio of the fullresotion image size and the calculated 196 * @return {number} The ratio of the fullresotion image size and the calculated
172 * displayed image size. 197 * displayed image size.
173 */ 198 */
174 Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) { 199 Viewport.prototype.getFittingScaleForImageSize_ = function(width, height) {
175 var scaleX = this.screenBounds_.width / width; 200 var scaleX = this.screenBounds_.width / width;
176 var scaleY = this.screenBounds_.height / height; 201 var scaleY = this.screenBounds_.height / height;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 */ 345 */
321 Viewport.prototype.imageToScreenRect = function(rect) { 346 Viewport.prototype.imageToScreenRect = function(rect) {
322 return new Rect( 347 return new Rect(
323 this.imageToScreenX(rect.left), 348 this.imageToScreenX(rect.left),
324 this.imageToScreenY(rect.top), 349 this.imageToScreenY(rect.top),
325 Math.round(this.imageToScreenSize(rect.width)), 350 Math.round(this.imageToScreenSize(rect.width)),
326 Math.round(this.imageToScreenSize(rect.height))); 351 Math.round(this.imageToScreenSize(rect.height)));
327 }; 352 };
328 353
329 /** 354 /**
330 * @return {boolean} True if some part of the image is clipped by the screen.
331 */
332 Viewport.prototype.isClipped = function() {
333 return this.getMarginX_() < 0 || this.getMarginY_() < 0;
334 };
335
336 /**
337 * @return {number} Horizontal margin.
338 * Negative if the image is clipped horizontally.
339 * @private
340 */
341 Viewport.prototype.getMarginX_ = function() {
342 return Math.round(
343 (this.screenBounds_.width - this.imageBounds_.width * this.scale_) / 2);
344 };
345
346 /**
347 * @return {number} Vertical margin.
348 * Negative if the image is clipped vertically.
349 * @private
350 */
351 Viewport.prototype.getMarginY_ = function() {
352 return Math.round(
353 (this.screenBounds_.height - this.imageBounds_.height * this.scale_) / 2);
354 };
355
356 /**
357 * @param {number} x X-offset.
358 * @return {number} X-offset clamped to the valid range.
359 * @private
360 */
361 Viewport.prototype.clampOffsetX_ = function(x) {
362 var limit = Math.round(Math.max(0, -this.getMarginX_() / this.scale_));
363 return ImageUtil.clamp(-limit, x, limit);
364 };
365
366 /**
367 * @param {number} y Y-offset.
368 * @return {number} Y-offset clamped to the valid range.
369 * @private
370 */
371 Viewport.prototype.clampOffsetY_ = function(y) {
372 var limit = Math.round(Math.max(0, -this.getMarginY_() / this.scale_));
373 return ImageUtil.clamp(-limit, y, limit);
374 };
375
376 /**
377 * @private 355 * @private
378 */ 356 */
379 Viewport.prototype.getCenteredRect_ = function( 357 Viewport.prototype.getCenteredRect_ = function(
380 width, height, offsetX, offsetY) { 358 width, height, offsetX, offsetY) {
381 return new Rect( 359 return new Rect(
382 ~~((this.screenBounds_.width - width) / 2) + offsetX, 360 ~~((this.screenBounds_.width - width) / 2) + offsetX,
383 ~~((this.screenBounds_.height - height) / 2) + offsetY, 361 ~~((this.screenBounds_.height - height) / 2) + offsetY,
384 width, 362 width,
385 height); 363 height);
386 }; 364 };
387 365
388 /** 366 /**
389 * Resets zoom and offset. 367 * Resets zoom and offset.
390 */ 368 */
391 Viewport.prototype.resetView = function() { 369 Viewport.prototype.resetView = function() {
392 this.zoom_ = 1; 370 this.zoom_ = 1;
393 this.offsetX_ = 0; 371 this.offsetX_ = 0;
394 this.offsetY_ = 0; 372 this.offsetY_ = 0;
373 this.rotation_ = 0;
395 this.update_(); 374 this.update_();
396 }; 375 };
397 376
398 /** 377 /**
399 * Recalculate the viewport parameters. 378 * Recalculate the viewport parameters.
400 * @private 379 * @private
401 */ 380 */
402 Viewport.prototype.update_ = function() { 381 Viewport.prototype.update_ = function() {
403 // Update scale. 382 // Update scale.
404 this.scale_ = this.getFittingScaleForImageSize_( 383 this.scale_ = this.getFittingScaleForImageSize_(
405 this.imageBounds_.width, this.imageBounds_.height); 384 this.imageBounds_.width, this.imageBounds_.height);
406 385
407 // Limit offset values. 386 // Limit offset values.
408 var zoomedWidht = ~~(this.imageBounds_.width * this.scale_ * this.zoom_); 387 var zoomedWidht;
409 var zoomedHeight = ~~(this.imageBounds_.height * this.scale_ * this.zoom_); 388 var zoomedHeight;
389 if (this.rotation_ % 2 == 0) {
390 zoomedWidht = ~~(this.imageBounds_.width * this.scale_ * this.zoom_);
391 zoomedHeight = ~~(this.imageBounds_.height * this.scale_ * this.zoom_);
392 } else {
393 var scale = this.getFittingScaleForImageSize_(
394 this.imageBounds_.height, this.imageBounds_.width);
395 zoomedWidht = ~~(this.imageBounds_.height * scale * this.zoom_);
396 zoomedHeight = ~~(this.imageBounds_.width * scale * this.zoom_);
397 }
410 var dx = Math.max(zoomedWidht - this.screenBounds_.width, 0) / 2; 398 var dx = Math.max(zoomedWidht - this.screenBounds_.width, 0) / 2;
411 var dy = Math.max(zoomedHeight - this.screenBounds_.height, 0) /2; 399 var dy = Math.max(zoomedHeight - this.screenBounds_.height, 0) /2;
412 this.offsetX_ = ImageUtil.clamp(-dx, this.offsetX_, dx); 400 this.offsetX_ = ImageUtil.clamp(-dx, this.offsetX_, dx);
413 this.offsetY_ = ImageUtil.clamp(-dy, this.offsetY_, dy); 401 this.offsetY_ = ImageUtil.clamp(-dy, this.offsetY_, dy);
414 402
415 // Image bounds on screen. 403 // Image bounds on screen.
416 this.imageBoundsOnScreen_ = this.getCenteredRect_( 404 this.imageBoundsOnScreen_ = this.getCenteredRect_(
417 zoomedWidht, zoomedHeight, this.offsetX_, this.offsetY_); 405 zoomedWidht, zoomedHeight, this.offsetX_, this.offsetY_);
418 406
419 // Image bounds of element (that is not applied zoom and offset) on screen. 407 // Image bounds of element (that is not applied zoom and offset) on screen.
(...skipping 14 matching lines...) Expand all
434 var top = Math.max(this.imageBoundsOnScreen_.top, 0); 422 var top = Math.max(this.imageBoundsOnScreen_.top, 0);
435 var right = Math.min( 423 var right = Math.min(
436 this.imageBoundsOnScreen_.right, this.screenBounds_.width); 424 this.imageBoundsOnScreen_.right, this.screenBounds_.width);
437 var bottom = Math.min( 425 var bottom = Math.min(
438 this.imageBoundsOnScreen_.bottom, this.screenBounds_.height); 426 this.imageBoundsOnScreen_.bottom, this.screenBounds_.height);
439 this.imageBoundsOnScreenClipped_ = new Rect( 427 this.imageBoundsOnScreenClipped_ = new Rect(
440 left, top, right - left, bottom - top); 428 left, top, right - left, bottom - top);
441 }; 429 };
442 430
443 /** 431 /**
432 * Clones the viewport.
433 * @return {Viewport} New instance.
434 */
435 Viewport.prototype.clone = function() {
436 var viewport = new Viewport();
437 viewport.imageBounds_ = new Rect(this.imageBounds_);
438 viewport.screenBounds_ = new Rect(this.screenBounds_);
439 viewport.scale_ = this.scale_;
440 viewport.zoom_ = this.zoom_;
441 viewport.offsetX_ = this.offsetX_;
442 viewport.offsetY_ = this.offsetY_;
443 viewport.rotation_ = this.rotation_;
444 viewport.generation_ = this.generation_;
445 viewport.update_();
446 return viewport;
447 };
448
449 /**
444 * Obtains CSS transformation for the screen image. 450 * Obtains CSS transformation for the screen image.
445 * @return {string} Transformation description. 451 * @return {string} Transformation description.
446 */ 452 */
447 Viewport.prototype.getTransformation = function() { 453 Viewport.prototype.getTransformation = function() {
448 return 'translate(' + this.offsetX_ + 'px, ' + this.offsetY_ + 'px) ' + 454 var rotationScaleAdjustment;
449 'scale(' + this.zoom_ + ')'; 455 if (this.rotation_ % 2) {
456 rotationScaleAdjustment = this.getFittingScaleForImageSize_(
457 this.imageBounds_.height, this.imageBounds_.width) / this.scale_;
458 } else {
459 rotationScaleAdjustment = 1;
460 }
461 return [
462 'translate(' + this.offsetX_ + 'px, ' + this.offsetY_ + 'px) ',
463 'rotate(' + (this.rotation_ * 90) + 'deg)',
464 'scale(' + (this.zoom_ * rotationScaleAdjustment) + ')'
465 ].join(' ');
450 }; 466 };
451 467
452 /** 468 /**
453 * Obtains shift CSS transformation for the screen image. 469 * Obtains shift CSS transformation for the screen image.
454 * @param {number} dx Amount of shift. 470 * @param {number} dx Amount of shift.
455 * @return {string} Transformation description. 471 * @return {string} Transformation description.
456 */ 472 */
457 Viewport.prototype.getShiftTransformation = function(dx) { 473 Viewport.prototype.getShiftTransformation = function(dx) {
458 return 'translateX(' + dx + 'px) ' + this.getTransformation(); 474 return 'translateX(' + dx + 'px) ' + this.getTransformation();
459 }; 475 };
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 var screenWidth = this.screenBounds_.width; 540 var screenWidth = this.screenBounds_.width;
525 var screenHeight = this.screenBounds_.height; 541 var screenHeight = this.screenBounds_.height;
526 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2; 542 var dx = screenRect.left + screenRect.width / 2 - screenWidth / 2;
527 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2; 543 var dy = screenRect.top + screenRect.height / 2 - screenHeight / 2;
528 return [ 544 return [
529 'translate(' + dx + 'px,' + dy + 'px)', 545 'translate(' + dx + 'px,' + dy + 'px)',
530 'scale(' + scaleX + ',' + scaleY + ')', 546 'scale(' + scaleX + ',' + scaleY + ')',
531 this.getTransformation() 547 this.getTransformation()
532 ].join(' '); 548 ].join(' ');
533 }; 549 };
OLDNEW
« no previous file with comments | « ui/file_manager/gallery/js/image_editor/image_view.js ('k') | ui/file_manager/gallery/js/slide_mode.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698