OLD | NEW |
---|---|
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 Loading... | |
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. | 41 * The content image or canvas element. |
42 * @type {HTMLCanvasElement} | |
43 * @private | |
44 */ | |
45 this.screenImage_ = null; | |
46 | |
47 /** | |
48 * The content canvas element. | |
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 Loading... | |
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 canvas). |
239 */ | 214 */ |
240 ImageView.prototype.getCanvas = function() { return this.contentCanvas_; }; | 215 ImageView.prototype.getImage = function() { return assert(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 17 matching lines...) Expand all Loading... | |
274 // canvas. | 249 // canvas. |
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 if (this.contentImage_.tagName === 'canvas') { |
285 this.screenImage_.getContext('2d'), canvas, deviceRect, imageRect); | 260 ImageRect.drawImage( |
261 this.contentImage_.getContext('2d'), canvas, deviceRect, imageRect); | |
262 } else { | |
263 ImageRect.drawImage(this.contentImage_, canvas, deviceRect, imageRect); | |
yawano
2016/01/21 05:14:38
Is it okay to pass an image element as the first a
ryoh
2016/01/21 07:28:53
Done.
| |
264 } | |
286 }; | 265 }; |
287 | 266 |
288 /** | 267 /** |
289 * Creates an overlay canvas with properties similar to the screen canvas. | 268 * Creates an overlay canvas with properties similar to the screen canvas. |
290 * Useful for showing quick feedback when editing. | 269 * Useful for showing quick feedback when editing. |
291 * | 270 * |
292 * @return {!HTMLCanvasElement} Overlay canvas. | 271 * @return {!HTMLCanvasElement} Overlay canvas. |
293 */ | 272 */ |
294 ImageView.prototype.createOverlayCanvas = function() { | 273 ImageView.prototype.createOverlayCanvas = function() { |
295 var canvas = assertInstanceof(this.document_.createElement('canvas'), | 274 var canvas = assertInstanceof(this.document_.createElement('canvas'), |
(...skipping 19 matching lines...) Expand all Loading... | |
315 } | 294 } |
316 if (canvas.height !== deviceRect.height) { | 295 if (canvas.height !== deviceRect.height) { |
317 canvas.height = deviceRect.height; | 296 canvas.height = deviceRect.height; |
318 needRepaint = true; | 297 needRepaint = true; |
319 } | 298 } |
320 this.setTransform_(canvas, this.viewport_); | 299 this.setTransform_(canvas, this.viewport_); |
321 return needRepaint; | 300 return needRepaint; |
322 }; | 301 }; |
323 | 302 |
324 /** | 303 /** |
325 * Gets screen image data with specified size. | 304 * Gets screen image canvas with specified size. |
326 * @param {number} width | 305 * @param {number} width |
327 * @param {number} height | 306 * @param {number} height |
328 * @return {!ImageData} A new ImageData object. | 307 * @return {!HTMLCanvasElement} A scaled canvas. |
329 */ | 308 */ |
330 ImageView.prototype.getScreenImageDataWith = function(width, height) { | 309 ImageView.prototype.getImageCanvasWith = function(width, height) { |
331 // If specified size is same with current screen image size, just return it. | |
332 if (width === this.screenImage_.width && | |
333 height === this.screenImage_.height) { | |
334 return this.screenImage_.getContext('2d').getImageData( | |
335 0, 0, this.screenImage_.width, this.screenImage_.height); | |
336 } | |
337 | |
338 // Resize if these sizes are different. | 310 // Resize if these sizes are different. |
339 var resizeCanvas = document.createElement('canvas'); | 311 var resizeCanvas = assertInstanceof(document.createElement('canvas'), |
312 HTMLCanvasElement); | |
340 resizeCanvas.width = width; | 313 resizeCanvas.width = width; |
341 resizeCanvas.height = height; | 314 resizeCanvas.height = height; |
342 | 315 |
343 var context = resizeCanvas.getContext('2d'); | 316 var context = resizeCanvas.getContext('2d'); |
344 context.drawImage(this.screenImage_, | 317 context.drawImage(this.contentImage_, |
345 0, 0, this.screenImage_.width, this.screenImage_.height, | 318 0, 0, this.contentImage_.width, this.contentImage_.height, |
346 0, 0, resizeCanvas.width, resizeCanvas.height); | 319 0, 0, resizeCanvas.width, resizeCanvas.height); |
347 return context.getImageData(0, 0, resizeCanvas.width, resizeCanvas.height); | 320 return resizeCanvas; |
348 }; | 321 }; |
349 | 322 |
350 /** | 323 /** |
351 * @return {boolean} True if the image is currently being loaded. | 324 * @return {boolean} True if the image is currently being loaded. |
352 */ | 325 */ |
353 ImageView.prototype.isLoading = function() { | 326 ImageView.prototype.isLoading = function() { |
354 return this.imageLoader_.isBusy(); | 327 return this.imageLoader_.isBusy(); |
355 }; | 328 }; |
356 | 329 |
357 /** | 330 /** |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 | 507 |
535 /** | 508 /** |
536 * Unloads content. | 509 * Unloads content. |
537 * @param {ImageRect=} opt_zoomToRect Target rectangle for zoom-out-effect. | 510 * @param {ImageRect=} opt_zoomToRect Target rectangle for zoom-out-effect. |
538 */ | 511 */ |
539 ImageView.prototype.unload = function(opt_zoomToRect) { | 512 ImageView.prototype.unload = function(opt_zoomToRect) { |
540 if (this.unloadTimer_) { | 513 if (this.unloadTimer_) { |
541 clearTimeout(this.unloadTimer_); | 514 clearTimeout(this.unloadTimer_); |
542 this.unloadTimer_ = null; | 515 this.unloadTimer_ = null; |
543 } | 516 } |
544 if (opt_zoomToRect && this.screenImage_) { | 517 if (opt_zoomToRect && this.contentImage_) { |
545 var effect = this.createZoomEffect(opt_zoomToRect); | 518 var effect = this.createZoomEffect(opt_zoomToRect); |
546 this.setTransform_(this.screenImage_, this.viewport_, effect); | 519 this.setTransform_(this.contentImage_, this.viewport_, effect); |
547 this.screenImage_.setAttribute('fade', true); | 520 this.contentImage_.setAttribute('fade', true); |
548 this.unloadTimer_ = setTimeout(function() { | 521 this.unloadTimer_ = setTimeout(function() { |
549 this.unloadTimer_ = null; | 522 this.unloadTimer_ = null; |
550 this.unload(null /* force unload */); | 523 this.unload(null /* force unload */); |
551 }.bind(this), effect.getSafeInterval()); | 524 }.bind(this), effect.getSafeInterval()); |
552 return; | 525 return; |
553 } | 526 } |
554 this.container_.textContent = ''; | 527 this.container_.textContent = ''; |
555 this.contentCanvas_ = null; | 528 this.contentImage_ = null; |
556 this.screenImage_ = null; | |
557 }; | 529 }; |
558 | 530 |
559 /** | 531 /** |
560 * @param {!(HTMLCanvasElement|HTMLImageElement)} content The image element. | 532 * @param {!(HTMLCanvasElement|HTMLImageElement)} content The image element. |
561 * @param {number=} opt_width Image width. | 533 * @param {number=} opt_width Image width. |
562 * @param {number=} opt_height Image height. | 534 * @param {number=} opt_height Image height. |
563 * @param {boolean=} opt_preview True if the image is a preview (not full res). | 535 * @param {boolean=} opt_preview True if the image is a preview (not full res). |
564 * @private | 536 * @private |
565 */ | 537 */ |
566 ImageView.prototype.replaceContent_ = function( | 538 ImageView.prototype.replaceContent_ = function( |
567 content, opt_width, opt_height, opt_preview) { | 539 content, opt_width, opt_height, opt_preview) { |
568 | 540 |
569 if (this.contentCanvas_ && this.contentCanvas_.parentNode === this.container_) | 541 if (this.contentImage_ && this.contentImage_.parentNode === this.container_) |
570 this.container_.removeChild(this.contentCanvas_); | 542 this.container_.removeChild(this.contentImage_); |
571 | 543 |
572 this.screenImage_ = assertInstanceof(this.document_.createElement('canvas'), | 544 this.contentImage_ = content; |
573 HTMLCanvasElement); | 545 this.container_.appendChild(content); |
574 this.screenImage_.className = 'image'; | |
575 | |
576 this.contentCanvas_ = content; | |
577 this.invalidateCaches(); | 546 this.invalidateCaches(); |
578 this.viewport_.setImageSize( | 547 this.viewport_.setImageSize( |
579 opt_width || this.contentCanvas_.width, | 548 opt_width || this.contentImage_.width, |
580 opt_height || this.contentCanvas_.height); | 549 opt_height || this.contentImage_.height); |
581 this.draw(); | 550 this.draw(); |
582 | 551 |
583 this.container_.appendChild(this.screenImage_); | |
584 | |
585 this.preview_ = opt_preview || false; | 552 this.preview_ = opt_preview || false; |
586 // If this is not a thumbnail, cache the content and the screen-scale image. | 553 // If this is not a thumbnail, cache the content and the screen-scale image. |
587 if (this.hasValidImage()) { | 554 if (this.hasValidImage()) { |
588 // Insert the full resolution canvas into DOM so that it can be printed. | 555 // Insert the full resolution canvas into DOM so that it can be printed. |
589 this.container_.appendChild(this.contentCanvas_); | 556 this.container_.appendChild(this.contentImage_); |
yawano
2016/01/21 05:14:38
nit: unnecessary. contentImage_ should be children
ryoh
2016/01/21 07:28:53
Done.
| |
590 this.contentCanvas_.classList.add('fullres'); | 557 this.contentImage_.classList.add('image'); |
591 this.setTransform_( | 558 this.setTransform_(this.contentImage_, this.viewport_, null, 0); |
592 this.contentCanvas_, this.viewport_, null, 0); | |
593 | 559 |
594 this.contentItem_.contentImage = this.contentCanvas_; | 560 this.contentItem_.contentImage = this.contentImage_; |
595 this.contentItem_.screenImage = this.screenImage_; | |
596 | 561 |
597 // TODO(kaznacheev): It is better to pass screenImage_ as it is usually | 562 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 | 563 |
602 this.contentRevision_++; | 564 this.contentRevision_++; |
603 for (var i = 0; i !== this.contentCallbacks_.length; i++) { | 565 for (var i = 0; i !== this.contentCallbacks_.length; i++) { |
604 try { | 566 try { |
605 this.contentCallbacks_[i](); | 567 this.contentCallbacks_[i](); |
606 } catch (e) { | 568 } catch (e) { |
607 console.error(e); | 569 console.error(e); |
608 } | 570 } |
609 } | 571 } |
610 } | 572 } |
611 }; | 573 }; |
612 | 574 |
613 /** | 575 /** |
614 * Adds a listener for content changes. | 576 * Adds a listener for content changes. |
615 * @param {function()} callback Callback. | 577 * @param {function()} callback Callback. |
616 */ | 578 */ |
617 ImageView.prototype.addContentCallback = function(callback) { | 579 ImageView.prototype.addContentCallback = function(callback) { |
618 this.contentCallbacks_.push(callback); | 580 this.contentCallbacks_.push(callback); |
619 }; | 581 }; |
620 | 582 |
621 /** | 583 /** |
622 * Updates the cached thumbnail image. | 584 * Updates the cached thumbnail image. |
623 * | 585 * |
624 * @param {!HTMLCanvasElement} canvas The source canvas. | 586 * @param {!HTMLCanvasElement|!HTMLImageElement} image The source image or |
587 * canvas. | |
625 * @private | 588 * @private |
626 */ | 589 */ |
627 ImageView.prototype.updateThumbnail_ = function(canvas) { | 590 ImageView.prototype.updateThumbnail_ = function(image) { |
628 ImageUtil.trace.resetTimer('thumb'); | 591 ImageUtil.trace.resetTimer('thumb'); |
629 var pixelCount = 10000; | 592 var pixelCount = 10000; |
630 var downScale = | 593 var downScale = |
631 Math.max(1, Math.sqrt(canvas.width * canvas.height / pixelCount)); | 594 Math.max(1, Math.sqrt(image.width * image.height / pixelCount)); |
632 | 595 |
633 this.thumbnailCanvas_ = canvas.ownerDocument.createElement('canvas'); | 596 this.thumbnailCanvas_ = image.ownerDocument.createElement('canvas'); |
634 this.thumbnailCanvas_.width = Math.round(canvas.width / downScale); | 597 this.thumbnailCanvas_.width = Math.round(image.width / downScale); |
635 this.thumbnailCanvas_.height = Math.round(canvas.height / downScale); | 598 this.thumbnailCanvas_.height = Math.round(image.height / downScale); |
636 ImageRect.drawImage(this.thumbnailCanvas_.getContext('2d'), canvas); | 599 ImageRect.drawImage(this.thumbnailCanvas_.getContext('2d'), image); |
637 ImageUtil.trace.reportTimer('thumb'); | 600 ImageUtil.trace.reportTimer('thumb'); |
638 }; | 601 }; |
639 | 602 |
640 /** | 603 /** |
641 * Replaces the displayed image, possibly with slide-in animation. | 604 * Replaces the displayed image, possibly with slide-in animation. |
642 * | 605 * |
643 * @param {!(HTMLCanvasElement|HTMLImageElement)} content The image element. | 606 * @param {!(HTMLCanvasElement|HTMLImageElement)} newContentImage |
607 * The image element. | |
644 * @param {ImageView.Effect=} opt_effect Transition effect object. | 608 * @param {ImageView.Effect=} opt_effect Transition effect object. |
645 * @param {number=} opt_width Image width. | 609 * @param {number=} opt_width Image width. |
646 * @param {number=} opt_height Image height. | 610 * @param {number=} opt_height Image height. |
647 * @param {boolean=} opt_preview True if the image is a preview (not full res). | 611 * @param {boolean=} opt_preview True if the image is a preview (not full res). |
648 */ | 612 */ |
649 ImageView.prototype.replace = function( | 613 ImageView.prototype.replace = function( |
650 content, opt_effect, opt_width, opt_height, opt_preview) { | 614 newContentImage, opt_effect, opt_width, opt_height, opt_preview) { |
651 var oldScreenImage = this.screenImage_; | 615 var oldContentImage = this.contentImage_; |
652 var oldViewport = this.viewport_.clone(); | 616 var oldViewport = this.viewport_.clone(); |
653 this.replaceContent_(content, opt_width, opt_height, opt_preview); | 617 this.replaceContent_(newContentImage, opt_width, opt_height, opt_preview); |
654 if (!opt_effect) { | 618 if (!opt_effect) { |
655 if (oldScreenImage) | |
656 oldScreenImage.parentNode.removeChild(oldScreenImage); | |
657 return; | 619 return; |
658 } | 620 } |
659 | 621 |
660 assert(this.screenImage_); | 622 assert(this.contentImage_); |
661 var newScreenImage = this.screenImage_; | |
662 this.viewport_.resetView(); | 623 this.viewport_.resetView(); |
663 | 624 |
664 if (oldScreenImage) | 625 if (oldContentImage) |
665 ImageUtil.setAttribute(newScreenImage, 'fade', true); | 626 ImageUtil.setAttribute(newContentImage, 'fade', true); |
666 this.setTransform_( | 627 this.setTransform_( |
667 newScreenImage, this.viewport_, opt_effect, 0 /* instant */); | 628 newContentImage, this.viewport_, opt_effect, 0 /* instant */); |
668 this.setTransform_( | |
669 content, this.viewport_, opt_effect, 0 /* instant */); | |
670 | 629 |
671 // We need to call requestAnimationFrame twice here. The first call is for | 630 // We need to call requestAnimationFrame twice here. The first call is for |
672 // commiting the styles of beggining of transition that are assigned above. | 631 // 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 | 632 // The second call is for assigning and commiting the styles of end of |
674 // transition, which triggers transition animation. | 633 // transition, which triggers transition animation. |
675 requestAnimationFrame(function() { | 634 requestAnimationFrame(function() { |
676 requestAnimationFrame(function() { | 635 requestAnimationFrame(function() { |
677 this.setTransform_( | 636 this.setTransform_( |
678 newScreenImage, | 637 newContentImage, |
679 this.viewport_, | 638 this.viewport_, |
680 null, | 639 null, |
681 opt_effect ? opt_effect.getDuration() : undefined); | 640 opt_effect ? opt_effect.getDuration() : undefined); |
682 this.setTransform_( | 641 if (oldContentImage) { |
683 content, | 642 ImageUtil.setAttribute(newContentImage, 'fade', false); |
684 this.viewport_, | 643 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(); | 644 var reverse = opt_effect.getReverse(); |
691 if (reverse) { | 645 if (reverse) { |
692 this.setTransform_(oldScreenImage, oldViewport, reverse); | 646 this.setTransform_(oldContentImage, oldViewport, reverse); |
693 setTimeout(function() { | 647 setTimeout(function() { |
694 if (oldScreenImage.parentNode) | 648 if (oldContentImage.parentNode) |
695 oldScreenImage.parentNode.removeChild(oldScreenImage); | 649 oldContentImage.parentNode.removeChild(oldContentImage); |
696 }, reverse.getSafeInterval()); | 650 }, reverse.getSafeInterval()); |
697 } else { | 651 } else { |
698 if (oldScreenImage.parentNode) | 652 if (oldContentImage.parentNode) |
699 oldScreenImage.parentNode.removeChild(oldScreenImage); | 653 oldContentImage.parentNode.removeChild(oldContentImage); |
700 } | 654 } |
701 } | 655 } |
702 }.bind(this)); | 656 }.bind(this)); |
703 }.bind(this)); | 657 }.bind(this)); |
704 }; | 658 }; |
705 | 659 |
706 /** | 660 /** |
707 * @param {!HTMLCanvasElement|!HTMLImageElement} element The element to | 661 * @param {!HTMLCanvasElement|!HTMLImageElement} element The element to |
708 * transform. | 662 * transform. |
709 * @param {!Viewport} viewport Viewport to be used for calculating | 663 * @param {!Viewport} viewport Viewport to be used for calculating |
(...skipping 29 matching lines...) Expand all Loading... | |
739 * the new image to visualize the operation. | 693 * the new image to visualize the operation. |
740 * | 694 * |
741 * @param {!HTMLCanvasElement} canvas New content canvas. | 695 * @param {!HTMLCanvasElement} canvas New content canvas. |
742 * @param {ImageRect} imageCropRect The crop rectangle in image coordinates. | 696 * @param {ImageRect} imageCropRect The crop rectangle in image coordinates. |
743 * Null for rotation operations. | 697 * Null for rotation operations. |
744 * @param {number} rotate90 Rotation angle in 90 degree increments. | 698 * @param {number} rotate90 Rotation angle in 90 degree increments. |
745 * @return {number} Animation duration. | 699 * @return {number} Animation duration. |
746 */ | 700 */ |
747 ImageView.prototype.replaceAndAnimate = function( | 701 ImageView.prototype.replaceAndAnimate = function( |
748 canvas, imageCropRect, rotate90) { | 702 canvas, imageCropRect, rotate90) { |
749 assert(this.screenImage_); | 703 assert(this.contentImage_); |
750 | 704 |
751 var oldImageBounds = { | 705 var oldImageBounds = { |
752 width: this.viewport_.getImageBounds().width, | 706 width: this.viewport_.getImageBounds().width, |
753 height: this.viewport_.getImageBounds().height | 707 height: this.viewport_.getImageBounds().height |
754 }; | 708 }; |
755 var oldScreenImage = this.screenImage_; | 709 var oldScreenImage = this.contentImage_; |
756 this.replaceContent_(canvas); | 710 this.replaceContent_(canvas); |
757 var newScreenImage = this.screenImage_; | 711 var newScreenImage = this.contentImage_; |
758 var effect = rotate90 ? | 712 var effect = rotate90 ? |
759 new ImageView.Effect.Rotate(rotate90 > 0) : | 713 new ImageView.Effect.Rotate(rotate90 > 0) : |
760 new ImageView.Effect.Zoom( | 714 new ImageView.Effect.Zoom( |
761 oldImageBounds.width, oldImageBounds.height, assert(imageCropRect)); | 715 oldImageBounds.width, oldImageBounds.height, assert(imageCropRect)); |
762 | 716 |
763 this.setTransform_(newScreenImage, this.viewport_, effect, 0 /* instant */); | 717 this.setTransform_(newScreenImage, this.viewport_, effect, 0 /* instant */); |
764 | 718 |
765 oldScreenImage.parentNode.appendChild(newScreenImage); | |
766 oldScreenImage.parentNode.removeChild(oldScreenImage); | |
767 | |
768 // Let the layout fire, then animate back to non-transformed state. | 719 // Let the layout fire, then animate back to non-transformed state. |
769 setTimeout( | 720 setTimeout( |
770 this.setTransform_.bind( | 721 this.setTransform_.bind( |
771 this, newScreenImage, this.viewport_, null, effect.getDuration()), | 722 this, newScreenImage, this.viewport_, null, effect.getDuration()), |
772 0); | 723 0); |
773 | 724 |
774 return effect.getSafeInterval(); | 725 return effect.getSafeInterval(); |
775 }; | 726 }; |
776 | 727 |
777 /** | 728 /** |
778 * Visualizes "undo crop". Shrink the current image to the given crop rectangle | 729 * Visualizes "undo crop". Shrink the current image to the given crop rectangle |
779 * while fading in the new image. | 730 * while fading in the new image. |
780 * | 731 * |
781 * @param {!HTMLCanvasElement} canvas New content canvas. | 732 * @param {!HTMLCanvasElement} canvas New content canvas. |
782 * @param {!ImageRect} imageCropRect The crop rectangle in image coordinates. | 733 * @param {!ImageRect} imageCropRect The crop rectangle in image coordinates. |
783 * @return {number} Animation duration. | 734 * @return {number} Animation duration. |
784 */ | 735 */ |
785 ImageView.prototype.animateAndReplace = function(canvas, imageCropRect) { | 736 ImageView.prototype.animateAndReplace = function(canvas, imageCropRect) { |
786 var oldScreenImage = this.screenImage_; | 737 var oldScreenImage = assert(this.contentImage_); |
738 oldScreenImage.style.zIndex = 1000; | |
787 this.replaceContent_(canvas); | 739 this.replaceContent_(canvas); |
788 var newScreenImage = this.screenImage_; | 740 this.container_.appendChild(oldScreenImage); |
741 var newScreenImage = this.contentImage_; | |
789 var setFade = ImageUtil.setAttribute.bind(null, assert(newScreenImage), | 742 var setFade = ImageUtil.setAttribute.bind(null, assert(newScreenImage), |
790 'fade'); | 743 'fade'); |
791 setFade(true); | 744 setFade(true); |
792 oldScreenImage.parentNode.insertBefore(newScreenImage, oldScreenImage); | |
793 var effect = new ImageView.Effect.Zoom( | 745 var effect = new ImageView.Effect.Zoom( |
794 this.viewport_.getImageBounds().width, | 746 this.viewport_.getImageBounds().width, |
795 this.viewport_.getImageBounds().height, | 747 this.viewport_.getImageBounds().height, |
796 imageCropRect); | 748 imageCropRect); |
749 // Animate to the transformed state. | |
750 setTimeout(function() { | |
751 this.setTransform_(oldScreenImage, this.viewport_, effect); | |
752 }.bind(this)); | |
yawano
2016/01/21 05:14:38
nit: add 0 as second argument. We don't emit it.
ryoh
2016/01/21 07:28:53
Done.
| |
797 | 753 |
798 // Animate to the transformed state. | |
799 this.setTransform_(oldScreenImage, this.viewport_, effect); | |
800 setTimeout(setFade.bind(null, false), 0); | 754 setTimeout(setFade.bind(null, false), 0); |
755 | |
801 setTimeout(function() { | 756 setTimeout(function() { |
802 if (oldScreenImage.parentNode) | 757 if (oldScreenImage.parentNode) |
803 oldScreenImage.parentNode.removeChild(oldScreenImage); | 758 oldScreenImage.parentNode.removeChild(oldScreenImage); |
804 }, effect.getSafeInterval()); | 759 }, effect.getSafeInterval()); |
805 | 760 |
806 return effect.getSafeInterval(); | 761 return effect.getSafeInterval(); |
807 }; | 762 }; |
808 | 763 |
809 /* Transition effects */ | 764 /* Transition effects */ |
810 | 765 |
811 /** | 766 /** |
812 * Base class for effects. | 767 * Base class for effects. |
813 * | 768 * |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1015 | 970 |
1016 ImageView.Effect.Rotate.prototype = { __proto__: ImageView.Effect.prototype }; | 971 ImageView.Effect.Rotate.prototype = { __proto__: ImageView.Effect.prototype }; |
1017 | 972 |
1018 /** | 973 /** |
1019 * @override | 974 * @override |
1020 */ | 975 */ |
1021 ImageView.Effect.Rotate.prototype.transform = function(element, viewport) { | 976 ImageView.Effect.Rotate.prototype.transform = function(element, viewport) { |
1022 return viewport.getRotatingTransformation( | 977 return viewport.getRotatingTransformation( |
1023 element.width, element.height, this.orientation_ ? -1 : 1); | 978 element.width, element.height, this.orientation_ ? -1 : 1); |
1024 }; | 979 }; |
OLD | NEW |