// VERSION: 2.3 LAST UPDATE: 11.07.2013/**LicensedundertheMITlicense:http://www.opensource.org/licenses/mit-license.php**MadebyWilq32,wilq32@gmail.com,Wroclaw,Poland,01.2009*Website:http://jqueryrotate.com*/(function($) { var supportedCSS,supportedCSSOrigin, styles=document.getElementsByTagName("head")[0].style,toCheck="transformProperty WebkitTransform OTransform msTransform MozTransform".split(" "); for (var a = 0; a < toCheck.length; a++) if (styles[toCheck[a]] !== undefined) { supportedCSS = toCheck[a]; } if (supportedCSS) { supportedCSSOrigin = supportedCSS.replace(/[tT]ransform/,"TransformOrigin");if(supportedCSSOrigin[0]=="T")supportedCSSOrigin[0]="t";}// Bad eval to preven google closure to remove it from code o_Oeval('IE = "v"=="\v"');jQuery.fn.extend({rotate:function(parameters){if(this.length===0||typeofparameters=="undefined")return;if(typeofparameters=="number")parameters={angle:parameters};varreturned=[];for(vari=0,i0=this.length;i<i0;i++){varelement=this.get(i);if(!element.Wilq32||!element.Wilq32.PhotoEffect){varparamClone=$.extend(true,{},parameters);varnewRotObject=newWilq32.PhotoEffect(element,paramClone)._rootObj;returned.push($(newRotObject));}else{element.Wilq32.PhotoEffect._handleRotation(parameters);}}returnreturned;},getRotateAngle:function(){varret=[0];for(vari=0,i0=this.length;i<i0;i++){varelement=this.get(i);if(element.Wilq32&&element.Wilq32.PhotoEffect){ret[i]=element.Wilq32.PhotoEffect._angle;}}returnret;},stopRotate:function(){for(vari=0,i0=this.length;i<i0;i++){varelement=this.get(i);if(element.Wilq32&&element.Wilq32.PhotoEffect){clearTimeout(element.Wilq32.PhotoEffect._timer);}}}});// Library agnostic interfaceWilq32=window.Wilq32||{};Wilq32.PhotoEffect=(function(){if(supportedCSS){returnfunction(img,parameters){img.Wilq32={PhotoEffect:this};this._img=this._rootObj=this._eventObj=img;this._handleRotation(parameters);}}else{returnfunction(img,parameters){this._img=img;this._onLoadDelegate=[parameters];this._rootObj=document.createElement('span');this._rootObj.style.display="inline-block";this._rootObj.Wilq32={PhotoEffect:this};img.parentNode.insertBefore(this._rootObj,img);if(img.complete){this._Loader();}else{varself=this;// TODO: Remove jQuery dependencyjQuery(this._img).bind("load",function(){self._Loader();});}}}})();Wilq32.PhotoEffect.prototype={_setupParameters:function(parameters){this._parameters=this._parameters||{};if(typeofthis._angle!=="number"){this._angle=0;}if(typeofparameters.angle==="number"){this._angle=parameters.angle;}this._parameters.animateTo=(typeofparameters.animateTo==="number")?(parameters.animateTo):(this._angle);this._parameters.step=parameters.step||this._parameters.step||null;this._parameters.easing=parameters.easing||this._parameters.easing||this._defaultEasing;this._parameters.duration='duration'inparameters?parameters.duration:parameters.duration||this._parameters.duration||1000;this._parameters.callback=parameters.callback||this._parameters.callback||this._emptyFunction;this._parameters.center=parameters.center||this._parameters.center||["50%","50%"];if(typeofthis._parameters.center[0]=="string"){this._rotationCenterX=(parseInt(this._parameters.center[0],10)/100)*this._imgWidth*this._aspectW;}else{this._rotationCenterX=this._parameters.center[0];}if(typeofthis._parameters.center[1]=="string"){this._rotationCenterY=(parseInt(this._parameters.center[1],10)/100)*this._imgHeight*this._aspectH;}else{this._rotationCenterY=this._parameters.center[1];}if(parameters.bind&¶meters.bind!=this._parameters.bind){this._BindEvents(parameters.bind);}},_emptyFunction:function(){},_defaultEasing:function(x,t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b},_handleRotation:function(parameters,dontcheck){if(!supportedCSS&&!this._img.complete&&!dontcheck){this._onLoadDelegate.push(parameters);return;}this._setupParameters(parameters);if(this._angle==this._parameters.animateTo){this._rotate(this._angle);}else{this._animateStart();}},_BindEvents:function(events){if(events&&this._eventObj){// Unbinding previous Eventsif(this._parameters.bind){varoldEvents=this._parameters.bind;for(varainoldEvents)if(oldEvents.hasOwnProperty(a))// TODO: Remove jQuery dependencyjQuery(this._eventObj).unbind(a,oldEvents[a]);}this._parameters.bind=events;for(varainevents)if(events.hasOwnProperty(a))// TODO: Remove jQuery dependencyjQuery(this._eventObj).bind(a,events[a]);}},_Loader:(function(){if(IE)returnfunction(){varwidth=this._img.width;varheight=this._img.height;this._imgWidth=width;this._imgHeight=height;this._img.parentNode.removeChild(this._img);this._vimage=this.createVMLNode('image');this._vimage.src=this._img.src;this._vimage.style.height=height+"px";this._vimage.style.width=width+"px";this._vimage.style.position="absolute";// FIXES IE PROBLEM - its only rendered if its on absolute position!this._vimage.style.top="0px";this._vimage.style.left="0px";this._aspectW=this._aspectH=1;/* Group minifying a small 1px precision problem when rotating object */this._container=this.createVMLNode('group');this._container.style.width=width;this._container.style.height=height;this._container.style.position="absolute";this._container.style.top="0px";this._container.style.left="0px";this._container.setAttribute('coordsize',width-1+','+(height-1));// This -1, -1 trying to fix ugly problem with small displacement on IEthis._container.appendChild(this._vimage);this._rootObj.appendChild(this._container);this._rootObj.style.position="relative";// FIXES IE PROBLEMthis._rootObj.style.width=width+"px";this._rootObj.style.height=height+"px";this._rootObj.setAttribute('id',this._img.getAttribute('id'));this._rootObj.className=this._img.className;this._eventObj=this._rootObj;varparameters;while(parameters=this._onLoadDelegate.shift()){this._handleRotation(parameters,true);}}elsereturnfunction(){this._rootObj.setAttribute('id',this._img.getAttribute('id'));this._rootObj.className=this._img.className;this._imgWidth=this._img.naturalWidth;this._imgHeight=this._img.naturalHeight;var_widthMax=Math.sqrt((this._imgHeight)*(this._imgHeight)+(this._imgWidth)*(this._imgWidth));this._width=_widthMax*3;this._height=_widthMax*3;this._aspectW=this._img.offsetWidth/this._img.naturalWidth;this._aspectH=this._img.offsetHeight/this._img.naturalHeight;this._img.parentNode.removeChild(this._img);this._canvas=document.createElement('canvas');this._canvas.setAttribute('width',this._width);this._canvas.style.position="relative";this._canvas.style.left=-this._img.height*this._aspectW+"px";this._canvas.style.top=-this._img.width*this._aspectH+"px";this._canvas.Wilq32=this._rootObj.Wilq32;this._rootObj.appendChild(this._canvas);this._rootObj.style.width=this._img.width*this._aspectW+"px";this._rootObj.style.height=this._img.height*this._aspectH+"px";this._eventObj=this._canvas;this._cnv=this._canvas.getContext('2d');varparameters;while(parameters=this._onLoadDelegate.shift()){this._handleRotation(parameters,true);}}})(),_animateStart:function(){if(this._timer){clearTimeout(this._timer);}this._animateStartTime=+newDate;this._animateStartAngle=this._angle;this._animate();},_animate:function(){varactualTime=+newDate;varcheckEnd=actualTime-this._animateStartTime>this._parameters.duration;// TODO: Bug for animatedGif for static rotation ? (to test)if(checkEnd&&!this._parameters.animatedGif){clearTimeout(this._timer);}else{if(this._canvas||this._vimage||this._img){varangle=this._parameters.easing(0,actualTime-this._animateStartTime,this._animateStartAngle,this._parameters.animateTo-this._animateStartAngle,this._parameters.duration);this._rotate((~~(angle*10))/10);}if(this._parameters.step){this._parameters.step(this._angle);}varself=this;this._timer=setTimeout(function(){self._animate.call(self);},10);}// To fix Bug that prevents using recursive function in callback I moved this function to backif(this._parameters.callback&&checkEnd){this._angle=this._parameters.animateTo;this._rotate(this._angle);this._parameters.callback.call(this._rootObj);}},_rotate:(function(){varrad=Math.PI/180;if(IE)returnfunction(angle){this._angle=angle;this._container.style.rotation=(angle%360)+"deg";this._vimage.style.top=-(this._rotationCenterY-this._imgHeight/2)+"px";this._vimage.style.left=-(this._rotationCenterX-this._imgWidth/2)+"px";this._container.style.top=this._rotationCenterY-this._imgHeight/2+"px";this._container.style.left=this._rotationCenterX-this._imgWidth/2+"px";}elseif(supportedCSS)returnfunction(angle){this._angle=angle;this._img.style[supportedCSS]="rotate("+(angle%360)+"deg)";this._img.style[supportedCSSOrigin]=this._parameters.center.join(" ");}elsereturnfunction(angle){this._angle=angle;angle=(angle%360)*rad;// clear canvasthis._canvas.width=this._width;//+this._widthAdd;this._canvas.height=this._height;//+this._heightAdd;// REMEMBER: all drawings are read from backwards.. so first function is translate, then rotate, then translate, translate..this._cnv.translate(this._imgWidth*this._aspectW,this._imgHeight*this._aspectH);// at least center image on screenthis._cnv.translate(this._rotationCenterX,this._rotationCenterY);// we move image back to its orginalthis._cnv.rotate(angle);// rotate imagethis._cnv.translate(-this._rotationCenterX,-this._rotationCenterY);// move image to its center, so we can rotate around its centerthis._cnv.scale(this._aspectW,this._aspectH);// SCALE - if needed ;)this._cnv.drawImage(this._img,0,0);// First - we draw image}})()}if(IE){Wilq32.PhotoEffect.prototype.createVMLNode=(function(){document.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!document.namespaces.rvml&&document.namespaces.add("rvml","urn:schemas-microsoft-com:vml");returnfunction(tagName){returndocument.createElement('<rvml:'+tagName+' class="rvml">');};}catch(e){returnfunction(tagName){returndocument.createElement('<'+tagName+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');};}})();}})(jQuery);