/*! jQThumb V1.9.3 Copyright (c) 2013-2014 Dual licensed under the MIT and GPL licenses. Author : Pak Cheong Version : 1.9.3 Repo : https://github.com/pakcheong/jqthumb Demo : http://pakcheong.github.io/jqthumb/ Last Updated : Thursday, July 10th, 2014, 4:32:44 PM Requirements : jQuery >=v1.3.0 or Zepto (with zepto-data plugin) >=v1.0.0 */ ;(function ( $, window, document, undefined ) { var pluginName = "jqthumb", grandGlobal = { outputElems: [], inputElems: [] }, defaults = { classname : 'jqthumb', width : 100, height : 100, position : { top: '50%', left: '50%' }, source : 'src', showoncomplete : true, before : function(){}, after : function(){}, done : function(){} }; function Plugin ( element, options ) {// The actual plugin constructor this.element = element; this.settings = $.extend( {}, defaults, options ); this.settings.width = this.settings.width.toString().replace(/px/g, ''); this.settings.height = this.settings.height.toString().replace(/px/g, ''); this.settings.position.top = this.settings.position.top.toString().replace(/px/g, ''); this.settings.position.left = this.settings.position.left.toString().replace(/px/g, ''); this._defaults = defaults; this._name = pluginName; if(typeof options == 'string'){ if(options.toLowerCase() == 'kill'){ this.kill(this.element); } }else{ this.init(); } } Plugin.prototype = { init: function () { if(this.support_css3_attr('backgroundSize') === false){ // old browsers need to do calculation to perform same output like "background-size: cover" this.nonCss3Supported_method(this.element, this.settings); }else{ // modern browsers that support CSS3 would be easier this.css3Supported_method(this.element, this.settings); } }, kill: function(_this){ if( $(_this).data(pluginName)){ if($(_this).prev().data(pluginName) !== pluginName){ console.error('We could not find the element created by jqthumb. It is probably due to one or more element has been added right before the image element after the plugin initialization, or it was removed.'); return false; } /* START: remove output elements */ var tempArr = []; $.each(grandGlobal.outputElems, function(index, obj){ if($(obj)[0] == $(_this).prev()[0]){ }else{ tempArr.push(grandGlobal.outputElems[index]); } }); grandGlobal.outputElems = tempArr; /* END: remove output elements */ /* START: remove input elements */ tempArr = []; $.each(grandGlobal.inputElems, function(index, obj){ if($(obj)[0] == $(_this)[0]){ }else{ tempArr.push(grandGlobal.inputElems[index]); } }); grandGlobal.inputElems = tempArr; /* END: remove input elements */ $(_this).prev().remove(); $(_this).removeAttr('style'); // first, remove all the styles first if(typeof $(_this).data(pluginName + '-original-styles') !== 'undefined'){ $(_this).attr('style', $(_this).data(pluginName + '-original-styles')); // then re-store the original styles } if(typeof $(_this).data(pluginName + '-original-styles') !== 'undefined'){ $(_this).removeData(pluginName + '-original-styles'); // remove data that stores the original stylings before the image being rendered } if(typeof $(_this).data(pluginName) !== 'undefined'){ $(_this).removeData(pluginName); // remove data that stored during plugin initialization } } }, nonCss3Supported_method: function(_this, options){ options.before.call(_this, _this); var that = this, $this = $(_this); $this.data(pluginName + '-original-styles', $this.attr('style')); // keep original styles into data $this.hide(); var $tempImg = $(""); $tempImg.bind('load', function(){ var newImg = { obj: $tempImg, size: { width: this.width, height: this.height } }, pw = that.percentOrPixel(options.width), ph = that.percentOrPixel(options.height), imgContainer = $('
'), ratio = 0; $(imgContainer) .insertBefore($this) .append($(newImg.obj)) .css({ 'position' : 'relative', 'overflow' : 'hidden', 'width' : (pw == '%') ? options.width : options.width + 'px', 'height' : (ph == '%') ? options.height : options.height + 'px' }) .data(pluginName, pluginName); // it would be easy to kill later if(newImg.size.width > newImg.size.height){ // horizontal $(newImg.obj).css({ 'width' : 'auto', 'max-height' : 99999999, 'min-height' : 0, 'max-width' : 99999999, 'min-width' : 0, 'height' : $(newImg.obj).parent().height() + 'px' }); ratio = $(newImg.obj).height() / $(newImg.obj).width(); // get ratio if( $(newImg.obj).width() < $(newImg.obj).parent().width() ){ $(newImg.obj).css({ 'width': $(newImg.obj).parent().width(), 'height': parseFloat($(newImg.obj).parent().width() * ratio) }); } }else{ // vertical $(newImg.obj).css({ 'width' : $(newImg.obj).parent().width() + 'px', 'max-height' : 99999999, 'min-height' : 0, 'max-width' : 99999999, 'min-width' : 0, 'height' : 'auto' }); ratio = $(newImg.obj).width() / $(newImg.obj).height(); // get ratio if( $(newImg.obj).height() < $(newImg.obj).parent().height() ){ $(newImg.obj).css({ 'width': parseFloat($(newImg.obj).parent().height() * ratio), 'height': $(newImg.obj).parent().height() }); } } posTop = (that.percentOrPixel(options.position.top) == '%') ? options.position.top : options.position.top + 'px'; posLeft = (that.percentOrPixel(options.position.left) == '%') ? options.position.left : options.position.left + 'px'; $(newImg.obj).css({ 'position' : 'absolute', 'top' : posTop, 'margin-top' : (function(){ if(that.percentOrPixel(options.position.top) == '%'){ return '-' + parseFloat(($(newImg.obj).height() / 100) * options.position.top.slice(0,-1)) + 'px'; } })(), 'left' : posLeft, 'margin-left' : (function(){ if(that.percentOrPixel(options.position.left) == '%'){ return '-' + parseFloat(($(newImg.obj).width() / 100) * options.position.left.slice(0,-1)) + 'px'; } })() }); $(imgContainer) .hide() .addClass(options.classname); if(options.showoncomplete === true){ $(imgContainer).show(); } options.after.call(_this, $(imgContainer)); that.updateGlobal(_this, $(imgContainer), options); }).attr("src", $this.attr(options.source)); // for older browsers, must bind events first then set attr later (IE7, IE8) }, css3Supported_method: function (_this, options) { options.before.call(_this, _this); var that = this, $oriImage = $(_this), $tempImg = $('').attr('src', $oriImage.attr(options.source)); $oriImage.data(pluginName + '-original-styles', $oriImage.attr('style')); // keep original styles into data $oriImage.hide(); $.each($tempImg, function(index, obj){ var $tempImg = $(obj); $tempImg.one('load', function() { var pw = that.percentOrPixel(options.width), ph = that.percentOrPixel(options.height), featuredBgImgContainer = null, featuredBgImg = null; featuredBgImgContainer = $('') .css({ 'width' : (pw == '%') ? options.width : options.width + 'px', 'height' : (ph == '%') ? options.height : options.height + 'px', 'display' : 'none' }) .addClass(options.classname) .data(pluginName, pluginName); // it would be easy to kill later featuredBgImg = $('').css({ 'width' : '100%', 'height' : '100%', 'background-image' : 'url("' + $oriImage.attr(options.source) + '")', // '-ms-filter' : '"progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + $oriImage.attr(options.source) + '",sizingMethod="scale")', // this does not work in Zepto 'background-repeat' : 'no-repeat', 'background-position': (function(){ var posTop = (that.percentOrPixel(options.position.top) == '%') ? options.position.top : options.position.top + 'px', posLeft = (that.percentOrPixel(options.position.left) == '%') ? options.position.left : options.position.left + 'px'; return posTop + ' ' + posLeft; })(), 'background-size' : 'cover' }) .appendTo($(featuredBgImgContainer)); $(featuredBgImgContainer).insertBefore($(_this)); if(options.showoncomplete === true){ $(featuredBgImgContainer).show(); } that.checkSrcAttrName(_this, options); options.after.call(_this, $(featuredBgImgContainer)); that.updateGlobal(_this, $(featuredBgImgContainer), options); }); }); }, updateGlobal: function(_this, obj, options){ _this.global.outputElems.push( $(obj)[0] ); _this.global.elemCounter++; grandGlobal.outputElems.push( $(obj)[0] ); if(_this.global.elemCounter == _this.global.inputElems.length){ options.done.call(_this, _this.global.outputElems); } }, checkSrcAttrName: function(_this, options){ if( options.source != 'src' && ( typeof $(_this).attr('src') === 'undefined' || $(_this).attr('src') === '' ) ) { $(_this).attr('src', $(_this).attr(options.source)); } }, percentOrPixel: function(str){ str = str.toString(); if(str.match("px$") || str.match("PX$") || str.match("pX$") || str.match("Px$")) { return 'px'; }else if(str.match("%$")) { return '%'; } }, support_css3_attr: (function() { /* code available at http://net.tutsplus.com/tutorials/html-css-techniques/quick-tip-detect-css-support-in-browsers-with-javascript/ */ var div = document.createElement('div'), vendors = 'Khtml Ms O Moz Webkit'.split(' '), len = vendors.length; return function(prop) { if ( prop in div.style ) return true; prop = prop.replace(/^[a-z]/, function(val) { return val.toUpperCase(); }); for(i=0; i