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

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

Issue 1608143002: support animated GIF (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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
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 /** 5 /**
6 * The overlay displaying the image. 6 * The overlay displaying the image.
7 * 7 *
8 * @param {!HTMLElement} container The container element. 8 * @param {!HTMLElement} container The container element.
9 * @param {!Viewport} viewport The viewport. 9 * @param {!Viewport} viewport The viewport.
10 * @param {!MetadataModel} metadataModel 10 * @param {!MetadataModel} metadataModel
(...skipping 20 matching lines...) Expand all
31 this.imageLoader_ = 31 this.imageLoader_ =
32 new ImageUtil.ImageLoader(this.document_, metadataModel); 32 new ImageUtil.ImageLoader(this.document_, metadataModel);
33 // We have a separate image loader for prefetch which does not get cancelled 33 // We have a separate image loader for prefetch which does not get cancelled
34 // when the selection changes. 34 // when the selection changes.
35 this.prefetchLoader_ = 35 this.prefetchLoader_ =
36 new ImageUtil.ImageLoader(this.document_, metadataModel); 36 new ImageUtil.ImageLoader(this.document_, metadataModel);
37 37
38 this.contentCallbacks_ = []; 38 this.contentCallbacks_ = [];
39 39
40 /** 40 /**
41 * The element displaying the current content.
42 * @type {HTMLCanvasElement}
43 * @private
44 */
45 this.screenImage_ = null;
46
47 /**
48 * The content canvas element. 41 * The content canvas element.
hirono 2016/01/20 06:07:09 This is existing document error, but could you upd
ryoh 2016/01/21 03:19:55 Done.
49 * @type {(HTMLCanvasElement|HTMLImageElement)} 42 * @type {(HTMLCanvasElement|HTMLImageElement)}
50 * @private 43 * @private
51 */ 44 */
52 this.contentCanvas_ = null; 45 this.contentImage_ = null;
53 46
54 /** 47 /**
55 * True if the image is a preview (not full res). 48 * True if the image is a preview (not full res).
56 * @type {boolean} 49 * @type {boolean}
57 * @private 50 * @private
58 */ 51 */
59 this.preview_ = false; 52 this.preview_ = false;
60 53
61 /** 54 /**
62 * Cached thumbnail image. 55 * Cached thumbnail image.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 165
173 /** 166 /**
174 * @override 167 * @override
175 */ 168 */
176 ImageView.prototype.getZIndex = function() { return -1; }; 169 ImageView.prototype.getZIndex = function() { return -1; };
177 170
178 /** 171 /**
179 * @override 172 * @override
180 */ 173 */
181 ImageView.prototype.draw = function() { 174 ImageView.prototype.draw = function() {
182 if (!this.contentCanvas_) // Do nothing if the image content is not set. 175 if (!this.contentImage_) // Do nothing if the image content is not set.
183 return; 176 return;
184 this.setTransform_( 177 this.setTransform_(
185 this.contentCanvas_, 178 this.contentImage_,
186 this.viewport_, 179 this.viewport_,
187 new ImageView.Effect.None(), 180 new ImageView.Effect.None(),
188 ImageView.Effect.DEFAULT_DURATION); 181 ImageView.Effect.DEFAULT_DURATION);
189 if ((this.screenImage_ && this.setupDeviceBuffer(this.screenImage_)) ||
190 this.displayedContentGeneration_ !== this.contentGeneration_) {
191 this.displayedContentGeneration_ = this.contentGeneration_;
192 ImageUtil.trace.resetTimer('paint');
193 this.paintDeviceRect(
194 this.contentCanvas_, ImageRect.createFromImage(this.contentCanvas_));
195 ImageUtil.trace.reportTimer('paint');
196 }
197 }; 182 };
198 183
199 /** 184 /**
200 * Applies the viewport change that does not affect the screen cache size (zoom 185 * Applies the viewport change that does not affect the screen cache size (zoom
201 * change or offset change) with animation. 186 * change or offset change) with animation.
202 */ 187 */
203 ImageView.prototype.applyViewportChange = function() { 188 ImageView.prototype.applyViewportChange = function() {
204 var zooming = this.viewport_.getZoom() > 1; 189 if (this.contentImage_) {
205 if (this.contentCanvas_) {
206 // Show full resolution image only for zooming.
207 this.contentCanvas_.style.opacity = zooming ? '1' : '0';
208 this.setTransform_( 190 this.setTransform_(
209 this.contentCanvas_, 191 this.contentImage_,
210 this.viewport_, 192 this.viewport_,
211 new ImageView.Effect.None(), 193 new ImageView.Effect.None(),
212 ImageView.Effect.DEFAULT_DURATION); 194 ImageView.Effect.DEFAULT_DURATION);
213 } 195 }
214 if (this.screenImage_) {
215 this.setTransform_(
216 this.screenImage_,
217 this.viewport_,
218 new ImageView.Effect.None(),
219 ImageView.Effect.DEFAULT_DURATION);
220 }
221 }; 196 };
222 197
223 /** 198 /**
224 * @return {number} The cache generation. 199 * @return {number} The cache generation.
225 */ 200 */
226 ImageView.prototype.getCacheGeneration = function() { 201 ImageView.prototype.getCacheGeneration = function() {
227 return this.contentGeneration_; 202 return this.contentGeneration_;
228 }; 203 };
229 204
230 /** 205 /**
231 * Invalidates the caches to force redrawing the screen canvas. 206 * Invalidates the caches to force redrawing the screen canvas.
232 */ 207 */
233 ImageView.prototype.invalidateCaches = function() { 208 ImageView.prototype.invalidateCaches = function() {
234 this.contentGeneration_++; 209 this.contentGeneration_++;
235 }; 210 };
236 211
237 /** 212 /**
238 * @return {HTMLCanvasElement} The content canvas element. 213 * @return {HTMLCanvasElement|HTMLImageElement} The content image(or element).
yawano 2016/01/20 06:23:09 (or canvas) element?
ryoh 2016/01/21 03:19:55 Done.
239 */ 214 */
240 ImageView.prototype.getCanvas = function() { return this.contentCanvas_; }; 215 ImageView.prototype.getImage = function() { return this.contentImage_; };
241 216
242 /** 217 /**
243 * @return {boolean} True if the a valid image is currently loaded. 218 * @return {boolean} True if the a valid image is currently loaded.
244 */ 219 */
245 ImageView.prototype.hasValidImage = function() { 220 ImageView.prototype.hasValidImage = function() {
246 return !!(!this.preview_ && this.contentCanvas_ && this.contentCanvas_.width); 221 return !!(!this.preview_ && this.contentImage_ && this.contentImage_.width);
247 }; 222 };
248 223
249 /** 224 /**
250 * @return {!HTMLCanvasElement} The cached thumbnail image. 225 * @return {!HTMLCanvasElement} The cached thumbnail image.
251 */ 226 */
252 ImageView.prototype.getThumbnail = function() { 227 ImageView.prototype.getThumbnail = function() {
253 assert(this.thumbnailCanvas_); 228 assert(this.thumbnailCanvas_);
254 return this.thumbnailCanvas_; 229 return this.thumbnailCanvas_;
255 }; 230 };
256 231
(...skipping 18 matching lines...) Expand all
275 var deviceBounds = this.viewport_.getDeviceBounds(); 250 var deviceBounds = this.viewport_.getDeviceBounds();
276 var scaleX = deviceBounds.width / canvas.width; 251 var scaleX = deviceBounds.width / canvas.width;
277 var scaleY = deviceBounds.height / canvas.height; 252 var scaleY = deviceBounds.height / canvas.height;
278 var deviceRect = new ImageRect( 253 var deviceRect = new ImageRect(
279 imageRect.left * scaleX, 254 imageRect.left * scaleX,
280 imageRect.top * scaleY, 255 imageRect.top * scaleY,
281 imageRect.width * scaleX, 256 imageRect.width * scaleX,
282 imageRect.height * scaleY); 257 imageRect.height * scaleY);
283 258
284 ImageRect.drawImage( 259 ImageRect.drawImage(
285 this.screenImage_.getContext('2d'), canvas, deviceRect, imageRect); 260 this.contentImage_.getContext('2d'), canvas, deviceRect, imageRect);
hirono 2016/01/20 06:07:10 Can we ensure this.contentImage_ is a canvas here?
ryoh 2016/01/21 03:19:55 Done.
286 }; 261 };
287 262
288 /** 263 /**
289 * Creates an overlay canvas with properties similar to the screen canvas. 264 * Creates an overlay canvas with properties similar to the screen canvas.
290 * Useful for showing quick feedback when editing. 265 * Useful for showing quick feedback when editing.
291 * 266 *
292 * @return {!HTMLCanvasElement} Overlay canvas. 267 * @return {!HTMLCanvasElement} Overlay canvas.
293 */ 268 */
294 ImageView.prototype.createOverlayCanvas = function() { 269 ImageView.prototype.createOverlayCanvas = function() {
295 var canvas = assertInstanceof(this.document_.createElement('canvas'), 270 var canvas = assertInstanceof(this.document_.createElement('canvas'),
(...skipping 24 matching lines...) Expand all
320 this.setTransform_(canvas, this.viewport_); 295 this.setTransform_(canvas, this.viewport_);
321 return needRepaint; 296 return needRepaint;
322 }; 297 };
323 298
324 /** 299 /**
325 * Gets screen image data with specified size. 300 * Gets screen image data with specified size.
326 * @param {number} width 301 * @param {number} width
327 * @param {number} height 302 * @param {number} height
328 * @return {!ImageData} A new ImageData object. 303 * @return {!ImageData} A new ImageData object.
329 */ 304 */
330 ImageView.prototype.getScreenImageDataWith = function(width, height) { 305 ImageView.prototype.getScreenImageDataWith = function(width, height) {
hirono 2016/01/20 06:07:09 Could you update the caller of this method so that
ryoh 2016/01/21 03:19:55 Done.
331 // If specified size is same with current screen image size, just return it. 306 // If specified size is same with current screen image size
332 if (width === this.screenImage_.width && 307 // and it's a canvas, just return it.
333 height === this.screenImage_.height) { 308 if (width === this.contentImage_.width &&
334 return this.screenImage_.getContext('2d').getImageData( 309 height === this.contentImage_.height &&
335 0, 0, this.screenImage_.width, this.screenImage_.height); 310 this.contentImage_.tagName === 'canvas') {
311 return this.contentImage_.getImageData(0,0,width,height);
yawano 2016/01/20 06:23:09 nit: put space after ",".
ryoh 2016/01/21 03:19:55 Done.
336 } 312 }
337 313
338 // Resize if these sizes are different. 314 // Resize if these sizes are different.
339 var resizeCanvas = document.createElement('canvas'); 315 var resizeCanvas = document.createElement('canvas');
340 resizeCanvas.width = width; 316 resizeCanvas.width = width;
341 resizeCanvas.height = height; 317 resizeCanvas.height = height;
342 318
343 var context = resizeCanvas.getContext('2d'); 319 var context = resizeCanvas.getContext('2d');
344 context.drawImage(this.screenImage_, 320 context.drawImage(this.contentImage_,
345 0, 0, this.screenImage_.width, this.screenImage_.height, 321 0, 0, this.contentImage_.width, this.contentImage_.height,
346 0, 0, resizeCanvas.width, resizeCanvas.height); 322 0, 0, resizeCanvas.width, resizeCanvas.height);
347 return context.getImageData(0, 0, resizeCanvas.width, resizeCanvas.height); 323 return context.getImageData(0, 0, resizeCanvas.width, resizeCanvas.height);
348 }; 324 };
349 325
350 /** 326 /**
351 * @return {boolean} True if the image is currently being loaded. 327 * @return {boolean} True if the image is currently being loaded.
352 */ 328 */
353 ImageView.prototype.isLoading = function() { 329 ImageView.prototype.isLoading = function() {
354 return this.imageLoader_.isBusy(); 330 return this.imageLoader_.isBusy();
355 }; 331 };
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 510
535 /** 511 /**
536 * Unloads content. 512 * Unloads content.
537 * @param {ImageRect=} opt_zoomToRect Target rectangle for zoom-out-effect. 513 * @param {ImageRect=} opt_zoomToRect Target rectangle for zoom-out-effect.
538 */ 514 */
539 ImageView.prototype.unload = function(opt_zoomToRect) { 515 ImageView.prototype.unload = function(opt_zoomToRect) {
540 if (this.unloadTimer_) { 516 if (this.unloadTimer_) {
541 clearTimeout(this.unloadTimer_); 517 clearTimeout(this.unloadTimer_);
542 this.unloadTimer_ = null; 518 this.unloadTimer_ = null;
543 } 519 }
544 if (opt_zoomToRect && this.screenImage_) {
hirono 2016/01/20 06:07:09 I think we cannot remove this zoom out effect. Cou
ryoh 2016/01/21 03:19:55 Yeah, we can't remove. Thanks.
545 var effect = this.createZoomEffect(opt_zoomToRect);
546 this.setTransform_(this.screenImage_, this.viewport_, effect);
547 this.screenImage_.setAttribute('fade', true);
548 this.unloadTimer_ = setTimeout(function() {
549 this.unloadTimer_ = null;
550 this.unload(null /* force unload */);
551 }.bind(this), effect.getSafeInterval());
552 return;
553 }
554 this.container_.textContent = ''; 520 this.container_.textContent = '';
555 this.contentCanvas_ = null; 521 this.contentImage_ = null;
556 this.screenImage_ = null;
557 }; 522 };
558 523
559 /** 524 /**
560 * @param {!(HTMLCanvasElement|HTMLImageElement)} content The image element. 525 * @param {!(HTMLCanvasElement|HTMLImageElement)} content The image element.
561 * @param {number=} opt_width Image width. 526 * @param {number=} opt_width Image width.
562 * @param {number=} opt_height Image height. 527 * @param {number=} opt_height Image height.
563 * @param {boolean=} opt_preview True if the image is a preview (not full res). 528 * @param {boolean=} opt_preview True if the image is a preview (not full res).
564 * @private 529 * @private
565 */ 530 */
566 ImageView.prototype.replaceContent_ = function( 531 ImageView.prototype.replaceContent_ = function(
567 content, opt_width, opt_height, opt_preview) { 532 content, opt_width, opt_height, opt_preview) {
568 533
569 if (this.contentCanvas_ && this.contentCanvas_.parentNode === this.container_) 534 if (this.contentImage_ && this.contentImage_.parentNode === this.container_)
570 this.container_.removeChild(this.contentCanvas_); 535 this.container_.removeChild(this.contentImage_);
571 536
572 this.screenImage_ = assertInstanceof(this.document_.createElement('canvas'), 537 this.contentImage_ = content;
573 HTMLCanvasElement);
574 this.screenImage_.className = 'image';
575
576 this.contentCanvas_ = content;
577 this.invalidateCaches(); 538 this.invalidateCaches();
578 this.viewport_.setImageSize( 539 this.viewport_.setImageSize(
579 opt_width || this.contentCanvas_.width, 540 opt_width || this.contentImage_.width,
580 opt_height || this.contentCanvas_.height); 541 opt_height || this.contentImage_.height);
581 this.draw(); 542 this.draw();
582 543
583 this.container_.appendChild(this.screenImage_);
584
585 this.preview_ = opt_preview || false; 544 this.preview_ = opt_preview || false;
586 // If this is not a thumbnail, cache the content and the screen-scale image. 545 // If this is not a thumbnail, cache the content and the screen-scale image.
587 if (this.hasValidImage()) { 546 if (this.hasValidImage()) {
588 // Insert the full resolution canvas into DOM so that it can be printed. 547 // Insert the full resolution canvas into DOM so that it can be printed.
589 this.container_.appendChild(this.contentCanvas_); 548 this.container_.appendChild(this.contentImage_);
590 this.contentCanvas_.classList.add('fullres'); 549 this.contentImage_.classList.add('image');
591 this.setTransform_( 550 this.setTransform_(
592 this.contentCanvas_, this.viewport_, null, 0); 551 this.contentImage_, this.viewport_, null, 0);
hirono 2016/01/20 06:07:09 nit: It looks to fit in one line.
ryoh 2016/01/21 03:19:55 Done.
593 552
594 this.contentItem_.contentImage = this.contentCanvas_; 553 this.contentItem_.contentImage = this.contentImage_;
595 this.contentItem_.screenImage = this.screenImage_;
596 554
597 // TODO(kaznacheev): It is better to pass screenImage_ as it is usually 555 this.updateThumbnail_(this.contentImage_);
598 // much smaller than contentCanvas_ and still contains the entire image.
599 // Once we implement zoom/pan we should pass contentCanvas_ instead.
600 this.updateThumbnail_(this.screenImage_);
601 556
602 this.contentRevision_++; 557 this.contentRevision_++;
603 for (var i = 0; i !== this.contentCallbacks_.length; i++) { 558 for (var i = 0; i !== this.contentCallbacks_.length; i++) {
604 try { 559 try {
605 this.contentCallbacks_[i](); 560 this.contentCallbacks_[i]();
606 } catch (e) { 561 } catch (e) {
607 console.error(e); 562 console.error(e);
608 } 563 }
609 } 564 }
610 } 565 }
611 }; 566 };
612 567
613 /** 568 /**
614 * Adds a listener for content changes. 569 * Adds a listener for content changes.
615 * @param {function()} callback Callback. 570 * @param {function()} callback Callback.
616 */ 571 */
617 ImageView.prototype.addContentCallback = function(callback) { 572 ImageView.prototype.addContentCallback = function(callback) {
618 this.contentCallbacks_.push(callback); 573 this.contentCallbacks_.push(callback);
619 }; 574 };
620 575
621 /** 576 /**
622 * Updates the cached thumbnail image. 577 * Updates the cached thumbnail image.
623 * 578 *
624 * @param {!HTMLCanvasElement} canvas The source canvas. 579 * @param {!HTMLCanvasElement|!HTMLImageElement} canvas The source canvas.
hirono 2016/01/20 06:07:09 Please update 'canvas' with right name.
ryoh 2016/01/21 03:19:55 Done.
625 * @private 580 * @private
626 */ 581 */
627 ImageView.prototype.updateThumbnail_ = function(canvas) { 582 ImageView.prototype.updateThumbnail_ = function(canvas) {
628 ImageUtil.trace.resetTimer('thumb'); 583 ImageUtil.trace.resetTimer('thumb');
629 var pixelCount = 10000; 584 var pixelCount = 10000;
630 var downScale = 585 var downScale =
631 Math.max(1, Math.sqrt(canvas.width * canvas.height / pixelCount)); 586 Math.max(1, Math.sqrt(canvas.width * canvas.height / pixelCount));
632 587
633 this.thumbnailCanvas_ = canvas.ownerDocument.createElement('canvas'); 588 this.thumbnailCanvas_ = canvas.ownerDocument.createElement('canvas');
634 this.thumbnailCanvas_.width = Math.round(canvas.width / downScale); 589 this.thumbnailCanvas_.width = Math.round(canvas.width / downScale);
635 this.thumbnailCanvas_.height = Math.round(canvas.height / downScale); 590 this.thumbnailCanvas_.height = Math.round(canvas.height / downScale);
636 ImageRect.drawImage(this.thumbnailCanvas_.getContext('2d'), canvas); 591 ImageRect.drawImage(this.thumbnailCanvas_.getContext('2d'), canvas);
637 ImageUtil.trace.reportTimer('thumb'); 592 ImageUtil.trace.reportTimer('thumb');
638 }; 593 };
639 594
640 /** 595 /**
641 * Replaces the displayed image, possibly with slide-in animation. 596 * Replaces the displayed image, possibly with slide-in animation.
642 * 597 *
643 * @param {!(HTMLCanvasElement|HTMLImageElement)} content The image element. 598 * @param {!(HTMLCanvasElement|HTMLImageElement)} newContentImage
599 * The image element.
644 * @param {ImageView.Effect=} opt_effect Transition effect object. 600 * @param {ImageView.Effect=} opt_effect Transition effect object.
645 * @param {number=} opt_width Image width. 601 * @param {number=} opt_width Image width.
646 * @param {number=} opt_height Image height. 602 * @param {number=} opt_height Image height.
647 * @param {boolean=} opt_preview True if the image is a preview (not full res). 603 * @param {boolean=} opt_preview True if the image is a preview (not full res).
648 */ 604 */
649 ImageView.prototype.replace = function( 605 ImageView.prototype.replace = function(
650 content, opt_effect, opt_width, opt_height, opt_preview) { 606 newContentImage, opt_effect, opt_width, opt_height, opt_preview) {
651 var oldScreenImage = this.screenImage_; 607 var oldContentImage = this.contentImage_;
652 var oldViewport = this.viewport_.clone(); 608 var oldViewport = this.viewport_.clone();
653 this.replaceContent_(content, opt_width, opt_height, opt_preview); 609 this.replaceContent_(newContentImage, opt_width, opt_height, opt_preview);
654 if (!opt_effect) { 610 if (!opt_effect) {
655 if (oldScreenImage)
656 oldScreenImage.parentNode.removeChild(oldScreenImage);
657 return; 611 return;
658 } 612 }
659 613
660 assert(this.screenImage_); 614 assert(this.contentImage_);
661 var newScreenImage = this.screenImage_;
662 this.viewport_.resetView(); 615 this.viewport_.resetView();
663 616
664 if (oldScreenImage) 617 if (oldContentImage)
665 ImageUtil.setAttribute(newScreenImage, 'fade', true); 618 ImageUtil.setAttribute(newContentImage, 'fade', true);
666 this.setTransform_( 619 this.setTransform_(
667 newScreenImage, this.viewport_, opt_effect, 0 /* instant */); 620 newContentImage, this.viewport_, opt_effect, 0 /* instant */);
668 this.setTransform_(
669 content, this.viewport_, opt_effect, 0 /* instant */);
670 621
671 // We need to call requestAnimationFrame twice here. The first call is for 622 // We need to call requestAnimationFrame twice here. The first call is for
672 // commiting the styles of beggining of transition that are assigned above. 623 // commiting the styles of beggining of transition that are assigned above.
673 // The second call is for assigning and commiting the styles of end of 624 // The second call is for assigning and commiting the styles of end of
674 // transition, which triggers transition animation. 625 // transition, which triggers transition animation.
675 requestAnimationFrame(function() { 626 requestAnimationFrame(function() {
676 requestAnimationFrame(function() { 627 requestAnimationFrame(function() {
677 this.setTransform_( 628 this.setTransform_(
678 newScreenImage, 629 newContentImage,
679 this.viewport_, 630 this.viewport_,
680 null, 631 null,
681 opt_effect ? opt_effect.getDuration() : undefined); 632 opt_effect ? opt_effect.getDuration() : undefined);
682 this.setTransform_( 633 if (oldContentImage) {
683 content, 634 ImageUtil.setAttribute(newContentImage, 'fade', false);
684 this.viewport_, 635 ImageUtil.setAttribute(oldContentImage, 'fade', true);
685 null,
686 opt_effect ? opt_effect.getDuration() : undefined);
687 if (oldScreenImage) {
688 ImageUtil.setAttribute(newScreenImage, 'fade', false);
689 ImageUtil.setAttribute(oldScreenImage, 'fade', true);
690 var reverse = opt_effect.getReverse(); 636 var reverse = opt_effect.getReverse();
691 if (reverse) { 637 if (reverse) {
692 this.setTransform_(oldScreenImage, oldViewport, reverse); 638 this.setTransform_(oldContentImage, oldViewport, reverse);
693 setTimeout(function() { 639 setTimeout(function() {
694 if (oldScreenImage.parentNode) 640 if (oldContentImage.parentNode)
695 oldScreenImage.parentNode.removeChild(oldScreenImage); 641 oldContentImage.parentNode.removeChild(oldContentImage);
696 }, reverse.getSafeInterval()); 642 }, reverse.getSafeInterval());
697 } else { 643 } else {
698 if (oldScreenImage.parentNode) 644 if (oldContentImage.parentNode)
699 oldScreenImage.parentNode.removeChild(oldScreenImage); 645 oldContentImage.parentNode.removeChild(oldContentImage);
700 } 646 }
701 } 647 }
702 }.bind(this)); 648 }.bind(this));
703 }.bind(this)); 649 }.bind(this));
704 }; 650 };
705 651
706 /** 652 /**
707 * @param {!HTMLCanvasElement|!HTMLImageElement} element The element to 653 * @param {!HTMLCanvasElement|!HTMLImageElement} element The element to
708 * transform. 654 * transform.
709 * @param {!Viewport} viewport Viewport to be used for calculating 655 * @param {!Viewport} viewport Viewport to be used for calculating
(...skipping 29 matching lines...) Expand all
739 * the new image to visualize the operation. 685 * the new image to visualize the operation.
740 * 686 *
741 * @param {!HTMLCanvasElement} canvas New content canvas. 687 * @param {!HTMLCanvasElement} canvas New content canvas.
742 * @param {ImageRect} imageCropRect The crop rectangle in image coordinates. 688 * @param {ImageRect} imageCropRect The crop rectangle in image coordinates.
743 * Null for rotation operations. 689 * Null for rotation operations.
744 * @param {number} rotate90 Rotation angle in 90 degree increments. 690 * @param {number} rotate90 Rotation angle in 90 degree increments.
745 * @return {number} Animation duration. 691 * @return {number} Animation duration.
746 */ 692 */
747 ImageView.prototype.replaceAndAnimate = function( 693 ImageView.prototype.replaceAndAnimate = function(
748 canvas, imageCropRect, rotate90) { 694 canvas, imageCropRect, rotate90) {
749 assert(this.screenImage_); 695 assert(this.contentImage_);
750 696
751 var oldImageBounds = { 697 var oldImageBounds = {
752 width: this.viewport_.getImageBounds().width, 698 width: this.viewport_.getImageBounds().width,
753 height: this.viewport_.getImageBounds().height 699 height: this.viewport_.getImageBounds().height
754 }; 700 };
755 var oldScreenImage = this.screenImage_; 701 var oldScreenImage = this.contentImage_;
756 this.replaceContent_(canvas); 702 this.replaceContent_(canvas);
757 var newScreenImage = this.screenImage_; 703 var newScreenImage = this.contentImage_;
758 var effect = rotate90 ? 704 var effect = rotate90 ?
759 new ImageView.Effect.Rotate(rotate90 > 0) : 705 new ImageView.Effect.Rotate(rotate90 > 0) :
760 new ImageView.Effect.Zoom( 706 new ImageView.Effect.Zoom(
761 oldImageBounds.width, oldImageBounds.height, assert(imageCropRect)); 707 oldImageBounds.width, oldImageBounds.height, assert(imageCropRect));
762 708
763 this.setTransform_(newScreenImage, this.viewport_, effect, 0 /* instant */); 709 this.setTransform_(newScreenImage, this.viewport_, effect, 0 /* instant */);
764 710
765 oldScreenImage.parentNode.appendChild(newScreenImage);
766 oldScreenImage.parentNode.removeChild(oldScreenImage);
767
768 // Let the layout fire, then animate back to non-transformed state. 711 // Let the layout fire, then animate back to non-transformed state.
769 setTimeout( 712 setTimeout(
770 this.setTransform_.bind( 713 this.setTransform_.bind(
771 this, newScreenImage, this.viewport_, null, effect.getDuration()), 714 this, newScreenImage, this.viewport_, null, effect.getDuration()),
772 0); 715 0);
773 716
774 return effect.getSafeInterval(); 717 return effect.getSafeInterval();
775 }; 718 };
776 719
777 /** 720 /**
778 * Visualizes "undo crop". Shrink the current image to the given crop rectangle 721 * Visualizes "undo crop". Shrink the current image to the given crop rectangle
779 * while fading in the new image. 722 * while fading in the new image.
780 * 723 *
781 * @param {!HTMLCanvasElement} canvas New content canvas. 724 * @param {!HTMLCanvasElement} canvas New content canvas.
782 * @param {!ImageRect} imageCropRect The crop rectangle in image coordinates. 725 * @param {!ImageRect} imageCropRect The crop rectangle in image coordinates.
783 * @return {number} Animation duration. 726 * @return {number} Animation duration.
784 */ 727 */
785 ImageView.prototype.animateAndReplace = function(canvas, imageCropRect) { 728 ImageView.prototype.animateAndReplace = function(canvas, imageCropRect) {
786 var oldScreenImage = this.screenImage_; 729 var oldScreenImage = this.contentImage_;
787 this.replaceContent_(canvas); 730 this.replaceContent_(canvas);
788 var newScreenImage = this.screenImage_; 731 var newScreenImage = this.contentImage_;
789 var setFade = ImageUtil.setAttribute.bind(null, assert(newScreenImage), 732 var setFade = ImageUtil.setAttribute.bind(null, assert(newScreenImage),
790 'fade'); 733 'fade');
791 setFade(true); 734 setFade(true);
792 oldScreenImage.parentNode.insertBefore(newScreenImage, oldScreenImage);
793 var effect = new ImageView.Effect.Zoom( 735 var effect = new ImageView.Effect.Zoom(
794 this.viewport_.getImageBounds().width, 736 this.viewport_.getImageBounds().width,
795 this.viewport_.getImageBounds().height, 737 this.viewport_.getImageBounds().height,
796 imageCropRect); 738 imageCropRect);
797 739
798 // Animate to the transformed state.
799 this.setTransform_(oldScreenImage, this.viewport_, effect);
hirono 2016/01/20 06:07:09 It looks we cannot remove this effect.
ryoh 2016/01/21 03:19:55 Done.
800 setTimeout(setFade.bind(null, false), 0); 740 setTimeout(setFade.bind(null, false), 0);
801 setTimeout(function() {
802 if (oldScreenImage.parentNode)
803 oldScreenImage.parentNode.removeChild(oldScreenImage);
804 }, effect.getSafeInterval());
805 741
806 return effect.getSafeInterval(); 742 return effect.getSafeInterval();
807 }; 743 };
808 744
809 /* Transition effects */ 745 /* Transition effects */
810 746
811 /** 747 /**
812 * Base class for effects. 748 * Base class for effects.
813 * 749 *
814 * @param {number} duration Duration in ms. 750 * @param {number} duration Duration in ms.
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 951
1016 ImageView.Effect.Rotate.prototype = { __proto__: ImageView.Effect.prototype }; 952 ImageView.Effect.Rotate.prototype = { __proto__: ImageView.Effect.prototype };
1017 953
1018 /** 954 /**
1019 * @override 955 * @override
1020 */ 956 */
1021 ImageView.Effect.Rotate.prototype.transform = function(element, viewport) { 957 ImageView.Effect.Rotate.prototype.transform = function(element, viewport) {
1022 return viewport.getRotatingTransformation( 958 return viewport.getRotatingTransformation(
1023 element.width, element.height, this.orientation_ ? -1 : 1); 959 element.width, element.height, this.orientation_ ? -1 : 1);
1024 }; 960 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698