| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 * @constructor | 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 {MetadataCache} metadataCache The metadataCache. | 10 * @param {MetadataCache} metadataCache The metadataCache. |
| 11 * @constructor |
| 11 */ | 12 */ |
| 12 function ImageView(container, viewport, metadataCache) { | 13 function ImageView(container, viewport, metadataCache) { |
| 13 this.container_ = container; | 14 this.container_ = container; |
| 14 this.viewport_ = viewport; | 15 this.viewport_ = viewport; |
| 15 this.document_ = container.ownerDocument; | 16 this.document_ = container.ownerDocument; |
| 16 this.contentGeneration_ = 0; | 17 this.contentGeneration_ = 0; |
| 17 this.displayedContentGeneration_ = 0; | 18 this.displayedContentGeneration_ = 0; |
| 18 this.displayedViewportGeneration_ = 0; | 19 this.displayedViewportGeneration_ = 0; |
| 19 | 20 |
| 20 this.imageLoader_ = new ImageUtil.ImageLoader(this.document_); | 21 this.imageLoader_ = new ImageUtil.ImageLoader(this.document_); |
| 21 // We have a separate image loader for prefetch which does not get cancelled | 22 // We have a separate image loader for prefetch which does not get cancelled |
| 22 // when the selection changes. | 23 // when the selection changes. |
| 23 this.prefetchLoader_ = new ImageUtil.ImageLoader(this.document_); | 24 this.prefetchLoader_ = new ImageUtil.ImageLoader(this.document_); |
| 24 | 25 |
| 25 // The content cache is used for prefetching the next image when going | 26 // The content cache is used for prefetching the next image when going |
| 26 // through the images sequentially. The real life photos can be large | 27 // through the images sequentially. The real life photos can be large |
| 27 // (18Mpix = 72Mb pixel array) so we want only the minimum amount of caching. | 28 // (18Mpix = 72Mb pixel array) so we want only the minimum amount of caching. |
| 28 this.contentCache_ = new ImageView.Cache(2); | 29 this.contentCache_ = new ImageView.Cache(2); |
| 29 | 30 |
| 30 // We reuse previously generated screen-scale images so that going back to | 31 // We reuse previously generated screen-scale images so that going back to |
| 31 // a recently loaded image looks instant even if the image is not in | 32 // a recently loaded image looks instant even if the image is not in |
| 32 // the content cache any more. Screen-scale images are small (~1Mpix) | 33 // the content cache any more. Screen-scale images are small (~1Mpix) |
| 33 // so we can afford to cache more of them. | 34 // so we can afford to cache more of them. |
| 34 this.screenCache_ = new ImageView.Cache(5); | 35 this.screenCache_ = new ImageView.Cache(5); |
| 35 this.contentCallbacks_ = []; | 36 this.contentCallbacks_ = []; |
| 36 | 37 |
| 37 /** | 38 /** |
| 38 * The element displaying the current content. | 39 * The element displaying the current content. |
| 40 * |
| 39 * @type {HTMLCanvasElement|HTMLVideoElement} | 41 * @type {HTMLCanvasElement|HTMLVideoElement} |
| 42 * @private |
| 40 */ | 43 */ |
| 41 this.screenImage_ = null; | 44 this.screenImage_ = null; |
| 42 | 45 |
| 43 this.localImageTransformFetcher_ = function(url, callback) { | 46 this.localImageTransformFetcher_ = function(url, callback) { |
| 44 metadataCache.get(url, 'fetchedMedia', function(fetchedMedia) { | 47 metadataCache.get(url, 'fetchedMedia', function(fetchedMedia) { |
| 45 callback(fetchedMedia.imageTransform); | 48 callback(fetchedMedia.imageTransform); |
| 46 }); | 49 }); |
| 47 }; | 50 }; |
| 48 } | 51 } |
| 49 | 52 |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 oldScreenImage.parentNode.removeChild(oldScreenImage); | 766 oldScreenImage.parentNode.removeChild(oldScreenImage); |
| 764 }, effect.getSafeInterval()); | 767 }, effect.getSafeInterval()); |
| 765 | 768 |
| 766 return effect.getSafeInterval(); | 769 return effect.getSafeInterval(); |
| 767 }; | 770 }; |
| 768 | 771 |
| 769 | 772 |
| 770 /** | 773 /** |
| 771 * Generic cache with a limited capacity and LRU eviction. | 774 * Generic cache with a limited capacity and LRU eviction. |
| 772 * | 775 * |
| 776 * @param {number} capacity Maximum number of cached item. |
| 773 * @constructor | 777 * @constructor |
| 774 * @param {number} capacity Maximum number of cached item. | |
| 775 */ | 778 */ |
| 776 ImageView.Cache = function(capacity) { | 779 ImageView.Cache = function(capacity) { |
| 777 this.capacity_ = capacity; | 780 this.capacity_ = capacity; |
| 778 this.map_ = {}; | 781 this.map_ = {}; |
| 779 this.order_ = []; | 782 this.order_ = []; |
| 780 }; | 783 }; |
| 781 | 784 |
| 782 /** | 785 /** |
| 783 * Fetch the item from the cache. | 786 * Fetch the item from the cache. |
| 784 * | 787 * |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 if (pos < 0) | 846 if (pos < 0) |
| 844 return; // Not cached. | 847 return; // Not cached. |
| 845 | 848 |
| 846 this.order_[pos] = newId; | 849 this.order_[pos] = newId; |
| 847 this.map_[newId] = this.map_[oldId]; | 850 this.map_[newId] = this.map_[oldId]; |
| 848 delete this.map_[oldId]; | 851 delete this.map_[oldId]; |
| 849 }; | 852 }; |
| 850 | 853 |
| 851 /** | 854 /** |
| 852 * Disposes an object. | 855 * Disposes an object. |
| 856 * |
| 853 * @param {object} item The item object. | 857 * @param {object} item The item object. |
| 854 * @private | 858 * @private |
| 855 */ | 859 */ |
| 856 ImageView.Cache.prototype.deleteItem_ = function(item) { | 860 ImageView.Cache.prototype.deleteItem_ = function(item) { |
| 857 // Trick to reduce memory usage without waiting for gc. | 861 // Trick to reduce memory usage without waiting for gc. |
| 858 if (item instanceof HTMLCanvasElement) { | 862 if (item instanceof HTMLCanvasElement) { |
| 859 // If the canvas is being used somewhere else (eg. displayed on the screen), | 863 // If the canvas is being used somewhere else (eg. displayed on the screen), |
| 860 // it will be cleared. | 864 // it will be cleared. |
| 861 item.width = 0; | 865 item.width = 0; |
| 862 item.height = 0; | 866 item.height = 0; |
| 863 } | 867 } |
| 864 }; | 868 }; |
| 865 | 869 |
| 866 /* Transition effects */ | 870 /* Transition effects */ |
| 867 | 871 |
| 868 /** | 872 /** |
| 869 * Base class for effects. | 873 * Base class for effects. |
| 874 * |
| 870 * @param {number} duration Duration in ms. | 875 * @param {number} duration Duration in ms. |
| 871 * @param {string} opt_timing CSS transition timing function name. | 876 * @param {string} opt_timing CSS transition timing function name. |
| 872 * @constructor | 877 * @constructor |
| 873 */ | 878 */ |
| 874 ImageView.Effect = function(duration, opt_timing) { | 879 ImageView.Effect = function(duration, opt_timing) { |
| 875 this.duration_ = duration; | 880 this.duration_ = duration; |
| 876 this.timing_ = opt_timing || 'linear'; | 881 this.timing_ = opt_timing || 'linear'; |
| 877 }; | 882 }; |
| 878 | 883 |
| 879 /** | 884 /** |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1045 | 1050 |
| 1046 /** | 1051 /** |
| 1047 * @param {HTMLCanvasElement|HTMLVideoElement} element Element. | 1052 * @param {HTMLCanvasElement|HTMLVideoElement} element Element. |
| 1048 * @return {string} Transform string. | 1053 * @return {string} Transform string. |
| 1049 */ | 1054 */ |
| 1050 ImageView.Effect.Rotate.prototype.transform = function(element) { | 1055 ImageView.Effect.Rotate.prototype.transform = function(element) { |
| 1051 var ratio = ImageView.Effect.getPixelRatio_(element); | 1056 var ratio = ImageView.Effect.getPixelRatio_(element); |
| 1052 return 'rotate(' + (this.rotate90_ * 90) + 'deg) ' + | 1057 return 'rotate(' + (this.rotate90_ * 90) + 'deg) ' + |
| 1053 'scale(' + (this.scale_ / ratio) + ')'; | 1058 'scale(' + (this.scale_ / ratio) + ')'; |
| 1054 }; | 1059 }; |
| OLD | NEW |