papercrop 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of papercrop might be problematic. Click here for more details.

@@ -1,246 +1,22 @@
1
1
  /**
2
- * jquery.Jcrop.min.js v0.9.9 (build:20110607)
3
- * jQuery Image Cropping Plugin
4
- * @author Kelly Hallman <khallman@gmail.com>
5
- * Copyright (c) 2008-2011 Kelly Hallman - released under MIT License
2
+ * jquery.Jcrop.min.js v0.9.10 (build:20130117)
3
+ * jQuery Image Cropping Plugin - released under MIT License
4
+ * Copyright (c) 2008-2012 Tapmodo Interactive LLC
6
5
  * https://github.com/tapmodo/Jcrop
7
6
  */
8
-
9
- (function($){$.Jcrop=function(obj,opt){var options=$.extend({},$.Jcrop.defaults),docOffset,lastcurs,ie6mode=false;function px(n){return parseInt(n,10)+'px';}
10
- function pct(n){return parseInt(n,10)+'%';}
11
- function cssClass(cl){return options.baseClass+'-'+cl;}
12
- function supportsColorFade(){return $.fx.step.hasOwnProperty('backgroundColor');}
13
- function getPos(obj)
14
- {var pos=$(obj).offset();return[pos.left,pos.top];}
15
- function mouseAbs(e)
16
- {return[(e.pageX-docOffset[0]),(e.pageY-docOffset[1])];}
17
- function setOptions(opt)
18
- {if(typeof(opt)!=='object'){opt={};}
19
- options=$.extend(options,opt);if(typeof(options.onChange)!=='function'){options.onChange=function(){};}
20
- if(typeof(options.onSelect)!=='function'){options.onSelect=function(){};}
21
- if(typeof(options.onRelease)!=='function'){options.onRelease=function(){};}}
22
- function myCursor(type)
23
- {if(type!==lastcurs){Tracker.setCursor(type);lastcurs=type;}}
24
- function startDragMode(mode,pos)
25
- {docOffset=getPos($img);Tracker.setCursor(mode==='move'?mode:mode+'-resize');if(mode==='move'){return Tracker.activateHandlers(createMover(pos),doneSelect);}
26
- var fc=Coords.getFixed();var opp=oppLockCorner(mode);var opc=Coords.getCorner(oppLockCorner(opp));Coords.setPressed(Coords.getCorner(opp));Coords.setCurrent(opc);Tracker.activateHandlers(dragmodeHandler(mode,fc),doneSelect);}
27
- function dragmodeHandler(mode,f)
28
- {return function(pos){if(!options.aspectRatio){switch(mode){case'e':pos[1]=f.y2;break;case'w':pos[1]=f.y2;break;case'n':pos[0]=f.x2;break;case's':pos[0]=f.x2;break;}}else{switch(mode){case'e':pos[1]=f.y+1;break;case'w':pos[1]=f.y+1;break;case'n':pos[0]=f.x+1;break;case's':pos[0]=f.x+1;break;}}
29
- Coords.setCurrent(pos);Selection.update();};}
30
- function createMover(pos)
31
- {var lloc=pos;KeyManager.watchKeys();return function(pos){Coords.moveOffset([pos[0]-lloc[0],pos[1]-lloc[1]]);lloc=pos;Selection.update();};}
32
- function oppLockCorner(ord)
33
- {switch(ord){case'n':return'sw';case's':return'nw';case'e':return'nw';case'w':return'ne';case'ne':return'sw';case'nw':return'se';case'se':return'nw';case'sw':return'ne';}}
34
- function createDragger(ord)
35
- {return function(e){if(options.disabled){return false;}
36
- if((ord==='move')&&!options.allowMove){return false;}
37
- btndown=true;startDragMode(ord,mouseAbs(e));e.stopPropagation();e.preventDefault();return false;};}
38
- function presize($obj,w,h)
39
- {var nw=$obj.width(),nh=$obj.height();if((nw>w)&&w>0){nw=w;nh=(w/$obj.width())*$obj.height();}
40
- if((nh>h)&&h>0){nh=h;nw=(h/$obj.height())*$obj.width();}
41
- xscale=$obj.width()/nw;yscale=$obj.height()/nh;$obj.width(nw).height(nh);}
42
- function unscale(c)
43
- {return{x:parseInt(c.x*xscale,10),y:parseInt(c.y*yscale,10),x2:parseInt(c.x2*xscale,10),y2:parseInt(c.y2*yscale,10),w:parseInt(c.w*xscale,10),h:parseInt(c.h*yscale,10)};}
44
- function doneSelect(pos)
45
- {var c=Coords.getFixed();if((c.w>options.minSelect[0])&&(c.h>options.minSelect[1])){Selection.enableHandles();Selection.done();}else{Selection.release();}
46
- Tracker.setCursor(options.allowSelect?'crosshair':'default');}
47
- function newSelection(e)
48
- {if(options.disabled){return false;}
49
- if(!options.allowSelect){return false;}
50
- btndown=true;docOffset=getPos($img);Selection.disableHandles();myCursor('crosshair');var pos=mouseAbs(e);Coords.setPressed(pos);Selection.update();Tracker.activateHandlers(selectDrag,doneSelect);KeyManager.watchKeys();e.stopPropagation();e.preventDefault();return false;}
51
- function selectDrag(pos)
52
- {Coords.setCurrent(pos);Selection.update();}
53
- function newTracker()
54
- {var trk=$('<div></div>').addClass(cssClass('tracker'));if($.browser.msie){trk.css({opacity:0,backgroundColor:'white'});}
55
- return trk;}
56
- if($.browser.msie&&($.browser.version.split('.')[0]==='6')){ie6mode=true;}
57
- if(typeof(obj)!=='object'){obj=$(obj)[0];}
58
- if(typeof(opt)!=='object'){opt={};}
59
- setOptions(opt);var img_css={border:'none',margin:0,padding:0,position:'absolute'};var $origimg=$(obj);var $img=$origimg.clone().removeAttr('id').css(img_css);$img.width($origimg.width());$img.height($origimg.height());$origimg.after($img).hide();presize($img,options.boxWidth,options.boxHeight);var boundx=$img.width(),boundy=$img.height(),$div=$('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({position:'relative',backgroundColor:options.bgColor}).insertAfter($origimg).append($img);delete(options.bgColor);if(options.addClass){$div.addClass(options.addClass);}
60
- var $img2=$('<img />').attr('src',$img.attr('src')).css(img_css).width(boundx).height(boundy),$img_holder=$('<div />').width(pct(100)).height(pct(100)).css({zIndex:310,position:'absolute',overflow:'hidden'}).append($img2),$hdl_holder=$('<div />').width(pct(100)).height(pct(100)).css('zIndex',320),$sel=$('<div />').css({position:'absolute',zIndex:300}).insertBefore($img).append($img_holder,$hdl_holder);if(ie6mode){$sel.css({overflowY:'hidden'});}
61
- var bound=options.boundary;var $trk=newTracker().width(boundx+(bound*2)).height(boundy+(bound*2)).css({position:'absolute',top:px(-bound),left:px(-bound),zIndex:290}).mousedown(newSelection);var bgopacity=options.bgOpacity,xlimit,ylimit,xmin,ymin,xscale,yscale,enabled=true,btndown,animating,shift_down;docOffset=getPos($img);var Touch=(function(){function hasTouchSupport(){var support={},events=['touchstart','touchmove','touchend'],el=document.createElement('div'),i;try{for(i=0;i<events.length;i++){var eventName=events[i];eventName='on'+eventName;var isSupported=(eventName in el);if(!isSupported){el.setAttribute(eventName,'return;');isSupported=typeof el[eventName]=='function';}
62
- support[events[i]]=isSupported;}
63
- return support.touchstart&&support.touchend&&support.touchmove;}
64
- catch(err){return false;}}
65
- function detectSupport(){if((options.touchSupport===true)||(options.touchSupport===false))return options.touchSupport;else return hasTouchSupport();}
66
- return{createDragger:function(ord){return function(e){e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;if(options.disabled){return false;}
67
- if((ord==='move')&&!options.allowMove){return false;}
68
- btndown=true;startDragMode(ord,mouseAbs(e));e.stopPropagation();e.preventDefault();return false;};},newSelection:function(e){e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;return newSelection(e);},isSupported:hasTouchSupport,support:detectSupport()};}());var Coords=(function(){var x1=0,y1=0,x2=0,y2=0,ox,oy;function setPressed(pos)
69
- {pos=rebound(pos);x2=x1=pos[0];y2=y1=pos[1];}
70
- function setCurrent(pos)
71
- {pos=rebound(pos);ox=pos[0]-x2;oy=pos[1]-y2;x2=pos[0];y2=pos[1];}
72
- function getOffset()
73
- {return[ox,oy];}
74
- function moveOffset(offset)
75
- {var ox=offset[0],oy=offset[1];if(0>x1+ox){ox-=ox+x1;}
76
- if(0>y1+oy){oy-=oy+y1;}
77
- if(boundy<y2+oy){oy+=boundy-(y2+oy);}
78
- if(boundx<x2+ox){ox+=boundx-(x2+ox);}
79
- x1+=ox;x2+=ox;y1+=oy;y2+=oy;}
80
- function getCorner(ord)
81
- {var c=getFixed();switch(ord){case'ne':return[c.x2,c.y];case'nw':return[c.x,c.y];case'se':return[c.x2,c.y2];case'sw':return[c.x,c.y2];}}
82
- function getFixed()
83
- {if(!options.aspectRatio){return getRect();}
84
- var aspect=options.aspectRatio,min_x=options.minSize[0]/xscale,max_x=options.maxSize[0]/xscale,max_y=options.maxSize[1]/yscale,rw=x2-x1,rh=y2-y1,rwa=Math.abs(rw),rha=Math.abs(rh),real_ratio=rwa/rha,xx,yy;if(max_x===0){max_x=boundx*10;}
85
- if(max_y===0){max_y=boundy*10;}
86
- if(real_ratio<aspect){yy=y2;w=rha*aspect;xx=rw<0?x1-w:w+x1;if(xx<0){xx=0;h=Math.abs((xx-x1)/aspect);yy=rh<0?y1-h:h+y1;}else if(xx>boundx){xx=boundx;h=Math.abs((xx-x1)/aspect);yy=rh<0?y1-h:h+y1;}}else{xx=x2;h=rwa/aspect;yy=rh<0?y1-h:y1+h;if(yy<0){yy=0;w=Math.abs((yy-y1)*aspect);xx=rw<0?x1-w:w+x1;}else if(yy>boundy){yy=boundy;w=Math.abs(yy-y1)*aspect;xx=rw<0?x1-w:w+x1;}}
87
- if(xx>x1){if(xx-x1<min_x){xx=x1+min_x;}else if(xx-x1>max_x){xx=x1+max_x;}
88
- if(yy>y1){yy=y1+(xx-x1)/aspect;}else{yy=y1-(xx-x1)/aspect;}}else if(xx<x1){if(x1-xx<min_x){xx=x1-min_x;}else if(x1-xx>max_x){xx=x1-max_x;}
89
- if(yy>y1){yy=y1+(x1-xx)/aspect;}else{yy=y1-(x1-xx)/aspect;}}
90
- if(xx<0){x1-=xx;xx=0;}else if(xx>boundx){x1-=xx-boundx;xx=boundx;}
91
- if(yy<0){y1-=yy;yy=0;}else if(yy>boundy){y1-=yy-boundy;yy=boundy;}
92
- return makeObj(flipCoords(x1,y1,xx,yy));}
93
- function rebound(p)
94
- {if(p[0]<0){p[0]=0;}
95
- if(p[1]<0){p[1]=0;}
96
- if(p[0]>boundx){p[0]=boundx;}
97
- if(p[1]>boundy){p[1]=boundy;}
98
- return[p[0],p[1]];}
99
- function flipCoords(x1,y1,x2,y2)
100
- {var xa=x1,xb=x2,ya=y1,yb=y2;if(x2<x1){xa=x2;xb=x1;}
101
- if(y2<y1){ya=y2;yb=y1;}
102
- return[Math.round(xa),Math.round(ya),Math.round(xb),Math.round(yb)];}
103
- function getRect()
104
- {var xsize=x2-x1,ysize=y2-y1,delta;if(xlimit&&(Math.abs(xsize)>xlimit)){x2=(xsize>0)?(x1+xlimit):(x1-xlimit);}
105
- if(ylimit&&(Math.abs(ysize)>ylimit)){y2=(ysize>0)?(y1+ylimit):(y1-ylimit);}
106
- if(ymin/yscale&&(Math.abs(ysize)<ymin/yscale)){y2=(ysize>0)?(y1+ymin/yscale):(y1-ymin/yscale);}
107
- if(xmin/xscale&&(Math.abs(xsize)<xmin/xscale)){x2=(xsize>0)?(x1+xmin/xscale):(x1-xmin/xscale);}
108
- if(x1<0){x2-=x1;x1-=x1;}
109
- if(y1<0){y2-=y1;y1-=y1;}
110
- if(x2<0){x1-=x2;x2-=x2;}
111
- if(y2<0){y1-=y2;y2-=y2;}
112
- if(x2>boundx){delta=x2-boundx;x1-=delta;x2-=delta;}
113
- if(y2>boundy){delta=y2-boundy;y1-=delta;y2-=delta;}
114
- if(x1>boundx){delta=x1-boundy;y2-=delta;y1-=delta;}
115
- if(y1>boundy){delta=y1-boundy;y2-=delta;y1-=delta;}
116
- return makeObj(flipCoords(x1,y1,x2,y2));}
117
- function makeObj(a)
118
- {return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]};}
119
- return{flipCoords:flipCoords,setPressed:setPressed,setCurrent:setCurrent,getOffset:getOffset,moveOffset:moveOffset,getCorner:getCorner,getFixed:getFixed};}());var Selection=(function(){var awake,hdep=370;var borders={};var handle={};var seehandles=false;var hhs=options.handleOffset;function insertBorder(type)
120
- {var jq=$('<div />').css({position:'absolute',opacity:options.borderOpacity}).addClass(cssClass(type));$img_holder.append(jq);return jq;}
121
- function dragDiv(ord,zi)
122
- {var jq=$('<div />').mousedown(createDragger(ord)).css({cursor:ord+'-resize',position:'absolute',zIndex:zi});if(Touch.support){jq.bind('touchstart',Touch.createDragger(ord));}
123
- $hdl_holder.append(jq);return jq;}
124
- function insertHandle(ord)
125
- {return dragDiv(ord,hdep++).css({top:px(-hhs+1),left:px(-hhs+1),opacity:options.handleOpacity}).addClass(cssClass('handle'));}
126
- function insertDragbar(ord)
127
- {var s=options.handleSize,h=s,w=s,t=hhs,l=hhs;switch(ord){case'n':case's':w=pct(100);break;case'e':case'w':h=pct(100);break;}
128
- return dragDiv(ord,hdep++).width(w).height(h).css({top:px(-t+1),left:px(-l+1)});}
129
- function createHandles(li)
130
- {var i;for(i=0;i<li.length;i++){handle[li[i]]=insertHandle(li[i]);}}
131
- function moveHandles(c)
132
- {var midvert=Math.round((c.h/2)-hhs),midhoriz=Math.round((c.w/2)-hhs),north=-hhs+1,west=-hhs+1,east=c.w-hhs,south=c.h-hhs,x,y;if(handle.e){handle.e.css({top:px(midvert),left:px(east)});handle.w.css({top:px(midvert)});handle.s.css({top:px(south),left:px(midhoriz)});handle.n.css({left:px(midhoriz)});}
133
- if(handle.ne){handle.ne.css({left:px(east)});handle.se.css({top:px(south),left:px(east)});handle.sw.css({top:px(south)});}
134
- if(handle.b){handle.b.css({top:px(south)});handle.r.css({left:px(east)});}}
135
- function moveto(x,y)
136
- {$img2.css({top:px(-y),left:px(-x)});$sel.css({top:px(y),left:px(x)});}
137
- function resize(w,h)
138
- {$sel.width(w).height(h);}
139
- function refresh()
140
- {var c=Coords.getFixed();Coords.setPressed([c.x,c.y]);Coords.setCurrent([c.x2,c.y2]);updateVisible();}
141
- function updateVisible()
142
- {if(awake){return update();}}
143
- function update()
144
- {var c=Coords.getFixed();resize(c.w,c.h);moveto(c.x,c.y);if(seehandles){moveHandles(c);}
145
- if(!awake){show();}
146
- options.onChange.call(api,unscale(c));}
147
- function show()
148
- {$sel.show();if(options.bgFade){$img.fadeTo(options.fadeTime,bgopacity);}else{$img.css('opacity',bgopacity);}
149
- awake=true;}
150
- function release()
151
- {disableHandles();$sel.hide();if(options.bgFade){$img.fadeTo(options.fadeTime,1);}else{$img.css('opacity',1);}
152
- awake=false;options.onRelease.call(api);}
153
- function showHandles()
154
- {if(seehandles){moveHandles(Coords.getFixed());$hdl_holder.show();}}
155
- function enableHandles()
156
- {seehandles=true;if(options.allowResize){moveHandles(Coords.getFixed());$hdl_holder.show();return true;}}
157
- function disableHandles()
158
- {seehandles=false;$hdl_holder.hide();}
159
- function animMode(v)
160
- {if(animating===v){disableHandles();}else{enableHandles();}}
161
- function done()
162
- {animMode(false);refresh();}
163
- if(options.drawBorders){borders={top:insertBorder('hline'),bottom:insertBorder('hline bottom'),left:insertBorder('vline'),right:insertBorder('vline right')};}
164
- if(options.dragEdges){handle.t=insertDragbar('n');handle.b=insertDragbar('s');handle.r=insertDragbar('e');handle.l=insertDragbar('w');}
165
- if(options.sideHandles){createHandles(['n','s','e','w']);}
166
- if(options.cornerHandles){createHandles(['sw','nw','ne','se']);}
167
- var $track=newTracker().mousedown(createDragger('move')).css({cursor:'move',position:'absolute',zIndex:360});if(Touch.support){$track.bind('touchstart.jcrop',Touch.createDragger('move'));}
168
- $img_holder.append($track);disableHandles();return{updateVisible:updateVisible,update:update,release:release,refresh:refresh,isAwake:function(){return awake;},setCursor:function(cursor){$track.css('cursor',cursor);},enableHandles:enableHandles,enableOnly:function(){seehandles=true;},showHandles:showHandles,disableHandles:disableHandles,animMode:animMode,done:done};}());var Tracker=(function(){var onMove=function(){},onDone=function(){},trackDoc=options.trackDocument;function toFront()
169
- {$trk.css({zIndex:450});if(trackDoc){$(document).bind('mousemove',trackMove).bind('mouseup',trackUp);}}
170
- function toBack()
171
- {$trk.css({zIndex:290});if(trackDoc){$(document).unbind('mousemove',trackMove).unbind('mouseup',trackUp);}}
172
- function trackMove(e)
173
- {onMove(mouseAbs(e));return false;}
174
- function trackUp(e)
175
- {e.preventDefault();e.stopPropagation();if(btndown){btndown=false;onDone(mouseAbs(e));if(Selection.isAwake()){options.onSelect.call(api,unscale(Coords.getFixed()));}
176
- toBack();onMove=function(){};onDone=function(){};}
177
- return false;}
178
- function activateHandlers(move,done)
179
- {btndown=true;onMove=move;onDone=done;toFront();return false;}
180
- function trackTouchMove(e)
181
- {e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;return trackMove(e);}
182
- function trackTouchEnd(e)
183
- {e.pageX=e.originalEvent.changedTouches[0].pageX;e.pageY=e.originalEvent.changedTouches[0].pageY;return trackUp(e);}
184
- function setCursor(t)
185
- {$trk.css('cursor',t);}
186
- if(Touch.support){$(document).bind('touchmove',trackTouchMove).bind('touchend',trackTouchEnd);}
187
- if(!trackDoc){$trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);}
188
- $img.before($trk);return{activateHandlers:activateHandlers,setCursor:setCursor};}());var KeyManager=(function(){var $keymgr=$('<input type="radio" />').css({position:'fixed',left:'-120px',width:'12px'}),$keywrap=$('<div />').css({position:'absolute',overflow:'hidden'}).append($keymgr);function watchKeys()
189
- {if(options.keySupport){$keymgr.show();$keymgr.focus();}}
190
- function onBlur(e)
191
- {$keymgr.hide();}
192
- function doNudge(e,x,y)
193
- {if(options.allowMove){Coords.moveOffset([x,y]);Selection.updateVisible();}
194
- e.preventDefault();e.stopPropagation();}
195
- function parseKey(e)
196
- {if(e.ctrlKey){return true;}
197
- shift_down=e.shiftKey?true:false;var nudge=shift_down?10:1;switch(e.keyCode){case 37:doNudge(e,-nudge,0);break;case 39:doNudge(e,nudge,0);break;case 38:doNudge(e,0,-nudge);break;case 40:doNudge(e,0,nudge);break;case 27:Selection.release();break;case 9:return true;}
198
- return false;}
199
- if(options.keySupport){$keymgr.keydown(parseKey).blur(onBlur);if(ie6mode||!options.fixedSupport){$keymgr.css({position:'absolute',left:'-20px'});$keywrap.append($keymgr).insertBefore($img);}else{$keymgr.insertBefore($img);}}
200
- return{watchKeys:watchKeys};}());function setClass(cname)
201
- {$div.removeClass().addClass(cssClass('holder')).addClass(cname);}
202
- function animateTo(a,callback)
203
- {var x1=parseInt(a[0],10)/xscale,y1=parseInt(a[1],10)/yscale,x2=parseInt(a[2],10)/xscale,y2=parseInt(a[3],10)/yscale;if(animating){return;}
204
- var animto=Coords.flipCoords(x1,y1,x2,y2),c=Coords.getFixed(),initcr=[c.x,c.y,c.x2,c.y2],animat=initcr,interv=options.animationDelay,ix1=animto[0]-initcr[0],iy1=animto[1]-initcr[1],ix2=animto[2]-initcr[2],iy2=animto[3]-initcr[3],pcent=0,velocity=options.swingSpeed;x=animat[0];y=animat[1];x2=animat[2];y2=animat[3];Selection.animMode(true);var anim_timer;function queueAnimator(){window.setTimeout(animator,interv);}
205
- var animator=(function(){return function(){pcent+=(100-pcent)/velocity;animat[0]=x+((pcent/100)*ix1);animat[1]=y+((pcent/100)*iy1);animat[2]=x2+((pcent/100)*ix2);animat[3]=y2+((pcent/100)*iy2);if(pcent>=99.8){pcent=100;}
206
- if(pcent<100){setSelectRaw(animat);queueAnimator();}else{Selection.done();if(typeof(callback)==='function'){callback.call(api);}}};}());queueAnimator();}
207
- function setSelect(rect)
208
- {setSelectRaw([parseInt(rect[0],10)/xscale,parseInt(rect[1],10)/yscale,parseInt(rect[2],10)/xscale,parseInt(rect[3],10)/yscale]);}
209
- function setSelectRaw(l)
210
- {Coords.setPressed([l[0],l[1]]);Coords.setCurrent([l[2],l[3]]);Selection.update();}
211
- function tellSelect()
212
- {return unscale(Coords.getFixed());}
213
- function tellScaled()
214
- {return Coords.getFixed();}
215
- function setOptionsNew(opt)
216
- {setOptions(opt);interfaceUpdate();}
217
- function disableCrop()
218
- {options.disabled=true;Selection.disableHandles();Selection.setCursor('default');Tracker.setCursor('default');}
219
- function enableCrop()
220
- {options.disabled=false;interfaceUpdate();}
221
- function cancelCrop()
222
- {Selection.done();Tracker.activateHandlers(null,null);}
223
- function destroy()
224
- {$div.remove();$origimg.show();$(obj).removeData('Jcrop');}
225
- function setImage(src,callback)
226
- {Selection.release();disableCrop();var img=new Image();img.onload=function(){var iw=img.width;var ih=img.height;var bw=options.boxWidth;var bh=options.boxHeight;$img.width(iw).height(ih);$img.attr('src',src);$img2.attr('src',src);presize($img,bw,bh);boundx=$img.width();boundy=$img.height();$img2.width(boundx).height(boundy);$trk.width(boundx+(bound*2)).height(boundy+(bound*2));$div.width(boundx).height(boundy);enableCrop();if(typeof(callback)==='function'){callback.call(api);}};img.src=src;}
227
- function interfaceUpdate(alt)
228
- {if(options.allowResize){if(alt){Selection.enableOnly();}else{Selection.enableHandles();}}else{Selection.disableHandles();}
229
- Tracker.setCursor(options.allowSelect?'crosshair':'default');Selection.setCursor(options.allowMove?'move':'default');if(options.hasOwnProperty('setSelect')){setSelect(options.setSelect);Selection.done();delete(options.setSelect);}
230
- if(options.hasOwnProperty('trueSize')){xscale=options.trueSize[0]/boundx;yscale=options.trueSize[1]/boundy;}
231
- if(options.hasOwnProperty('bgColor')){if(supportsColorFade()&&options.fadeTime){$div.animate({backgroundColor:options.bgColor},{queue:false,duration:options.fadeTime});}else{$div.css('backgroundColor',options.bgColor);}
232
- delete(options.bgColor);}
233
- if(options.hasOwnProperty('bgOpacity')){bgopacity=options.bgOpacity;if(Selection.isAwake()){if(options.fadeTime){$img.fadeTo(options.fadeTime,bgopacity);}else{$div.css('opacity',options.opacity);}}
234
- delete(options.bgOpacity);}
235
- xlimit=options.maxSize[0]||0;ylimit=options.maxSize[1]||0;xmin=options.minSize[0]||0;ymin=options.minSize[1]||0;if(options.hasOwnProperty('outerImage')){$img.attr('src',options.outerImage);delete(options.outerImage);}
236
- Selection.refresh();}
237
- if(Touch.support){$trk.bind('touchstart',Touch.newSelection);}
238
- $hdl_holder.hide();interfaceUpdate(true);var api={setImage:setImage,animateTo:animateTo,setSelect:setSelect,setOptions:setOptionsNew,tellSelect:tellSelect,tellScaled:tellScaled,setClass:setClass,disable:disableCrop,enable:enableCrop,cancel:cancelCrop,release:Selection.release,destroy:destroy,focus:KeyManager.watchKeys,getBounds:function(){return[boundx*xscale,boundy*yscale];},getWidgetSize:function(){return[boundx,boundy];},getScaleFactor:function(){return[xscale,yscale];},ui:{holder:$div,selection:$sel}};if($.browser.msie){$div.bind('selectstart',function(){return false;});}
239
- $origimg.data('Jcrop',api);return api;};$.fn.Jcrop=function(options,callback)
240
- {function attachWhenDone(from)
241
- {var opt=(typeof(options)==='object')?options:{};var loadsrc=opt.useImg||from.src;var img=new Image();img.onload=function(){function attachJcrop(){var api=$.Jcrop(from,opt);if(typeof(callback)==='function'){callback.call(api);}}
242
- function attachAttempt(){if(!img.width||!img.height){window.setTimeout(attachAttempt,50);}else{attachJcrop();}}
243
- window.setTimeout(attachAttempt,50);};img.src=loadsrc;}
244
- this.each(function(){if($(this).data('Jcrop')){if(options==='api'){return $(this).data('Jcrop');}
245
- else{$(this).data('Jcrop').setOptions(options);}}
246
- else{attachWhenDone(this);}});return this;};$.Jcrop.defaults={allowSelect:true,allowMove:true,allowResize:true,trackDocument:true,baseClass:'jcrop',addClass:null,bgColor:'black',bgOpacity:0.6,bgFade:false,borderOpacity:0.4,handleOpacity:0.5,handleSize:9,handleOffset:5,aspectRatio:0,keySupport:true,cornerHandles:true,sideHandles:true,drawBorders:true,dragEdges:true,fixedSupport:true,touchSupport:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onRelease:function(){}};}(jQuery));
7
+ (function(a){a.Jcrop=function(b,c){function i(a){return Math.round(a)+"px"}function j(a){return d.baseClass+"-"+a}function k(){return a.fx.step.hasOwnProperty("backgroundColor")}function l(b){var c=a(b).offset();return[c.left,c.top]}function m(a){return[a.pageX-e[0],a.pageY-e[1]]}function n(b){typeof b!="object"&&(b={}),d=a.extend(d,b),a.each(["onChange","onSelect","onRelease","onDblClick"],function(a,b){typeof d[b]!="function"&&(d[b]=function(){})})}function o(a,b,c){e=l(D),bc.setCursor(a==="move"?a:a+"-resize");if(a==="move")return bc.activateHandlers(q(b),v,c);var d=_.getFixed(),f=r(a),g=_.getCorner(r(f));_.setPressed(_.getCorner(f)),_.setCurrent(g),bc.activateHandlers(p(a,d),v,c)}function p(a,b){return function(c){if(!d.aspectRatio)switch(a){case"e":c[1]=b.y2;break;case"w":c[1]=b.y2;break;case"n":c[0]=b.x2;break;case"s":c[0]=b.x2}else switch(a){case"e":c[1]=b.y+1;break;case"w":c[1]=b.y+1;break;case"n":c[0]=b.x+1;break;case"s":c[0]=b.x+1}_.setCurrent(c),bb.update()}}function q(a){var b=a;return bd.watchKeys
8
+ (),function(a){_.moveOffset([a[0]-b[0],a[1]-b[1]]),b=a,bb.update()}}function r(a){switch(a){case"n":return"sw";case"s":return"nw";case"e":return"nw";case"w":return"ne";case"ne":return"sw";case"nw":return"se";case"se":return"nw";case"sw":return"ne"}}function s(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(b)),b.stopPropagation(),b.preventDefault(),!1)}}function t(a,b,c){var d=a.width(),e=a.height();d>b&&b>0&&(d=b,e=b/a.width()*a.height()),e>c&&c>0&&(e=c,d=c/a.height()*a.width()),T=a.width()/d,U=a.height()/e,a.width(d).height(e)}function u(a){return{x:a.x*T,y:a.y*U,x2:a.x2*T,y2:a.y2*U,w:a.w*T,h:a.h*U}}function v(a){var b=_.getFixed();b.w>d.minSelect[0]&&b.h>d.minSelect[1]?(bb.enableHandles(),bb.done()):bb.release(),bc.setCursor(d.allowSelect?"crosshair":"default")}function w(a){if(d.disabled)return!1;if(!d.allowSelect)return!1;W=!0,e=l(D),bb.disableHandles(),bc.setCursor("crosshair");var b=m(a);return _.setPressed(b),bb.update(),bc.activateHandlers(x,v,a.type.substring
9
+ (0,5)==="touch"),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("<div></div>").addClass(j("tracker"));return g&&b.css({opacity:0,backgroundColor:"white"}),b}function be(a){G.removeClass().addClass(j("holder")).addClass(a)}function bf(a,b){function t(){window.setTimeout(u,l)}var c=a[0]/T,e=a[1]/U,f=a[2]/T,g=a[3]/U;if(X)return;var h=_.flipCoords(c,e,f,g),i=_.getFixed(),j=[i.x,i.y,i.x2,i.y2],k=j,l=d.animationDelay,m=h[0]-j[0],n=h[1]-j[1],o=h[2]-j[2],p=h[3]-j[3],q=0,r=d.swingSpeed;c=k[0],e=k[1],f=k[2],g=k[3],bb.animMode(!0);var s,u=function(){return function(){q+=(100-q)/r,k[0]=Math.round(c+q/100*m),k[1]=Math.round(e+q/100*n),k[2]=Math.round(f+q/100*o),k[3]=Math.round(g+q/100*p),q>=99.8&&(q=100),q<100?(bh(k),t()):(bb.done(),bb.animMode(!1),typeof b=="function"&&b.call(bs))}}();t()}function bg(a){bh([a[0]/T,a[1]/U,a[2]/T,a[3]/U]),d.onSelect.call(bs,u(_.getFixed())),bb.enableHandles()}function bh(a){_.setPressed([a[0],a[1]]),_.setCurrent([a[2],
10
+ a[3]]),bb.update()}function bi(){return u(_.getFixed())}function bj(){return _.getFixed()}function bk(a){n(a),br()}function bl(){d.disabled=!0,bb.disableHandles(),bb.setCursor("default"),bc.setCursor("default")}function bm(){d.disabled=!1,br()}function bn(){bb.done(),bc.activateHandlers(null,null)}function bo(){G.remove(),A.show(),A.css("visibility","visible"),a(b).removeData("Jcrop")}function bp(a,b){bb.release(),bl();var c=new Image;c.onload=function(){var e=c.width,f=c.height,g=d.boxWidth,h=d.boxHeight;D.width(e).height(f),D.attr("src",a),H.attr("src",a),t(D,g,h),E=D.width(),F=D.height(),H.width(E).height(F),M.width(E+L*2).height(F+L*2),G.width(E).height(F),ba.resize(E,F),bm(),typeof b=="function"&&b.call(bs)},c.src=a}function bq(a,b,c){var e=b||d.bgColor;d.bgFade&&k()&&d.fadeTime&&!c?a.animate({backgroundColor:e},{queue:!1,duration:d.fadeTime}):a.css("backgroundColor",e)}function br(a){d.allowResize?a?bb.enableOnly():bb.enableHandles():bb.disableHandles(),bc.setCursor(d.allowSelect?"crosshair":"default"),bb
11
+ .setCursor(d.allowMove?"move":"default"),d.hasOwnProperty("trueSize")&&(T=d.trueSize[0]/E,U=d.trueSize[1]/F),d.hasOwnProperty("setSelect")&&(bg(d.setSelect),bb.done(),delete d.setSelect),ba.refresh(),d.bgColor!=N&&(bq(d.shade?ba.getShades():G,d.shade?d.shadeColor||d.bgColor:d.bgColor),N=d.bgColor),O!=d.bgOpacity&&(O=d.bgOpacity,d.shade?ba.refresh():bb.setBgOpacity(O)),P=d.maxSize[0]||0,Q=d.maxSize[1]||0,R=d.minSize[0]||0,S=d.minSize[1]||0,d.hasOwnProperty("outerImage")&&(D.attr("src",d.outerImage),delete d.outerImage),bb.refresh()}var d=a.extend({},a.Jcrop.defaults),e,f=navigator.userAgent.toLowerCase(),g=/msie/.test(f),h=/msie [1-6]\./.test(f);typeof b!="object"&&(b=a(b)[0]),typeof c!="object"&&(c={}),n(c);var z={border:"none",visibility:"visible",margin:0,padding:0,position:"absolute",top:0,left:0},A=a(b),B=!0;if(b.tagName=="IMG"){if(A[0].width!=0&&A[0].height!=0)A.width(A[0].width),A.height(A[0].height);else{var C=new Image;C.src=A[0].src,A.width(C.width),A.height(C.height)}var D=A.clone().removeAttr("id").
12
+ css(z).show();D.width(A.width()),D.height(A.height()),A.after(D).hide()}else D=A.css(z).show(),B=!1,d.shade===null&&(d.shade=!0);t(D,d.boxWidth,d.boxHeight);var E=D.width(),F=D.height(),G=a("<div />").width(E).height(F).addClass(j("holder")).css({position:"relative",backgroundColor:d.bgColor}).insertAfter(A).append(D);d.addClass&&G.addClass(d.addClass);var H=a("<div />"),I=a("<div />").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("<div />").width("100%").height("100%").css("zIndex",320),K=a("<div />").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("<img />").attr("src",D.attr("src")).css(z).width(E).height(F),I.append(H)),h&&K.css({overflowY:"hidden"});var L=d.boundary,M=y().width(E+L*2).height(F+L*2).css({position:"absolute",top:i(-L),left:i(-L),zIndex:290}).mousedown(w),N=d.bgColor,O=d.bgOpacity,P,Q,R,S,T,U,V=!0,W,X,Y;e=l(D);var Z=function(){function a(){var a={},b=["touchstart"
13
+ ,"touchmove","touchend"],c=document.createElement("div"),d;try{for(d=0;d<b.length;d++){var e=b[d];e="on"+e;var f=e in c;f||(c.setAttribute(e,"return;"),f=typeof c[e]=="function"),a[b[d]]=f}return a.touchstart&&a.touchend&&a.touchmove}catch(g){return!1}}function b(){return d.touchSupport===!0||d.touchSupport===!1?d.touchSupport:a()}return{createDragger:function(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(Z.cfilter(b)),!0),b.stopPropagation(),b.preventDefault(),!1)}},newSelection:function(a){return w(Z.cfilter(a))},cfilter:function(a){return a.pageX=a.originalEvent.changedTouches[0].pageX,a.pageY=a.originalEvent.changedTouches[0].pageY,a},isSupported:a,support:b()}}(),_=function(){function h(d){d=n(d),c=a=d[0],e=b=d[1]}function i(a){a=n(a),f=a[0]-c,g=a[1]-e,c=a[0],e=a[1]}function j(){return[f,g]}function k(d){var f=d[0],g=d[1];0>a+f&&(f-=f+a),0>b+g&&(g-=g+b),F<e+g&&(g+=F-(e+g)),E<c+f&&(f+=E-(c+f)),a+=f,c+=f,b+=g,e+=g}function l(a){var b=m();switch(a){case"ne":return[
14
+ b.x2,b.y];case"nw":return[b.x,b.y];case"se":return[b.x2,b.y2];case"sw":return[b.x,b.y2]}}function m(){if(!d.aspectRatio)return p();var f=d.aspectRatio,g=d.minSize[0]/T,h=d.maxSize[0]/T,i=d.maxSize[1]/U,j=c-a,k=e-b,l=Math.abs(j),m=Math.abs(k),n=l/m,r,s,t,u;return h===0&&(h=E*10),i===0&&(i=F*10),n<f?(s=e,t=m*f,r=j<0?a-t:t+a,r<0?(r=0,u=Math.abs((r-a)/f),s=k<0?b-u:u+b):r>E&&(r=E,u=Math.abs((r-a)/f),s=k<0?b-u:u+b)):(r=c,u=l/f,s=k<0?b-u:b+u,s<0?(s=0,t=Math.abs((s-b)*f),r=j<0?a-t:t+a):s>F&&(s=F,t=Math.abs(s-b)*f,r=j<0?a-t:t+a)),r>a?(r-a<g?r=a+g:r-a>h&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):r<a&&(a-r<g?r=a-g:a-r>h&&(r=a-h),s>b?s=b+(a-r)/f:s=b-(a-r)/f),r<0?(a-=r,r=0):r>E&&(a-=r-E,r=E),s<0?(b-=s,s=0):s>F&&(b-=s-F,s=F),q(o(a,b,r,s))}function n(a){return a[0]<0&&(a[0]=0),a[1]<0&&(a[1]=0),a[0]>E&&(a[0]=E),a[1]>F&&(a[1]=F),[Math.round(a[0]),Math.round(a[1])]}function o(a,b,c,d){var e=a,f=c,g=b,h=d;return c<a&&(e=c,f=a),d<b&&(g=d,h=b),[e,g,f,h]}function p(){var d=c-a,f=e-b,g;return P&&Math.abs(d)>P&&(c=d>0?a+P:a-P),Q&&Math.abs
15
+ (f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)<S/U&&(e=f>0?b+S/U:b-S/U),R/T&&Math.abs(d)<R/T&&(c=d>0?a+R/T:a-R/T),a<0&&(c-=a,a-=a),b<0&&(e-=b,b-=b),c<0&&(a-=c,c-=c),e<0&&(b-=e,e-=e),c>E&&(g=c-E,a-=g,c-=g),e>F&&(g=e-F,b-=g,e-=g),a>E&&(g=a-F,e-=g,b-=g),b>F&&(g=b-F,e-=g,b-=g),q(o(a,b,c,e))}function q(a){return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]}}var a=0,b=0,c=0,e=0,f,g;return{flipCoords:o,setPressed:h,setCurrent:i,getOffset:j,moveOffset:k,getCorner:l,getFixed:m}}(),ba=function(){function f(a,b){e.left.css({height:i(b)}),e.right.css({height:i(b)})}function g(){return h(_.getFixed())}function h(a){e.top.css({left:i(a.x),width:i(a.w),height:i(a.y)}),e.bottom.css({top:i(a.y2),left:i(a.x),width:i(a.w),height:i(F-a.y2)}),e.right.css({left:i(a.x2),width:i(E-a.x2)}),e.left.css({width:i(a.x)})}function j(){return a("<div />").css({position:"absolute",backgroundColor:d.shadeColor||d.bgColor}).appendTo(c)}function k(){b||(b=!0,c.insertBefore(D),g(),bb.setBgOpacity(1,0,1),H.hide(),l(d.shadeColor||d.bgColor,1),bb.
16
+ isAwake()?n(d.bgOpacity,1):n(1,1))}function l(a,b){bq(p(),a,b)}function m(){b&&(c.remove(),H.show(),b=!1,bb.isAwake()?bb.setBgOpacity(d.bgOpacity,1,1):(bb.setBgOpacity(1,1,1),bb.disableHandles()),bq(G,0,1))}function n(a,e){b&&(d.bgFade&&!e?c.animate({opacity:1-a},{queue:!1,duration:d.fadeTime}):c.css({opacity:1-a}))}function o(){d.shade?k():m(),bb.isAwake()&&n(d.bgOpacity)}function p(){return c.children()}var b=!1,c=a("<div />").css({position:"absolute",zIndex:240,opacity:0}),e={top:j(),left:j().height(F),right:j().height(F),bottom:j()};return{update:g,updateRaw:h,getShades:p,setBgColor:l,enable:k,disable:m,resize:f,refresh:o,opacity:n}}(),bb=function(){function k(b){var c=a("<div />").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("<div />").mousedown(s(b)).css({cursor:b+"-resize",position:"absolute",zIndex:c}).addClass("ord-"+b);return Z.support&&d.bind("touchstart.jcrop",Z.createDragger(b)),J.append(d),d}function m(a){var b=d.handleSize;return l
17
+ (a,c++).css({opacity:d.handleOpacity}).width(b).height(b).addClass(j("handle"))}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b<a.length;b++)g[a[b]]=n(a[b])}function p(a){var b,c;for(c=0;c<a.length;c++){switch(a[c]){case"n":b="hline";break;case"s":b="hline bottom";break;case"e":b="vline right";break;case"w":b="vline"}e[a[c]]=k(b)}}function q(a){var b;for(b=0;b<a.length;b++)f[a[b]]=m(a[b])}function r(a,b){d.shade||H.css({top:i(-b),left:i(-a)}),K.css({top:i(b),left:i(a)})}function t(a,b){K.width(Math.round(a)).height(Math.round(b))}function v(){var a=_.getFixed();_.setPressed([a.x,a.y]),_.setCurrent([a.x2,a.y2]),w()}function w(a){if(b)return x(a)}function x(a){var c=_.getFixed();t(c.w,c.h),r(c.x,c.y),d.shade&&ba.updateRaw(c),b||A(),a?d.onSelect.call(bs,u(c)):d.onChange.call(bs,u(c))}function z(a,c,e){if(!b&&!c)return;d.bgFade&&!e?D.animate({opacity:a},{queue:!1,duration:d.fadeTime}):D.css("opacity",a)}function A(){K.show(),d.shade?ba.opacity(O):z(O,!0),b=!0}function B(){F(),
18
+ K.hide(),d.shade?ba.opacity(1):z(1),b=!1,d.onRelease.call(bs)}function C(){h&&J.show()}function E(){h=!0;if(d.allowResize)return J.show(),!0}function F(){h=!1,J.hide()}function G(a){a?(X=!0,F()):(X=!1,E())}function L(){G(!1),v()}var b,c=370,e={},f={},g={},h=!1;d.dragEdges&&a.isArray(d.createDragbars)&&o(d.createDragbars),a.isArray(d.createHandles)&&q(d.createHandles),d.drawBorders&&a.isArray(d.createBorders)&&p(d.createBorders),a(document).bind("touchstart.jcrop-ios",function(b){a(b.currentTarget).hasClass("jcrop-tracker")&&b.stopPropagation()});var M=y().mousedown(s("move")).css({cursor:"move",position:"absolute",zIndex:360});return Z.support&&M.bind("touchstart.jcrop",Z.createDragger("move")),I.append(M),F(),{updateVisible:w,update:x,release:B,refresh:v,isAwake:function(){return b},setCursor:function(a){M.css("cursor",a)},enableHandles:E,enableOnly:function(){h=!0},showHandles:C,disableHandles:F,animMode:G,setBgOpacity:z,done:L}}(),bc=function(){function f(b){M.css({zIndex:450}),b?a(document).bind("touchmove.jcrop"
19
+ ,k).bind("touchend.jcrop",l):e&&a(document).bind("mousemove.jcrop",h).bind("mouseup.jcrop",i)}function g(){M.css({zIndex:290}),a(document).unbind(".jcrop")}function h(a){return b(m(a)),!1}function i(a){return a.preventDefault(),a.stopPropagation(),W&&(W=!1,c(m(a)),bb.isAwake()&&d.onSelect.call(bs,u(_.getFixed())),g(),b=function(){},c=function(){}),!1}function j(a,d,e){return W=!0,b=a,c=d,f(e),!1}function k(a){return b(m(Z.cfilter(a))),!1}function l(a){return i(Z.cfilter(a))}function n(a){M.css("cursor",a)}var b=function(){},c=function(){},e=d.trackDocument;return e||M.mousemove(h).mouseup(i).mouseout(i),D.before(M),{activateHandlers:j,setCursor:n}}(),bd=function(){function e(){d.keySupport&&(b.show(),b.focus())}function f(a){b.hide()}function g(a,b,c){d.allowMove&&(_.moveOffset([b,c]),bb.updateVisible(!0)),a.preventDefault(),a.stopPropagation()}function i(a){if(a.ctrlKey||a.metaKey)return!0;Y=a.shiftKey?!0:!1;var b=Y?10:1;switch(a.keyCode){case 37:g(a,-b,0);break;case 39:g(a,b,0);break;case 38:g(a,0,-b);break;
20
+ case 40:g(a,0,b);break;case 27:d.allowSelect&&bb.release();break;case 9:return!0}return!1}var b=a('<input type="radio" />').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("<div />").css({position:"absolute",overflow:"hidden"}).append(b);return d.keySupport&&(b.keydown(i).blur(f),h||!d.fixedSupport?(b.css({position:"absolute",left:"-20px"}),c.append(b).insertBefore(D)):b.insertBefore(D)),{watchKeys:e}}();Z.support&&M.bind("touchstart.jcrop",Z.newSelection),J.hide(),br(!0);var bs={setImage:bp,animateTo:bf,setSelect:bg,setOptions:bk,tellSelect:bi,tellScaled:bj,setClass:be,disable:bl,enable:bm,cancel:bn,release:bb.release,destroy:bo,focus:bd.watchKeys,getBounds:function(){return[E*T,F*U]},getWidgetSize:function(){return[E,F]},getScaleFactor:function(){return[T,U]},getOptions:function(){return d},ui:{holder:G,selection:K}};return g&&G.bind("selectstart",function(){return!1}),A.data("Jcrop",bs),bs},a.fn.Jcrop=function(b,c){var d;return this.each(function(){if(a(this).data("Jcrop")){if(
21
+ b==="api")return a(this).data("Jcrop");a(this).data("Jcrop").setOptions(b)}else this.tagName=="IMG"?a.Jcrop.Loader(this,function(){a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d)}):(a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d))}),this},a.Jcrop.Loader=function(b,c,d){function g(){f.complete?(e.unbind(".jcloader"),a.isFunction(c)&&c.call(f)):window.setTimeout(g,50)}var e=a(b),f=e[0];e.bind("load.jcloader",g).bind("error.jcloader",function(b){e.unbind(".jcloader"),a.isFunction(d)&&d.call(f)}),f.complete&&a.isFunction(c)&&(e.unbind(".jcloader"),c.call(f))},a.Jcrop.defaults={allowSelect:!0,allowMove:!0,allowResize:!0,trackDocument:!0,baseClass:"jcrop",addClass:null,bgColor:"black",bgOpacity:.6,bgFade:!1,borderOpacity:.4,handleOpacity:.5,handleSize:7,aspectRatio:0,keySupport:!0,createHandles:["n","s","e","w","nw","ne","se","sw"],createDragbars:["n","s","e","w"],createBorders:["n","s","e","w"],drawBorders:!0,dragEdges:!0
22
+ ,fixedSupport:!0,touchSupport:null,shade:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onDblClick:function(){},onRelease:function(){}}})(jQuery);
@@ -1,46 +1,50 @@
1
1
  var jcrop_api;
2
2
 
3
- var init_papercrop = function() {
4
- $(document).ready(function() {
5
- $('div[id$=_cropbox]').each(function() {
6
- var aspect, attachment, preview, update_crop;
7
-
8
- attachment = $(this).attr('id').replace('_cropbox', '');
9
- preview = !!$("#" + attachment + "_crop_preview").length;
10
- aspect = $("input#" + attachment + "_aspect").val();
11
-
12
- update_crop = function(coords) {
13
- var preview_width, rx, ry;
14
-
15
- if (preview) {
16
- preview_width = $("#" + attachment + "_crop_preview_wrapper").width();
17
- rx = preview_width / coords.w;
18
- ry = preview_width / coords.h;
19
-
20
- $("img#" + attachment + "_crop_preview").css({
21
- width : Math.round(rx * $("input[id$='_" + attachment + "_original_w']").val()) + "px",
22
- height : Math.round((ry * $("input[id$='_" + attachment + "_original_h']").val()) / aspect) + "px",
23
- marginLeft : "-" + Math.round(rx * coords.x) + "px",
24
- marginTop : "-" + Math.round((ry * coords.y) / aspect) + "px"
25
- });
26
- }
27
-
28
- $("#" + attachment + "_crop_x").val(Math.round(coords.x));
29
- $("#" + attachment + "_crop_y").val(Math.round(coords.y));
30
- $("#" + attachment + "_crop_w").val(Math.round(coords.w));
31
- $("#" + attachment + "_crop_h").val(Math.round(coords.h));
32
- };
33
-
34
- $(this).find('img').Jcrop({
35
- onChange : update_crop,
36
- onSelect : update_crop,
37
- setSelect : [0, 0, 500, 500],
38
- aspectRatio : aspect,
39
- boxWidth : $("input[id$='_" + attachment + "_box_w']").val()
40
- }, function(){ jcrop_api = this; });
3
+ window.init_papercrop = function() {
4
+ $("div[id$=_cropbox]").each(function() {
5
+
6
+ var attachment = $(this).attr("id").replace("_cropbox", "");
7
+ var preview = !!$("#" + attachment + "_crop_preview").length;
8
+ var aspect = $("input#" + attachment + "_aspect").val();
9
+ var width = $(this).width();
10
+
11
+ console.log($(this));
12
+
13
+ update_crop = function(coords) {
14
+ var preview_width, rx, ry;
15
+
16
+ if (preview) {
17
+ preview_width = $("#" + attachment + "_crop_preview_wrapper").width();
18
+
19
+ rx = preview_width / coords.w;
20
+ ry = preview_width / coords.h;
21
+
22
+ $("img#" + attachment + "_crop_preview").css({
23
+ width : Math.round(rx * $("input[id$='_" + attachment + "_original_w']").val()) + "px",
24
+ height : Math.round((ry * $("input[id$='_" + attachment + "_original_h']").val()) / aspect) + "px",
25
+ marginLeft : "-" + Math.round(rx * coords.x) + "px",
26
+ marginTop : "-" + Math.round((ry * coords.y) / aspect) + "px"
27
+ });
28
+ }
29
+
30
+ $("#" + attachment + "_crop_x").val(Math.round(coords.x));
31
+ $("#" + attachment + "_crop_y").val(Math.round(coords.y));
32
+ $("#" + attachment + "_crop_w").val(Math.round(coords.w));
33
+ $("#" + attachment + "_crop_h").val(Math.round(coords.h));
34
+ };
35
+
36
+ $(this).find("img").Jcrop({
37
+ onChange : update_crop,
38
+ onSelect : update_crop,
39
+ setSelect : [0, 0, 250, 250],
40
+ aspectRatio : aspect,
41
+ boxWidth : $("input[id$='_" + attachment + "_box_w']").val()
42
+ }, function() {
43
+ jcrop_api = this;
41
44
  });
42
45
  });
43
- }
46
+ };
47
+
44
48
 
45
49
  $(document).ready(function() {
46
50
  init_papercrop();
@@ -1,35 +1,86 @@
1
- /* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */
2
- .jcrop-holder { text-align: left; }
1
+ /* jquery.Jcrop.css v0.9.10 - MIT License */
3
2
 
4
- .jcrop-vline, .jcrop-hline
5
- {
6
- font-size: 0px;
7
- position: absolute;
8
- background: white url('Jcrop.gif') top left repeat;
3
+ /*
4
+ The outer-most container in a typical Jcrop instance
5
+ If you are having difficulty with formatting related to styles
6
+ on a parent element, place any fixes here or in a like selector
7
+
8
+ You can also style this element if you want to add a border, etc
9
+ A better method for styling can be seen below with .jcrop-light
10
+ (Add a class to the holder and style elements for that extended class)
11
+ */
12
+ .jcrop-holder {
13
+ direction: ltr;
14
+ text-align: left;
9
15
  }
10
- .jcrop-vline { height: 100%; width: 1px !important; }
11
- .jcrop-hline { width: 100%; height: 1px !important; }
12
- .jcrop-vline.right { right: 0px; }
13
- .jcrop-hline.bottom { bottom: 0px; }
14
- .jcrop-handle {
15
- font-size: 1px;
16
- width: 7px !important;
17
- height: 7px !important;
18
- border: 1px #eee solid;
19
- background-color: #333;
16
+
17
+ /* These styles define the border lines */
18
+ .jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif) top left repeat;font-size:0;position:absolute;}
19
+ .jcrop-vline{height:100%;width:1px!important;}
20
+ .jcrop-hline{height:1px!important;width:100%;}
21
+ .jcrop-vline.right{right:0;}
22
+ .jcrop-hline.bottom{bottom:0;}
23
+
24
+ /* Handle style - size is set by Jcrop handleSize option (currently) */
25
+ .jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}
26
+
27
+ /* This style is used for invisible click targets */
28
+ .jcrop-tracker
29
+ {
30
+ height: 100%;
31
+ width: 100%;
32
+ -webkit-tap-highlight-color: transparent; /* "turn off" link highlight */
33
+ -webkit-touch-callout: none; /* disable callout, image save panel */
34
+ -webkit-user-select: none; /* disable cut copy paste */
20
35
  }
21
36
 
22
- .jcrop-tracker { width: 100%; height: 100%; }
37
+ /* Positioning of handles and drag bars */
38
+ .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
39
+ .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
40
+ .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
41
+ .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
42
+ .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
43
+ .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
44
+ .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
45
+ .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
46
+ .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
47
+ .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
48
+ .jcrop-dragbar.ord-n{margin-top:-4px;}
49
+ .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
50
+ .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
51
+ .jcrop-dragbar.ord-w{margin-left:-4px;}
23
52
 
24
- .custom .jcrop-vline,
25
- .custom .jcrop-hline
53
+ /* The "jcrop-light" class/extension */
54
+ .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline
26
55
  {
27
- background: yellow;
56
+ background:#FFF;
57
+ filter:Alpha(opacity=70)!important;
58
+ opacity:.70!important;
28
59
  }
29
- .custom .jcrop-handle
60
+ .jcrop-light .jcrop-handle
30
61
  {
31
- border-color: black;
32
- background-color: #C7BB00;
33
- -moz-border-radius: 3px;
34
- -webkit-border-radius: 3px;
62
+ -moz-border-radius:3px;
63
+ -webkit-border-radius:3px;
64
+ background-color:#000;
65
+ border-color:#FFF;
66
+ border-radius:3px;
35
67
  }
68
+
69
+ /* The "jcrop-dark" class/extension */
70
+ .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline
71
+ {
72
+ background:#000;
73
+ filter:Alpha(opacity=70)!important;
74
+ opacity:.7!important;
75
+ }
76
+ .jcrop-dark .jcrop-handle
77
+ {
78
+ -moz-border-radius:3px;
79
+ -webkit-border-radius:3px;
80
+ background-color:#FFF;
81
+ border-color:#000;
82
+ border-radius:3px;
83
+ }
84
+
85
+ /* Fix for twitter bootstrap et al. */
86
+ .jcrop-holder img,img.jcrop-preview{ max-width: none; }
data/lib/papercrop.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'papercrop/engine'
2
+ require 'papercrop/reg_exp'
2
3
  require 'papercrop/active_record_extension'
3
4
  require 'papercrop/helpers'
4
5
  require 'paperclip_processors/cropper'
@@ -16,14 +16,14 @@ module Papercrop
16
16
  #
17
17
  # crop_attached_file :avatar, :aspect => "4:3"
18
18
  #
19
- # @param attachment_name [Symbol] The name of the desired attachment to crop
19
+ # @param attachment_name [Symbol] Name of the desired attachment to crop
20
20
  # @param opts [Hash]
21
21
  def crop_attached_file(attachment_name, opts = {})
22
- [:crop_x, :crop_y, :crop_w, :crop_h, :original_w, :original_h, :box_w, :aspect].each do |a|
22
+ [:crop_x, :crop_y, :crop_w, :crop_h, :original_w, :original_h, :box_w, :aspect, :cropped_geometries].each do |a|
23
23
  attr_accessor :"#{attachment_name}_#{a}"
24
24
  end
25
25
 
26
- if opts[:aspect].kind_of?(String) && opts[:aspect] =~ /^(\d{1,2}):(\d{1,2})$/
26
+ if opts[:aspect].kind_of?(String) && opts[:aspect] =~ Papercrop::RegExp::ASPECT
27
27
  opts[:aspect] = Range.new *opts[:aspect].split(':').map(&:to_i)
28
28
  end
29
29
 
@@ -46,6 +46,9 @@ module Papercrop
46
46
  module InstanceMethods
47
47
 
48
48
  # Asks if the attachment received a crop process
49
+ # @param attachment_name [Symbol]
50
+ #
51
+ # @return [Boolean]
49
52
  def cropping?(attachment_name)
50
53
  !self.send(:"#{attachment_name}_crop_x").blank? &&
51
54
  !self.send(:"#{attachment_name}_crop_y").blank? &&
@@ -54,33 +57,50 @@ module Papercrop
54
57
  end
55
58
 
56
59
 
57
- # Returns a Paperclip::Geometry object from a named attachment
60
+ # Returns a Paperclip::Geometry object of a given attachment
58
61
  #
59
- # @param attachment_name [Symbol]
60
- # @param style [Symbol] attachment style, :original by default
61
- # @return Paperclip::Geometry
62
+ # @param attachment_name [Symbol]
63
+ # @param style = :original [Symbol] attachment style
64
+ # @return [Paperclip::Geometry]
62
65
  def image_geometry(attachment_name, style = :original)
63
- @geometry ||= {}
64
- @geometry[style] ||= Paperclip::Geometry.from_file(self.send(attachment_name).path(style))
66
+ @geometry ||= {}
67
+ path = (self.send(attachment_name).options[:storage] == :s3) ? self.send(attachment_name).url(style) : self.send(attachment_name).path(style)
68
+ @geometry[style] ||= Paperclip::Geometry.from_file(path)
65
69
  end
66
70
 
67
71
 
68
- # Uses method missing to reprocess the attachment callback
72
+ # Uses method missing to responding the model callback
69
73
  def method_missing(method, *args)
70
- if method.to_s =~ /(reprocess_to_crop_)(\S{1,})(_attachment)/
74
+ if method.to_s =~ Papercrop::RegExp::CALLBACK
71
75
  reprocess_cropped_attachment(
72
- method.to_s.scan(/(reprocess_to_crop_)(\S{1,})(_attachment)/).flatten.second.to_sym
76
+ method.to_s.scan(Papercrop::RegExp::CALLBACK).flatten.first.to_sym
73
77
  )
74
78
  else
75
79
  super
76
80
  end
77
81
  end
78
82
 
83
+
84
+ # Sets all cropping attributes to nil
85
+ # @param attachment_name [Symbol]
86
+ def reset_crop_attributes_of(attachment_name)
87
+ [:crop_x, :crop_y, :crop_w, :crop_h].each do |a|
88
+ self.send :"#{attachment_name}_#{a}=", nil
89
+ end
90
+ end
91
+
79
92
  private
80
93
 
81
- # Reprocess the attachment after cropping
94
+ # Saves the attachment if the crop attributes are present
95
+ # @param attachment_name [Symbol]
82
96
  def reprocess_cropped_attachment(attachment_name)
83
- self.send(attachment_name.to_sym).reprocess! if cropping?(attachment_name)
97
+ if cropping?(attachment_name)
98
+ attachment_instance = send(attachment_name)
99
+ attachment_instance.assign(attachment_instance)
100
+ attachment_instance.save
101
+
102
+ reset_crop_attributes_of(attachment_name)
103
+ end
84
104
  end
85
105
 
86
106
  end
@@ -0,0 +1,6 @@
1
+ module Papercrop
2
+ module RegExp
3
+ ASPECT = /^([1-9]{1}\d*):([1-9]{1}\d*)$/
4
+ CALLBACK = /reprocess_to_crop_(\S{1,})_attachment/
5
+ end
6
+ end
@@ -0,0 +1,65 @@
1
+ require "spec_helper"
2
+
3
+ describe "Form Helpers" do
4
+
5
+ before do
6
+ @landscape = Landscape.new(:name => "Mountains")
7
+ @landscape.picture = open("test_app/test/fixtures/matterhorn.jpg")
8
+ @landscape.save
9
+
10
+ @box = nil
11
+ end
12
+
13
+
14
+ it "builds the crop box" do
15
+ form_for @landscape do |f|
16
+ @box = f.cropbox(:picture)
17
+ end
18
+ @box = HTML::Document.new(@box)
19
+
20
+ assert_select @box.root, 'input#landscape_picture_original_w', :value => "1024.0"
21
+ assert_select @box.root, 'input#landscape_picture_original_h', :value => "768.0"
22
+ assert_select @box.root, 'input#landscape_picture_box_w', :value => "1024.0"
23
+ assert_select @box.root, 'input#picture_aspect', :value => @landscape.picture_aspect.to_s
24
+ assert_select @box.root, 'input#picture_crop_x'
25
+ assert_select @box.root, 'input#picture_crop_y'
26
+ assert_select @box.root, 'input#picture_crop_w'
27
+ assert_select @box.root, 'input#picture_crop_h'
28
+
29
+ assert_select @box.root, 'div#picture_cropbox' do
30
+ assert_select 'img', :src => @landscape.picture.path(:original)
31
+ end
32
+ end
33
+
34
+
35
+ it "builds the crop box with different width" do
36
+ form_for @landscape do |f|
37
+ @box = f.cropbox(:picture, :width => 400)
38
+ end
39
+ @box = HTML::Document.new(@box)
40
+
41
+ assert_select @box.root, 'input#landscape_picture_box_w', :value => "400"
42
+ end
43
+
44
+
45
+ it "builds the preview box" do
46
+ form_for @landscape do |f|
47
+ @box = f.crop_preview(:picture)
48
+ end
49
+ @box = HTML::Document.new(@box)
50
+
51
+ assert_select @box.root, 'div#picture_crop_preview_wrapper', :style => "width:100px; height:75px; overflow:hidden" do
52
+ assert_select 'img#picture_crop_preview', :src => @landscape.picture.path(:original)
53
+ end
54
+ end
55
+
56
+
57
+ it "build the preview box with different width" do
58
+ form_for @landscape do |f|
59
+ @box = f.crop_preview(:picture, :width => 40)
60
+ end
61
+ @box = HTML::Document.new(@box)
62
+
63
+ assert_select @box.root, 'div#picture_crop_preview_wrapper', :style => "width:40px; height:30px; overflow:hidden"
64
+ end
65
+ end
@@ -9,21 +9,28 @@ describe "Active Record Extension" do
9
9
  end
10
10
 
11
11
 
12
- after do
13
- @landscape.destroy
14
- end
15
-
12
+ it "clears the crop attributes" do
13
+ @landscape.picture_crop_x = 0.0
14
+ @landscape.picture_crop_y = 0.0
15
+ @landscape.picture_crop_w = 400
16
+ @landscape.picture_crop_h = 300
17
+ @landscape.reset_crop_attributes_of(:picture)
16
18
 
17
- it "includes accessors to the model" do
18
- %w{crop_x crop_y crop_w crop_h original_w original_h box_w aspect}.each do |m|
19
- @landscape.should respond_to(:"picture_#{m}")
20
- @landscape.should respond_to(:"picture_#{m}=")
21
- end
19
+ @landscape.picture_crop_x.should be(nil)
20
+ @landscape.picture_crop_y.should be(nil)
21
+ @landscape.picture_crop_w.should be(nil)
22
+ @landscape.picture_crop_h.should be(nil)
22
23
  end
23
24
 
24
25
 
25
- it "registers the post processor" do
26
- @landscape.attachment_definitions[:picture][:processors].should eq([:cropper])
26
+ it "crops images" do
27
+ @landscape.picture_crop_x = 300.0
28
+ @landscape.picture_crop_y = 200.0
29
+ @landscape.picture_crop_w = 400
30
+ @landscape.picture_crop_h = 300
31
+ @landscape.save
32
+
33
+ compare_images(CROPPED_IMG_PATH, @landscape.picture.path(:medium)).should eq(0.0)
27
34
  end
28
35
 
29
36
 
@@ -34,14 +41,14 @@ describe "Active Record Extension" do
34
41
  end
35
42
 
36
43
 
37
- it "returns image properties" do
38
- @landscape.picture_aspect.should eq(4.0 / 3.0)
39
-
40
- @landscape.image_geometry(:picture).width.should eq(1024.0)
41
- @landscape.image_geometry(:picture).height.should eq(768.0)
44
+ it "includes accessors to the model" do
45
+ %w{crop_x crop_y crop_w crop_h original_w original_h box_w aspect}.each do |m|
46
+ @landscape.should respond_to(:"picture_#{m}")
47
+ @landscape.should respond_to(:"picture_#{m}=")
48
+ end
42
49
  end
43
50
 
44
-
51
+
45
52
  it "knows when to crop" do
46
53
  @landscape.cropping?(:picture).should be(false)
47
54
  @landscape.picture_crop_x = 0.0
@@ -52,13 +59,24 @@ describe "Active Record Extension" do
52
59
  end
53
60
 
54
61
 
55
- it "crops images" do
56
- @landscape.picture_crop_x = 300.0
57
- @landscape.picture_crop_y = 200.0
58
- @landscape.picture_crop_w = 400
59
- @landscape.picture_crop_h = 300
60
- @landscape.save
62
+ it "registers the post processor" do
63
+ @landscape.attachment_definitions[:picture][:processors].should eq([:cropper])
64
+ end
61
65
 
62
- compare_images(CROPPED_IMG_PATH, @landscape.picture.path(:medium)).should eq(0.0)
66
+
67
+ it "returns image properties" do
68
+ @landscape.picture_aspect.should eq(4.0 / 3.0)
69
+
70
+ @landscape.image_geometry(:picture).width.should eq(1024.0)
71
+ @landscape.image_geometry(:picture).height.should eq(768.0)
72
+ end
73
+
74
+
75
+ it "returns url for s3 storage" do
76
+ @landscape.picture.expects(:url).returns("http://some-aws-s3-storage-url").once
77
+ @landscape.picture.expects(:options).returns(:storage => :s3).once
78
+ Paperclip::Geometry.expects(:from_file).with("http://some-aws-s3-storage-url").once
79
+
80
+ @landscape.image_geometry(:picture)
63
81
  end
64
82
  end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe "RegExp Module" do
4
+
5
+ it "recognizes a callback name" do
6
+ assert "reprocess_to_crop_picture_attachment" =~ Papercrop::RegExp::CALLBACK
7
+ assert "reprocess_to_crop_thing1_attachment" =~ Papercrop::RegExp::CALLBACK
8
+ assert not("reprocess_to_crop_picture_atachment" =~ Papercrop::RegExp::CALLBACK)
9
+ assert not("reprocess_to_crop_attachment" =~ Papercrop::RegExp::CALLBACK)
10
+ end
11
+
12
+
13
+ it "parses aspects" do
14
+ assert "1:1" =~ Papercrop::RegExp::ASPECT
15
+ assert "4:3" =~ Papercrop::RegExp::ASPECT
16
+ assert "10:3" =~ Papercrop::RegExp::ASPECT
17
+ assert not("4:0" =~ Papercrop::RegExp::ASPECT)
18
+ assert not("0:4" =~ Papercrop::RegExp::ASPECT)
19
+ assert not("00:0" =~ Papercrop::RegExp::ASPECT)
20
+ assert not("A:3" =~ Papercrop::RegExp::ASPECT)
21
+ end
22
+ end
data/spec/spec_helper.rb CHANGED
@@ -17,7 +17,7 @@ RSpec.configure do |config|
17
17
  #
18
18
  # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
19
19
  #
20
- # config.mock_with :mocha
20
+ config.mock_with :mocha
21
21
  # config.mock_with :flexmock
22
22
  # config.mock_with :rr
23
23
 
@@ -27,7 +27,7 @@ RSpec.configure do |config|
27
27
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
28
28
  # examples within a transaction, remove the following line or assign false
29
29
  # instead of true.
30
- config.use_transactional_fixtures = true
30
+ config.use_transactional_fixtures = false
31
31
 
32
32
  # If true, the base class of anonymous controllers will be inferred
33
33
  # automatically. This will be the default behavior in future versions of
@@ -40,12 +40,15 @@ RSpec.configure do |config|
40
40
  # --seed 1234
41
41
  config.order = "random"
42
42
 
43
+ config.include Capybara::DSL
43
44
 
44
45
  config.before(:suite) do
45
- DatabaseCleaner.strategy = :transaction
46
- DatabaseCleaner.clean_with(:truncation)
46
+ DatabaseCleaner.strategy = :truncation
47
47
  end
48
48
 
49
+ config.before(:each) do
50
+ DatabaseCleaner.start
51
+ end
49
52
 
50
53
  config.after(:each) do
51
54
  DatabaseCleaner.clean
@@ -33,11 +33,14 @@
33
33
 
34
34
  $.Jcrop = function (obj, opt) {
35
35
  var options = $.extend({}, $.Jcrop.defaults),
36
- docOffset, lastcurs, ie6mode = false;
36
+ docOffset,
37
+ _ua = navigator.userAgent.toLowerCase(),
38
+ is_msie = /msie/.test(_ua),
39
+ ie6mode = /msie [1-6]\./.test(_ua);
37
40
 
38
41
  // Internal Methods {{{
39
42
  function px(n) {
40
- return n + 'px';
43
+ return Math.round(n) + 'px';
41
44
  }
42
45
  function cssClass(cl) {
43
46
  return options.baseClass + '-' + cl;
@@ -66,13 +69,13 @@
66
69
  });
67
70
  }
68
71
  //}}}
69
- function startDragMode(mode, pos) //{{{
72
+ function startDragMode(mode, pos, touch) //{{{
70
73
  {
71
74
  docOffset = getPos($img);
72
75
  Tracker.setCursor(mode === 'move' ? mode : mode + '-resize');
73
76
 
74
77
  if (mode === 'move') {
75
- return Tracker.activateHandlers(createMover(pos), doneSelect);
78
+ return Tracker.activateHandlers(createMover(pos), doneSelect, touch);
76
79
  }
77
80
 
78
81
  var fc = Coords.getFixed();
@@ -82,7 +85,7 @@
82
85
  Coords.setPressed(Coords.getCorner(opp));
83
86
  Coords.setCurrent(opc);
84
87
 
85
- Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect);
88
+ Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect, touch);
86
89
  }
87
90
  //}}}
88
91
  function dragmodeHandler(mode, f) //{{{
@@ -237,7 +240,7 @@
237
240
  var pos = mouseAbs(e);
238
241
  Coords.setPressed(pos);
239
242
  Selection.update();
240
- Tracker.activateHandlers(selectDrag, doneSelect);
243
+ Tracker.activateHandlers(selectDrag, doneSelect, e.type.substring(0,5)==='touch');
241
244
  KeyManager.watchKeys();
242
245
 
243
246
  e.stopPropagation();
@@ -254,7 +257,7 @@
254
257
  function newTracker() //{{{
255
258
  {
256
259
  var trk = $('<div></div>').addClass(cssClass('tracker'));
257
- if ($.browser.msie) {
260
+ if (is_msie) {
258
261
  trk.css({
259
262
  opacity: 0,
260
263
  backgroundColor: 'white'
@@ -267,9 +270,6 @@
267
270
  // }}}
268
271
  // Initialization {{{
269
272
  // Sanitize some options {{{
270
- if ($.browser.msie && ($.browser.version.split('.')[0] === '6')) {
271
- ie6mode = true;
272
- }
273
273
  if (typeof(obj) !== 'object') {
274
274
  obj = $(obj)[0];
275
275
  }
@@ -398,8 +398,7 @@
398
398
  // Touch support detection function adapted (under MIT License)
399
399
  // from code by Jeffrey Sambells - http://github.com/iamamused/
400
400
  function hasTouchSupport() {
401
- var support = {},
402
- events = ['touchstart', 'touchmove', 'touchend'],
401
+ var support = {}, events = ['touchstart', 'touchmove', 'touchend'],
403
402
  el = document.createElement('div'), i;
404
403
 
405
404
  try {
@@ -427,25 +426,27 @@
427
426
  return {
428
427
  createDragger: function (ord) {
429
428
  return function (e) {
430
- e.pageX = e.originalEvent.changedTouches[0].pageX;
431
- e.pageY = e.originalEvent.changedTouches[0].pageY;
432
429
  if (options.disabled) {
433
430
  return false;
434
431
  }
435
432
  if ((ord === 'move') && !options.allowMove) {
436
433
  return false;
437
434
  }
435
+ docOffset = getPos($img);
438
436
  btndown = true;
439
- startDragMode(ord, mouseAbs(e));
437
+ startDragMode(ord, mouseAbs(Touch.cfilter(e)), true);
440
438
  e.stopPropagation();
441
439
  e.preventDefault();
442
440
  return false;
443
441
  };
444
442
  },
445
443
  newSelection: function (e) {
444
+ return newSelection(Touch.cfilter(e));
445
+ },
446
+ cfilter: function (e){
446
447
  e.pageX = e.originalEvent.changedTouches[0].pageX;
447
448
  e.pageY = e.originalEvent.changedTouches[0].pageY;
448
- return newSelection(e);
449
+ return e;
449
450
  },
450
451
  isSupported: hasTouchSupport,
451
452
  support: detectSupport()
@@ -622,21 +623,13 @@
622
623
  //}}}
623
624
  function rebound(p) //{{{
624
625
  {
625
- if (p[0] < 0) {
626
- p[0] = 0;
627
- }
628
- if (p[1] < 0) {
629
- p[1] = 0;
630
- }
626
+ if (p[0] < 0) p[0] = 0;
627
+ if (p[1] < 0) p[1] = 0;
631
628
 
632
- if (p[0] > boundx) {
633
- p[0] = boundx;
634
- }
635
- if (p[1] > boundy) {
636
- p[1] = boundy;
637
- }
629
+ if (p[0] > boundx) p[0] = boundx;
630
+ if (p[1] > boundy) p[1] = boundy;
638
631
 
639
- return [p[0], p[1]];
632
+ return [Math.round(p[0]), Math.round(p[1])];
640
633
  }
641
634
  //}}}
642
635
  function flipCoords(x1, y1, x2, y2) //{{{
@@ -953,7 +946,7 @@
953
946
  //}}}
954
947
  function resize(w, h) //{{{
955
948
  {
956
- $sel.width(w).height(h);
949
+ $sel.width(Math.round(w)).height(Math.round(h));
957
950
  }
958
951
  //}}}
959
952
  function refresh() //{{{
@@ -1053,9 +1046,11 @@
1053
1046
  //}}}
1054
1047
  function animMode(v) //{{{
1055
1048
  {
1056
- if (animating === v) {
1049
+ if (v) {
1050
+ animating = true;
1057
1051
  disableHandles();
1058
1052
  } else {
1053
+ animating = false;
1059
1054
  enableHandles();
1060
1055
  }
1061
1056
  }
@@ -1128,21 +1123,21 @@
1128
1123
  onDone = function () {},
1129
1124
  trackDoc = options.trackDocument;
1130
1125
 
1131
- function toFront() //{{{
1126
+ function toFront(touch) //{{{
1132
1127
  {
1133
1128
  $trk.css({
1134
1129
  zIndex: 450
1135
1130
  });
1136
- if (Touch.support) {
1131
+
1132
+ if (touch)
1137
1133
  $(document)
1138
1134
  .bind('touchmove.jcrop', trackTouchMove)
1139
1135
  .bind('touchend.jcrop', trackTouchEnd);
1140
- }
1141
- if (trackDoc) {
1136
+
1137
+ else if (trackDoc)
1142
1138
  $(document)
1143
1139
  .bind('mousemove.jcrop',trackMove)
1144
1140
  .bind('mouseup.jcrop',trackUp);
1145
- }
1146
1141
  }
1147
1142
  //}}}
1148
1143
  function toBack() //{{{
@@ -1181,27 +1176,24 @@
1181
1176
  return false;
1182
1177
  }
1183
1178
  //}}}
1184
- function activateHandlers(move, done) //{{{
1179
+ function activateHandlers(move, done, touch) //{{{
1185
1180
  {
1186
1181
  btndown = true;
1187
1182
  onMove = move;
1188
1183
  onDone = done;
1189
- toFront();
1184
+ toFront(touch);
1190
1185
  return false;
1191
1186
  }
1192
1187
  //}}}
1193
1188
  function trackTouchMove(e) //{{{
1194
1189
  {
1195
- e.pageX = e.originalEvent.changedTouches[0].pageX;
1196
- e.pageY = e.originalEvent.changedTouches[0].pageY;
1197
- return trackMove(e);
1190
+ onMove(mouseAbs(Touch.cfilter(e)));
1191
+ return false;
1198
1192
  }
1199
1193
  //}}}
1200
1194
  function trackTouchEnd(e) //{{{
1201
1195
  {
1202
- e.pageX = e.originalEvent.changedTouches[0].pageX;
1203
- e.pageY = e.originalEvent.changedTouches[0].pageY;
1204
- return trackUp(e);
1196
+ return trackUp(Touch.cfilter(e));
1205
1197
  }
1206
1198
  //}}}
1207
1199
  function setCursor(t) //{{{
@@ -1227,8 +1219,9 @@
1227
1219
  position: 'fixed',
1228
1220
  left: '-120px',
1229
1221
  width: '12px'
1230
- }),
1231
- $keywrap = $('<div />').css({
1222
+ }).addClass('jcrop-keymgr'),
1223
+
1224
+ $keywrap = $('<div />').css({
1232
1225
  position: 'absolute',
1233
1226
  overflow: 'hidden'
1234
1227
  }).append($keymgr);
@@ -1337,8 +1330,8 @@
1337
1330
  pcent = 0,
1338
1331
  velocity = options.swingSpeed;
1339
1332
 
1340
- x = animat[0];
1341
- y = animat[1];
1333
+ x1 = animat[0];
1334
+ y1 = animat[1];
1342
1335
  x2 = animat[2];
1343
1336
  y2 = animat[3];
1344
1337
 
@@ -1352,10 +1345,10 @@
1352
1345
  return function () {
1353
1346
  pcent += (100 - pcent) / velocity;
1354
1347
 
1355
- animat[0] = x + ((pcent / 100) * ix1);
1356
- animat[1] = y + ((pcent / 100) * iy1);
1357
- animat[2] = x2 + ((pcent / 100) * ix2);
1358
- animat[3] = y2 + ((pcent / 100) * iy2);
1348
+ animat[0] = Math.round(x1 + ((pcent / 100) * ix1));
1349
+ animat[1] = Math.round(y1 + ((pcent / 100) * iy1));
1350
+ animat[2] = Math.round(x2 + ((pcent / 100) * ix2));
1351
+ animat[3] = Math.round(y2 + ((pcent / 100) * iy2));
1359
1352
 
1360
1353
  if (pcent >= 99.8) {
1361
1354
  pcent = 100;
@@ -1365,6 +1358,7 @@
1365
1358
  queueAnimator();
1366
1359
  } else {
1367
1360
  Selection.done();
1361
+ Selection.animMode(false);
1368
1362
  if (typeof(callback) === 'function') {
1369
1363
  callback.call(api);
1370
1364
  }
@@ -1428,6 +1422,7 @@
1428
1422
  {
1429
1423
  $div.remove();
1430
1424
  $origimg.show();
1425
+ $origimg.css('visibility','visible');
1431
1426
  $(obj).removeData('Jcrop');
1432
1427
  }
1433
1428
  //}}}
@@ -1576,8 +1571,7 @@
1576
1571
  }
1577
1572
  };
1578
1573
 
1579
- if ($.browser.msie)
1580
- $div.bind('selectstart', function () { return false; });
1574
+ if (is_msie) $div.bind('selectstart', function () { return false; });
1581
1575
 
1582
1576
  $origimg.data('Jcrop', api);
1583
1577
  return api;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: papercrop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-12 00:00:00.000000000 Z
12
+ date: 2013-01-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: '3.1'
53
+ version: '3.4'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
- version: '3.1'
61
+ version: '3.4'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rspec-rails
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: 1.1.1
94
+ - !ruby/object:Gem::Dependency
95
+ name: mocha
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: rmagick
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -169,15 +185,18 @@ files:
169
185
  - lib/papercrop/active_record_extension.rb
170
186
  - lib/papercrop/engine.rb
171
187
  - lib/papercrop/helpers.rb
188
+ - lib/papercrop/reg_exp.rb
172
189
  - lib/papercrop.rb
173
190
  - vendor/jcrop-v0.9.10/css/Jcrop.gif
174
191
  - vendor/jcrop-v0.9.10/css/jquery.Jcrop.css
175
192
  - vendor/jcrop-v0.9.10/js/jquery.Jcrop.js
176
193
  - vendor/jcrop-v0.9.10/MIT-LICENSE.txt
177
194
  - README.md
195
+ - spec/helpers/form_helpers_spec.rb
178
196
  - spec/integration/papercrop_js_spec.rb
179
197
  - spec/integration/papercrop_spec.rb
180
198
  - spec/model_extensions/active_record_spec.rb
199
+ - spec/model_extensions/reg_exp_spec.rb
181
200
  - spec/spec_helper.rb
182
201
  - spec/support/compare_images.rb
183
202
  homepage: https://github.com/rsantamaria/papercrop
@@ -192,18 +211,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
211
  - - ! '>='
193
212
  - !ruby/object:Gem::Version
194
213
  version: '0'
195
- segments:
196
- - 0
197
- hash: 1413706832105900597
198
214
  required_rubygems_version: !ruby/object:Gem::Requirement
199
215
  none: false
200
216
  requirements:
201
217
  - - ! '>='
202
218
  - !ruby/object:Gem::Version
203
219
  version: '0'
204
- segments:
205
- - 0
206
- hash: 1413706832105900597
207
220
  requirements: []
208
221
  rubyforge_project:
209
222
  rubygems_version: 1.8.24
@@ -211,8 +224,11 @@ signing_key:
211
224
  specification_version: 3
212
225
  summary: Paperclip extension for cropping images
213
226
  test_files:
227
+ - spec/helpers/form_helpers_spec.rb
214
228
  - spec/integration/papercrop_js_spec.rb
215
229
  - spec/integration/papercrop_spec.rb
216
230
  - spec/model_extensions/active_record_spec.rb
231
+ - spec/model_extensions/reg_exp_spec.rb
217
232
  - spec/spec_helper.rb
218
233
  - spec/support/compare_images.rb
234
+ has_rdoc: