Advertisement
Guest User

Untitled

a guest
May 21st, 2013
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * jFlip plugin for jQuery v0.4 (28/2/2009)
  3.  *
  4.  * A plugin to make a page flipping gallery    
  5.  *
  6.  * Copyright (c) 2008-2009 Renato Formato (rformato@gmail.com)
  7.  * Dual licensed under the MIT (MIT-LICENSE.txt)
  8.  * and GPL (GPL-LICENSE.txt) licenses.
  9.  *    
  10.  */
  11. ;(function($){
  12.     var Flip = function(canvas,width,height,images,opts) {
  13.       //private vars
  14.       opts = $.extend({background:"green",cornersTop:true,scale:"noresize"},opts);
  15.       var obj = this,
  16.       el = canvas.prev(),
  17.       index = 0,
  18.       init = false,
  19.       background = opts.background,
  20.       cornersTop = opts.cornersTop,
  21.       gradientColors = opts.gradientColors || ['#4F2727','#FF8F8F','#F00'],
  22.       curlSize = opts.curlSize || 0.1,
  23.       scale = opts.scale,
  24.       patterns = [],
  25.       canvas2 = canvas.clone(),
  26.       ctx2 = $.browser.msie?null:canvas2[0].getContext("2d"),
  27.       canvas = $.browser.msie?$(G_vmlCanvasManager.initElement(canvas[0])):canvas,
  28.       ctx = canvas[0].getContext("2d"),
  29.       loaded = 0;
  30.       var images = images.each(function(i){
  31.         if(patterns[i]) return;
  32.         var img = this;
  33.         img.onload = function() {
  34.           var r = 1;
  35.           if(scale!="noresize") {
  36.             var rx = width/this.width,
  37.             ry = height/this.height;
  38.             if(scale=="fit")
  39.               r = (rx<1 || ry<1)?Math.min(rx,ry):1;
  40.             if(scale=="fill") {
  41.               r = Math.min(rx,ry);
  42.             }
  43.           };
  44.           $(img).data("flip.scale",r);
  45.           patterns[i] = ctx.createPattern(img,"no-repeat");
  46.           loaded++;
  47.           if(loaded==images.length && !init) {
  48.             init = true;
  49.             draw();
  50.           }
  51.         };
  52.         if(img.complete)
  53.           window.setTimeout(function(){img.onload()},10);
  54.       }).get();
  55.       var
  56.         width = width,height = height,mX = width,mY = height,
  57.         basemX = mX*(1-curlSize), basemY = mY*curlSize,sideLeft = false,
  58.         off = $.browser.msie?canvas.offset():null,
  59.         onCorner = false,
  60.         curlDuration=400,curling = false,
  61.         animationTimer,startDate,
  62.         flipDuration=700,flipping = false,baseFlipX,baseFlipY,
  63.         lastmX,lastmY,
  64.         inCanvas = false,
  65.         mousedown = false,
  66.         dragging = false;
  67.      
  68.       $(window).scroll(function(){
  69.               //off = canvas.offset(); //update offset on scroll
  70.       });
  71.      
  72.       //IE can't handle correctly mouseenter and mouseleave on VML
  73.       var c = $.browser.msie?(function(){
  74.           var div = $("<div>").width(width).height(height).css({position:"absolute",cursor:"default",zIndex:1}).appendTo("body");
  75.           //second hack for IE7 that can't handle correctly mouseenter and mouseleave if the div has no background color
  76.           if(parseInt($.browser.version)==7)
  77.             div.css({opacity:0.000001,background:"#FFF"});
  78.           var positionDiv = function() {
  79.             off = canvas.offset();
  80.             return div.css({left:off.left+'px',top:off.top+'px'});
  81.           }
  82.           $(window).resize(positionDiv);
  83.           return positionDiv();
  84.       })():canvas;
  85.       c.mousemove(function(e){
  86.         //track the mouse
  87.         /*
  88.         if(!off) off = canvas.offset(); //safari can't calculate correctly offset at DOM ready
  89.         mX = e.clientX-off.left;
  90.         mY = e.clientY-off.top;
  91.         window.setTimeout(draw,0);
  92.         return;
  93.         */
  94.         if(!off)
  95.           off = canvas.offset(); //safari can't calculate correctly offset at DOM ready
  96.        
  97.         if(mousedown && onCorner) {
  98.           if(!dragging) {
  99.             dragging = true;
  100.             window.clearInterval(animationTimer);
  101.           }
  102.           mX = !sideLeft?e.pageX-off.left:width-(e.pageX-off.left);
  103.           mY = cornersTop?e.pageY-off.top:height-(e.pageY-off.top);
  104.           window.setTimeout(draw,0);
  105.           return false;        
  106.         }
  107.        
  108.         lastmX = e.pageX||lastmX, lastmY = e.pageY||lastmY;
  109.         if(!flipping) {
  110.           sideLeft = (lastmX-off.left)<width/2;
  111.           //cornersTop = (lastmY-off.top)<height/2;
  112.         }
  113.         if(!flipping &&
  114.           ((lastmX-off.left)>basemX || (lastmX-off.left)<(width-basemX)) &&
  115.           ((cornersTop && (lastmY-off.top)<basemY) || (!cornersTop && (lastmY-off.top)>(height-basemY)))) {
  116.           if(!onCorner) {
  117.             onCorner= true;
  118.             c.css("cursor","pointer");          
  119.           }
  120.         } else {
  121.           if(onCorner) {
  122.             onCorner= false;
  123.             c.css("cursor","default");
  124.           }
  125.         };
  126.         return false;
  127.       }).bind("mouseenter",function(e){
  128.         inCanvas = true;
  129.         if(flipping) return;
  130.         window.clearInterval(animationTimer);
  131.         startDate = new Date().getTime();
  132.         animationTimer = window.setInterval(cornerCurlIn,10);
  133.         return false;
  134.       }).bind("mouseleave",function(e){
  135.         inCanvas = false;
  136.         dragging = false;
  137.         mousedown = false;
  138.         if(flipping) return;
  139.         window.clearInterval(animationTimer);
  140.         startDate = new Date().getTime();
  141.         animationTimer = window.setInterval(cornerCurlOut,10);
  142.         return false;
  143.       }).click(function(){
  144.         if(onCorner && !flipping) {
  145.           flipping = true;
  146.           c.triggerHandler("mousemove");
  147.           window.clearInterval(animationTimer);
  148.           startDate = new Date().getTime();
  149.           baseFlipX = mX;
  150.           baseFlipY = mY;
  151.           animationTimer = window.setInterval(flip,10);
  152.           index += sideLeft?-1:1;
  153.           if(index<0) index = images.length-1;
  154.           if(index==images.length) index = 0;
  155.           el.trigger("flip.jflip",[index,images.length]);
  156.         }
  157.         return false;
  158.       }).mousedown(function(){
  159.         dragging = false;
  160.         mousedown = true;
  161.         return false;
  162.       }).mouseup(function(){
  163.         mousedown = false;
  164.         return false;
  165.       });
  166.      
  167.       var flip = function() {
  168.         var date = new Date(),delta = date.getTime()-startDate;
  169.         if(delta>=flipDuration) {
  170.           window.clearInterval(animationTimer);
  171.           if(sideLeft) {
  172.             images.unshift(images.pop());
  173.             patterns.unshift(patterns.pop());
  174.           } else {
  175.             images.push(images.shift());
  176.             patterns.push(patterns.shift());          
  177.           }
  178.           mX = width;
  179.           mY = height;
  180.           draw();
  181.           flipping = false;
  182.           //init corner move if still in Canvas
  183.           if(inCanvas) {
  184.             startDate = new Date().getTime();
  185.             animationTimer = window.setInterval(cornerCurlIn,10);
  186.             c.triggerHandler("mousemove");
  187.           }
  188.           return;
  189.         }
  190.         //da mX a -width  (mX+width) in duration millisecondi
  191.         mX = baseFlipX-2*(width)*delta/flipDuration;
  192.         mY = baseFlipY+2*(height)*delta/flipDuration;
  193.         draw();
  194.       },
  195.       cornerMove =  function() {
  196.         var date = new Date(),delta = date.getTime()-startDate;
  197.        
  198.         mX = basemX+Math.sin(Math.PI*2*delta/1000);
  199.         mY = basemY+Math.cos(Math.PI*2*delta/1000);
  200.         drawing = true;
  201.         window.setTimeout(draw,0);
  202.       },
  203.       cornerCurlIn = function() {
  204.         var date = new Date(),delta = date.getTime()-startDate;
  205.         if(delta>=curlDuration) {
  206.           window.clearInterval(animationTimer);
  207.           startDate = new Date().getTime();
  208.           animationTimer = window.setInterval(cornerMove,10);        
  209.         }      
  210.         mX = width-(width-basemX)*delta/curlDuration;
  211.         mY = basemY*delta/curlDuration;
  212.         draw();    
  213.       },
  214.       cornerCurlOut = function() {
  215.         var date = new Date(),delta = date.getTime()-startDate;
  216.         if(delta>=curlDuration) {
  217.           window.clearInterval(animationTimer);
  218.         }      
  219.         mX = basemX+(width-basemX)*delta/curlDuration;
  220.         mY = basemY-basemY*delta/curlDuration;
  221.         draw();    
  222.       },
  223.       curlShape = function(m,q) {
  224.         //cannot draw outside the viewport because of IE blurring the pattern
  225.         var intyW = m*width+q,intx0 = -q/m;
  226.         if($.browser.msie) {
  227.           intyW = Math.round(intyW);
  228.           intx0 = Math.round(intx0);
  229.         };
  230.         ctx.beginPath();
  231.         ctx.moveTo(width,Math.min(intyW,height));
  232.         ctx.lineTo(width,0);
  233.         ctx.lineTo(Math.max(intx0,0),0);
  234.         if(intx0<0) {
  235.           ctx.lineTo(0,Math.min(q,height));
  236.           if(q<height) {
  237.             ctx.lineTo((height-q)/m,height);
  238.           }
  239.           ctx.lineTo(width,height);
  240.         } else {
  241.           if(intyW<height)
  242.             ctx.lineTo(width,intyW);
  243.           else {
  244.             ctx.lineTo((height-q)/m,height);
  245.             ctx.lineTo(width,height);
  246.           }
  247.         }
  248.       },
  249.       draw = function() {
  250.         if(!init) return;
  251.         if($.browser.msie)
  252.           ctx.clearRect(0,0,width,height);
  253.  
  254.         ctx.fillStyle = background;
  255.         ctx.fillRect(0,0,width,height);
  256.         var img = images[0], r = $(img).data("flip.scale");
  257.         if($.browser.msie) {
  258.           ctx.fillStyle = patterns[0];
  259.           ctx.fillStyle.width2 = ctx.fillStyle.width*r;
  260.           ctx.fillStyle.height2 = ctx.fillStyle.height*r;
  261.           ctx.fillRect(0,0,width,height);
  262.         } else {
  263.           ctx.drawImage(img,(width-img.width*r)/2,(height-img.height*r)/2,img.width*r,img.height*r);
  264.         }
  265.        
  266.         if(mY && mX!=width) {
  267.          
  268.           var m = 2,
  269.               q = (mY-m*(mX+width))/2;
  270.               m2 = mY/(width-mX),
  271.               q2 = mX*m2;
  272.           if(m==m2) return;
  273.  
  274.           var sx=1,sy=1,tx=0,ty=0;
  275.           ctx.save();
  276.           if(sideLeft) {
  277.             tx = width;
  278.             sx = -1;
  279.           }
  280.           if(!cornersTop) {
  281.             ty = height;
  282.             sy = -1;
  283.           }
  284.           ctx.translate(tx,ty);
  285.           ctx.scale(sx,sy);
  286.           //draw page flip
  287.           //intx,inty is the intersection between the line of the curl and the line
  288.           //from the canvas corner to the curl point
  289.           var intx = (q2-q)/(m-m2);
  290.           var inty = m*intx+q;
  291.           //y=m*x+mY-m*mX line per (mX,mY) parallel to the curl line
  292.           //y=-x/m+inty+intx/m line perpendicular to the curl line
  293.           //intersection x between the 2 lines = int2x
  294.           //y of perpendicular for the intersection x = int2y
  295.           //opera do not fill a shape if gradient is finished
  296.           var int2x = (2*inty+intx+2*m*mX-2*mY)/(2*m+1);
  297.           var int2y = -int2x/m+inty+intx/m;
  298.           var d = Math.sqrt(Math.pow(intx-int2x,2)+Math.pow(inty-int2y,2));
  299.           var stopHighlight = Math.min(d*0.5,30);
  300.          
  301.           var c;
  302.           if(!($.browser.mozilla && parseFloat($.browser.version)<1.9)) {
  303.             c = ctx;
  304.           } else {
  305.             c = ctx2;
  306.             c.clearRect(0,0,width,height);
  307.             c.save();
  308.             c.translate(1,0); //the curl shapes do not overlap perfeclty
  309.           }
  310.           var gradient = c.createLinearGradient(intx,inty,int2x,int2y);
  311.           gradient.addColorStop(0, gradientColors[0]);
  312.           gradient.addColorStop(stopHighlight/d, gradientColors[1]);
  313.           gradient.addColorStop(1, gradientColors[2]);
  314.           c.fillStyle = gradient;
  315.           c.beginPath();
  316.           c.moveTo(-q/m,0);
  317.           c.quadraticCurveTo((-q/m+mX)/2+0.02*mX,mY/2,mX,mY);
  318.           c.quadraticCurveTo((width+mX)/2,(m*width+q+mY)/2-0.02*(height-mY),width,m*width+q);
  319.           if(!($.browser.mozilla && parseFloat($.browser.version)<1.9)) {
  320.             c.fill();
  321.           } else {
  322.             //for ff 2.0 use a clip region on a second canvas and copy all its content (much faster)
  323.             c.save();
  324.             c.clip();
  325.             c.fillRect(0,0,width,height);
  326.             c.restore();
  327.             ctx.drawImage(canvas2[0],0,0);
  328.             c.restore();          
  329.           }
  330.           //can't understand why this doesn't work on ff 2, fill is slow
  331.           /*
  332.           ctx.save();
  333.           ctx.clip();
  334.           ctx.fillRect(0,0,width,height);
  335.           ctx.restore();
  336.           */
  337.           gradient = null;
  338.                    
  339.           //draw solid color background
  340.           ctx.fillStyle = background;
  341.           curlShape(m,q);
  342.           ctx.fill();
  343.  
  344.           //draw back image
  345.           curlShape(m,q);
  346.           //safari and opera delete the path when doing restore
  347.           if(!$.browser.safari && !$.browser.opera)
  348.            ctx.restore();          
  349.  
  350.           var img = sideLeft?images[images.length-1]:images[1];
  351.           r = $(img).data("flip.scale");
  352.           if($.browser.msie) {
  353.             //excanvas does not support clip
  354.             ctx.fillStyle = sideLeft?patterns[patterns.length-1]:patterns[1];
  355.             //hack to scale the pattern on IE (modified excanvas)
  356.             ctx.fillStyle.width2 = ctx.fillStyle.width*r;
  357.             ctx.fillStyle.height2 = ctx.fillStyle.height*r;
  358.             ctx.fill();
  359.           } else {
  360.             ctx.save();
  361.             ctx.clip();
  362.             //safari and opera delete the path when doing restore
  363.             //at this point we have not reverted the trasform
  364.             if($.browser.safari || $.browser.opera) {
  365.               //revert transform
  366.               ctx.scale(1/sx,1/sy);
  367.               ctx.translate(-tx,-ty);
  368.             }            
  369.  
  370.             ctx.drawImage(img,(width-img.width*r)/2,(height-img.height*r)/2,img.width*r,img.height*r);
  371.  
  372.             //ctx.drawImage(img,(width-img.width)/2,(height-img.height)/2);
  373.             ctx.restore();
  374.             if($.browser.safari || $.browser.opera)
  375.               ctx.restore()
  376.           }
  377.         }  
  378.       }
  379.     }
  380.  
  381.     $.fn.jFlip = function(width,height,opts){
  382.       return this.each(function() {
  383.         $(this).wrap("<div class='flip_gallery'>");
  384.         var images = $(this).find("img");
  385.         //cannot hide because explorer does not give the image dimensions if hidden
  386.         var canvas = $(document.createElement("canvas")).attr({width:width,height:height}).css({margin:0,width:width+"px",height:height+"px"})
  387.         $(this).css({position:"absolute",left:"-9000px",top:"-9000px"}).after(canvas);
  388.         new Flip($(this).next(),width || 300,height || 300,images,opts);
  389.       });
  390.     };
  391.    
  392. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement