PageRenderTime 28ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/skin/frontend/shopper/default/js/configurableswatches/product-media.js

https://bitbucket.org/maconeto/proman
JavaScript | 245 lines | 157 code | 44 blank | 44 comment | 29 complexity | 597755f86e200541f278c44680f273c9 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * Magento
  3. *
  4. * NOTICE OF LICENSE
  5. *
  6. * This source file is subject to the Academic Free License (AFL 3.0)
  7. * that is bundled with this package in the file LICENSE_AFL.txt.
  8. * It is also available through the world-wide-web at this URL:
  9. * http://opensource.org/licenses/afl-3.0.php
  10. * If you did not receive a copy of the license and are unable to
  11. * obtain it through the world-wide-web, please send an email
  12. * to license@magento.com so we can send you a copy immediately.
  13. *
  14. * DISCLAIMER
  15. *
  16. * Do not edit or add to this file if you wish to upgrade Magento to newer
  17. * versions in the future. If you wish to customize Magento for your
  18. * needs please refer to http://www.magento.com for more information.
  19. *
  20. * @category design
  21. * @package rwd_default
  22. * @copyright Copyright (c) 2006-2014 X.commerce, Inc. (http://www.magento.com)
  23. * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
  24. */
  25. var ConfigurableMediaImages = {
  26. imageType: null,
  27. swapHandler: null,
  28. productImages: {},
  29. imageObjects: {},
  30. arrayIntersect: function(a, b) {
  31. var ai=0, bi=0;
  32. var result = new Array();
  33. while( ai < a.length && bi < b.length )
  34. {
  35. if (a[ai] < b[bi] ){ ai++; }
  36. else if (a[ai] > b[bi] ){ bi++; }
  37. else /* they're equal */
  38. {
  39. result.push(a[ai]);
  40. ai++;
  41. bi++;
  42. }
  43. }
  44. return result;
  45. },
  46. getCompatibleProductImages: function(productFallback, selectedLabels) {
  47. //find compatible products
  48. var compatibleProducts = [];
  49. var compatibleProductSets = [];
  50. selectedLabels.each(function(selectedLabel) {
  51. if(!productFallback['option_labels'][selectedLabel]) {
  52. return;
  53. }
  54. var optionProducts = productFallback['option_labels'][selectedLabel]['products'];
  55. compatibleProductSets.push(optionProducts);
  56. //optimistically push all products
  57. optionProducts.each(function(productId) {
  58. compatibleProducts.push(productId);
  59. });
  60. });
  61. //intersect compatible products
  62. compatibleProductSets.each(function(productSet) {
  63. compatibleProducts = ConfigurableMediaImages.arrayIntersect(compatibleProducts, productSet);
  64. });
  65. return compatibleProducts;
  66. },
  67. isValidImage: function(fallbackImageUrl) {
  68. if(!fallbackImageUrl) {
  69. return false;
  70. }
  71. return true;
  72. },
  73. getSwatchImage: function(productId, optionLabel, selectedLabels, imageType) {
  74. if ( ! imageType)
  75. imageType = ConfigurableMediaImages.imageType;
  76. var fallback = ConfigurableMediaImages.productImages[productId];
  77. if(!fallback) {
  78. return null;
  79. }
  80. //first, try to get label-matching image on config product for this option's label
  81. var currentLabelImage = fallback['option_labels'][optionLabel];
  82. if(currentLabelImage && fallback['option_labels'][optionLabel]['configurable_product'][ConfigurableMediaImages.imageType]) {
  83. //found label image on configurable product
  84. return fallback['option_labels'][optionLabel]['configurable_product'][imageType];
  85. }
  86. var compatibleProducts = ConfigurableMediaImages.getCompatibleProductImages(fallback, selectedLabels);
  87. if(compatibleProducts.length == 0) { //no compatible products
  88. return null; //bail
  89. }
  90. //second, get any product which is compatible with currently selected option(s)
  91. jQuery.each(fallback['option_labels'], function(key, value) {
  92. var image = value['configurable_product'][imageType];
  93. var products = value['products'];
  94. if(image) { //configurable product has image in the first place
  95. //if intersection between compatible products and this label's products, we found a match
  96. var isCompatibleProduct = ConfigurableMediaImages.arrayIntersect(products, compatibleProducts).length > 0;
  97. if(isCompatibleProduct) {
  98. return image;
  99. }
  100. }
  101. });
  102. //third, get image off of child product which is compatible
  103. var childSwatchImage = null;
  104. var childProductImages = fallback[imageType];
  105. compatibleProducts.each(function(productId) {
  106. if(childProductImages[productId] && ConfigurableMediaImages.isValidImage(childProductImages[productId])) {
  107. childSwatchImage = childProductImages[productId];
  108. return false; //break "loop"
  109. }
  110. });
  111. if (childSwatchImage) {
  112. return childSwatchImage;
  113. }
  114. //fourth, get base image off parent product
  115. if (childProductImages[productId] && ConfigurableMediaImages.isValidImage(childProductImages[productId])) {
  116. return childProductImages[productId];
  117. }
  118. //no fallback image found
  119. return null;
  120. },
  121. getImageObject: function(productId, imageUrl) {
  122. var key = productId+'-'+imageUrl;
  123. if(!ConfigurableMediaImages.imageObjects[key]) {
  124. var image = jQuery('<img />');
  125. image.attr('src', imageUrl);
  126. ConfigurableMediaImages.imageObjects[key] = image;
  127. }
  128. return ConfigurableMediaImages.imageObjects[key];
  129. },
  130. updateImage: function(el) {
  131. var select = jQuery(el);
  132. var label = select.find('option:selected').attr('data-label');
  133. var productId = optionsPrice.productId; //get product ID from options price object
  134. //find all selected labels
  135. var selectedLabels = new Array();
  136. jQuery('.product-options .super-attribute-select').each(function() {
  137. var $option = jQuery(this);
  138. if($option.val() != '') {
  139. selectedLabels.push($option.find('option:selected').attr('data-label'));
  140. }
  141. });
  142. var swatchImageUrl = ConfigurableMediaImages.getSwatchImage(productId, label, selectedLabels, 'small_image');
  143. var zoomSwatchImageUrl = ConfigurableMediaImages.getSwatchImage(productId, label, selectedLabels, 'base_image');
  144. if(!ConfigurableMediaImages.isValidImage(swatchImageUrl) || !ConfigurableMediaImages.isValidImage(zoomSwatchImageUrl)) {
  145. return;
  146. }
  147. if (typeof this.swapHandler === 'function') {
  148. this.swapHandler.call(this, swatchImageUrl, zoomSwatchImageUrl);
  149. }
  150. },
  151. wireOptions: function() {
  152. jQuery('.product-options .super-attribute-select').change(function(e) {
  153. ConfigurableMediaImages.updateImage(this);
  154. });
  155. },
  156. swapListImage: function(productId, imageObject) {
  157. var originalImage = jQuery('#product-collection-image-' + productId),
  158. additionalImage = jQuery('#product-additional-image-' + productId);
  159. if(imageObject[0].complete) { //swap image immediately
  160. //remove additional image (if any)
  161. additionalImage.attr('src', imageObject[0].src).css({opacity: 1});
  162. // replace original image with new one
  163. originalImage.attr('src', imageObject[0].src).css({opacity: 1});
  164. // clear object
  165. delete imageObject;
  166. } else { //need to load image
  167. var wrapper = originalImage.parent();
  168. //add spinner
  169. wrapper.addClass('loading');
  170. //wait until image is loaded
  171. setTimeout(function() {
  172. //remove spinner
  173. wrapper.removeClass('loading');
  174. //remove additional image (if any)
  175. additionalImage.attr('src', imageObject[0].src).css({opacity: 1});
  176. // replace original image with new one
  177. originalImage.attr('src', imageObject[0].src).css({opacity: 1});
  178. // clear object
  179. delete imageObject;
  180. }, 250);
  181. }
  182. },
  183. swapListImageByOption: function(productId, optionLabel) {
  184. var swatchImageUrl = ConfigurableMediaImages.getSwatchImage(productId, optionLabel, [optionLabel]);
  185. if(!swatchImageUrl) {
  186. return;
  187. }
  188. var newImage = ConfigurableMediaImages.getImageObject(productId, swatchImageUrl);
  189. newImage.addClass('product-collection-image-' + productId);
  190. newImage.addClass('swatch_img');
  191. ConfigurableMediaImages.swapListImage(productId, newImage);
  192. },
  193. setImageFallback: function(productId, imageFallback) {
  194. ConfigurableMediaImages.productImages[productId] = imageFallback;
  195. },
  196. init: function(imageType, swapHandler) {
  197. ConfigurableMediaImages.imageType = imageType;
  198. ConfigurableMediaImages.swapHandler = swapHandler;
  199. ConfigurableMediaImages.wireOptions();
  200. }
  201. };