123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197 |
- /**
- * jquery.Jcrop.js v0.9.8
- * jQuery Image Cropping Plugin
- * @author Kelly Hallman <khallman@gmail.com>
- * Copyright (c) 2008-2009 Kelly Hallman - released under MIT License {{{
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- * }}}
- */
- (function($) {
- $.Jcrop = function(obj,opt)
- {
- // Initialization {{{
- // Sanitize some options {{{
- var obj = obj, opt = opt;
- if (typeof(obj) !== 'object') obj = $(obj)[0];
- if (typeof(opt) !== 'object') opt = { };
- // Some on-the-fly fixes for MSIE...sigh
- if (!('trackDocument' in opt))
- {
- opt.trackDocument = $.browser.msie ? false : true;
- if ($.browser.msie && $.browser.version.split('.')[0] == '8')
- opt.trackDocument = true;
- }
- if (!('keySupport' in opt))
- opt.keySupport = $.browser.msie ? false : true;
-
- // }}}
- // Extend the default options {{{
- var defaults = {
- // Basic Settings
- trackDocument: false,
- baseClass: 'jcrop',
- addClass: null,
- // Styling Options
- bgColor: 'black',
- bgOpacity: .6,
- borderOpacity: .4,
- handleOpacity: .5,
- handlePad: 5,
- handleSize: 9,
- handleOffset: 5,
- edgeMargin: 14,
- aspectRatio: 0,
- keySupport: true,
- cornerHandles: true,
- sideHandles: true,
- drawBorders: true,
- dragEdges: true,
- boxWidth: 0,
- boxHeight: 0,
- boundary: 8,
- animationDelay: 20,
- swingSpeed: 3,
- allowSelect: true,
- allowMove: true,
- allowResize: true,
- minSelect: [ 0, 0 ],
- maxSize: [ 0, 0 ],
- minSize: [ 0, 0 ],
- // Callbacks / Event Handlers
- onChange: function() { },
- onSelect: function() { }
- };
- var options = defaults;
- setOptions(opt);
- // }}}
- // Initialize some jQuery objects {{{
- var $origimg = $(obj);
- var $img = $origimg.clone().removeAttr('id').css({ position: 'absolute' });
- $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);
- ;
-
- if (options.addClass) $div.addClass(options.addClass);
- //$img.wrap($div);
- var $img2 = $('<img />')/*{{{*/
- .attr('src',$img.attr('src'))
- .css('position','absolute')
- .width(boundx).height(boundy)
- ;/*}}}*/
- var $img_holder = $('<div />')/*{{{*/
- .width(pct(100)).height(pct(100))
- .css({
- zIndex: 310,
- position: 'absolute',
- overflow: 'hidden'
- })
- .append($img2)
- ;/*}}}*/
- var $hdl_holder = $('<div />')/*{{{*/
- .width(pct(100)).height(pct(100))
- .css('zIndex',320);
- /*}}}*/
- var $sel = $('<div />')/*{{{*/
- .css({
- position: 'absolute',
- zIndex: 300
- })
- .insertBefore($img)
- .append($img_holder,$hdl_holder)
- ;/*}}}*/
- 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);
-
- /* }}} */
- // Set more variables {{{
- var xlimit, ylimit, xmin, ymin;
- var xscale, yscale, enabled = true;
- var docOffset = getPos($img),
- // Internal states
- btndown, lastcurs, dimmed, animating,
- shift_down;
- // }}}
-
- // }}}
- // Internal Modules {{{
- var Coords = function()/*{{{*/
- {
- var x1 = 0, y1 = 0, x2 = 0, y2 = 0, ox, oy;
- function setPressed(pos)/*{{{*/
- {
- var pos = rebound(pos);
- x2 = x1 = pos[0];
- y2 = y1 = pos[1];
- };
- /*}}}*/
- function setCurrent(pos)/*{{{*/
- {
- var pos = rebound(pos);
- ox = pos[0] - x2;
- oy = pos[1] - y2;
- x2 = pos[0];
- y2 = pos[1];
- };
- /*}}}*/
- function getOffset()/*{{{*/
- {
- return [ ox, oy ];
- };
- /*}}}*/
- function moveOffset(offset)/*{{{*/
- {
- var ox = offset[0], oy = offset[1];
- if (0 > x1 + ox) ox -= ox + x1;
- if (0 > y1 + oy) oy -= oy + y1;
- if (boundy < y2 + oy) oy += boundy - (y2 + oy);
- if (boundx < x2 + ox) ox += boundx - (x2 + ox);
- x1 += ox;
- x2 += ox;
- y1 += oy;
- y2 += oy;
- };
- /*}}}*/
- function getCorner(ord)/*{{{*/
- {
- 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 ];
- }
- };
- /*}}}*/
- function getFixed()/*{{{*/
- {
- if (!options.aspectRatio) return getRect();
- // This function could use some optimization I think...
- var aspect = options.aspectRatio,
- min_x = options.minSize[0]/xscale,
- min_y = options.minSize[1]/yscale,
- 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 }
- if (max_y == 0) { max_y = boundy * 10 }
- 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;
- }
- }
- // Magic %-)
- if(xx > x1) { // right side
- if(xx - x1 < min_x) {
- xx = x1 + min_x;
- } else if (xx - x1 > max_x) {
- xx = x1 + max_x;
- }
- if(yy > y1) {
- yy = y1 + (xx - x1)/aspect;
- } else {
- yy = y1 - (xx - x1)/aspect;
- }
- } else if (xx < x1) { // left side
- if(x1 - xx < min_x) {
- xx = x1 - min_x
- } else if (x1 - xx > max_x) {
- xx = x1 - max_x;
- }
- if(yy > y1) {
- yy = y1 + (x1 - xx)/aspect;
- } else {
- yy = y1 - (x1 - xx)/aspect;
- }
- }
- if(xx < 0) {
- x1 -= xx;
- xx = 0;
- } else if (xx > boundx) {
- x1 -= xx - boundx;
- xx = boundx;
- }
- if(yy < 0) {
- y1 -= yy;
- yy = 0;
- } else if (yy > boundy) {
- y1 -= yy - boundy;
- yy = boundy;
- }
- return last = makeObj(flipCoords(x1,y1,xx,yy));
- };
- /*}}}*/
- function rebound(p)/*{{{*/
- {
- if (p[0] < 0) p[0] = 0;
- if (p[1] < 0) p[1] = 0;
- if (p[0] > boundx) p[0] = boundx;
- if (p[1] > boundy) p[1] = boundy;
- return [ p[0], p[1] ];
- };
- /*}}}*/
- function flipCoords(x1,y1,x2,y2)/*{{{*/
- {
- var xa = x1, xb = x2, ya = y1, yb = y2;
- if (x2 < x1)
- {
- xa = x2;
- xb = x1;
- }
- if (y2 < y1)
- {
- ya = y2;
- yb = y1;
- }
- return [ Math.round(xa), Math.round(ya), Math.round(xb), Math.round(yb) ];
- };
- /*}}}*/
- function getRect()/*{{{*/
- {
- var xsize = x2 - x1;
- var ysize = y2 - y1;
- if (xlimit && (Math.abs(xsize) > xlimit))
- x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);
- if (ylimit && (Math.abs(ysize) > ylimit))
- y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);
- if (ymin && (Math.abs(ysize) < ymin))
- y2 = (ysize > 0) ? (y1 + ymin) : (y1 - ymin);
- if (xmin && (Math.abs(xsize) < xmin))
- x2 = (xsize > 0) ? (x1 + xmin) : (x1 - xmin);
- if (x1 < 0) { x2 -= x1; x1 -= x1; }
- if (y1 < 0) { y2 -= y1; y1 -= y1; }
- if (x2 < 0) { x1 -= x2; x2 -= x2; }
- if (y2 < 0) { y1 -= y2; y2 -= y2; }
- if (x2 > boundx) { var delta = x2 - boundx; x1 -= delta; x2 -= delta; }
- if (y2 > boundy) { var delta = y2 - boundy; y1 -= delta; y2 -= delta; }
- if (x1 > boundx) { var delta = x1 - boundy; y2 -= delta; y1 -= delta; }
- if (y1 > boundy) { var delta = y1 - boundy; y2 -= delta; y1 -= delta; }
- return makeObj(flipCoords(x1,y1,x2,y2));
- };
- /*}}}*/
- function makeObj(a)/*{{{*/
- {
- return { x: a[0], y: a[1], x2: a[2], y2: a[3],
- w: a[2] - a[0], h: a[3] - a[1] };
- };
- /*}}}*/
- return {
- flipCoords: flipCoords,
- setPressed: setPressed,
- setCurrent: setCurrent,
- getOffset: getOffset,
- moveOffset: moveOffset,
- getCorner: getCorner,
- getFixed: getFixed
- };
- }();
- /*}}}*/
- var Selection = function()/*{{{*/
- {
- var start, end, dragmode, awake, hdep = 370;
- var borders = { };
- var handle = { };
- var seehandles = false;
- var hhs = options.handleOffset;
- /* Insert draggable elements {{{*/
- // Insert border divs for outline
- if (options.drawBorders) {
- borders = {
- top: insertBorder('hline')
- .css('top',$.browser.msie?px(-1):px(0)),
- bottom: insertBorder('hline'),
- left: insertBorder('vline'),
- right: insertBorder('vline')
- };
- }
- // Insert handles on edges
- if (options.dragEdges) {
- handle.t = insertDragbar('n');
- handle.b = insertDragbar('s');
- handle.r = insertDragbar('e');
- handle.l = insertDragbar('w');
- }
- // Insert side handles
- options.sideHandles &&
- createHandles(['n','s','e','w']);
- // Insert corner handles
- options.cornerHandles &&
- createHandles(['sw','nw','ne','se']);
- /*}}}*/
- // Private Methods
- function insertBorder(type)/*{{{*/
- {
- var jq = $('<div />')
- .css({position: 'absolute', opacity: options.borderOpacity })
- .addClass(cssClass(type));
- $img_holder.append(jq);
- return jq;
- };
- /*}}}*/
- function dragDiv(ord,zi)/*{{{*/
- {
- var jq = $('<div />')
- .mousedown(createDragger(ord))
- .css({
- cursor: ord+'-resize',
- position: 'absolute',
- zIndex: zi
- })
- ;
- $hdl_holder.append(jq);
- return jq;
- };
- /*}}}*/
- function insertHandle(ord)/*{{{*/
- {
- return dragDiv(ord,hdep++)
- .css({ top: px(-hhs+1), left: px(-hhs+1), opacity: options.handleOpacity })
- .addClass(cssClass('handle'));
- };
- /*}}}*/
- function insertDragbar(ord)/*{{{*/
- {
- var s = options.handleSize,
- o = hhs,
- h = s, w = s,
- t = o, l = o;
- switch(ord)
- {
- case 'n': case 's': w = pct(100); break;
- case 'e': case 'w': h = pct(100); break;
- }
- return dragDiv(ord,hdep++).width(w).height(h)
- .css({ top: px(-t+1), left: px(-l+1)});
- };
- /*}}}*/
- function createHandles(li)/*{{{*/
- {
- for(i in li) handle[li[i]] = insertHandle(li[i]);
- };
- /*}}}*/
- function moveHandles(c)/*{{{*/
- {
- var midvert = Math.round((c.h / 2) - hhs),
- midhoriz = Math.round((c.w / 2) - hhs),
- north = west = -hhs+1,
- east = c.w - hhs,
- south = c.h - hhs,
- x, y;
- 'e' in handle &&
- 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) });
- 'ne' in handle &&
- handle.ne.css({ left: px(east) }) &&
- handle.se.css({ top: px(south), left: px(east) }) &&
- handle.sw.css({ top: px(south) });
- 'b' in handle &&
- handle.b.css({ top: px(south) }) &&
- handle.r.css({ left: px(east) });
- };
- /*}}}*/
- function moveto(x,y)/*{{{*/
- {
- $img2.css({ top: px(-y), left: px(-x) });
- $sel.css({ top: px(y), left: px(x) });
- };
- /*}}}*/
- function resize(w,h)/*{{{*/
- {
- $sel.width(w).height(h);
- };
- /*}}}*/
- function refresh()/*{{{*/
- {
- var c = Coords.getFixed();
- Coords.setPressed([c.x,c.y]);
- Coords.setCurrent([c.x2,c.y2]);
- updateVisible();
- };
- /*}}}*/
- // Internal Methods
- function updateVisible()/*{{{*/
- { if (awake) return update(); };
- /*}}}*/
- function update()/*{{{*/
- {
- var c = Coords.getFixed();
- resize(c.w,c.h);
- moveto(c.x,c.y);
- options.drawBorders &&
- borders['right'].css({ left: px(c.w-1) }) &&
- borders['bottom'].css({ top: px(c.h-1) });
- seehandles && moveHandles(c);
- awake || show();
- options.onChange(unscale(c));
- };
- /*}}}*/
- function show()/*{{{*/
- {
- $sel.show();
- $img.css('opacity',options.bgOpacity);
- awake = true;
- };
- /*}}}*/
- function release()/*{{{*/
- {
- disableHandles();
- $sel.hide();
- $img.css('opacity',1);
- awake = false;
- };
- /*}}}*/
- function showHandles()//{{{
- {
- if (seehandles)
- {
- moveHandles(Coords.getFixed());
- $hdl_holder.show();
- }
- };
- //}}}
- function enableHandles()/*{{{*/
- {
- seehandles = true;
- if (options.allowResize)
- {
- moveHandles(Coords.getFixed());
- $hdl_holder.show();
- return true;
- }
- };
- /*}}}*/
- function disableHandles()/*{{{*/
- {
- seehandles = false;
- $hdl_holder.hide();
- };
- /*}}}*/
- function animMode(v)/*{{{*/
- {
- (animating = v) ? disableHandles(): enableHandles();
- };
- /*}}}*/
- function done()/*{{{*/
- {
- animMode(false);
- refresh();
- };
- /*}}}*/
- var $track = newTracker().mousedown(createDragger('move'))
- .css({ cursor: 'move', position: 'absolute', zIndex: 360 })
- $img_holder.append($track);
- disableHandles();
- return {
- updateVisible: updateVisible,
- update: update,
- release: release,
- refresh: refresh,
- 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;
- if (!trackDoc)
- {
- $trk
- .mousemove(trackMove)
- .mouseup(trackUp)
- .mouseout(trackUp)
- ;
- }
- function toFront()/*{{{*/
- {
- $trk.css({zIndex:450});
- if (trackDoc)
- {
- $(document)
- .mousemove(trackMove)
- .mouseup(trackUp)
- ;
- }
- }
- /*}}}*/
- function toBack()/*{{{*/
- {
- $trk.css({zIndex:290});
- if (trackDoc)
- {
- $(document)
- .unbind('mousemove',trackMove)
- .unbind('mouseup',trackUp)
- ;
- }
- }
- /*}}}*/
- function trackMove(e)/*{{{*/
- {
- onMove(mouseAbs(e));
- };
- /*}}}*/
- function trackUp(e)/*{{{*/
- {
- e.preventDefault();
- e.stopPropagation();
- if (btndown)
- {
- btndown = false;
- onDone(mouseAbs(e));
- options.onSelect(unscale(Coords.getFixed()));
- toBack();
- onMove = function() { };
- onDone = function() { };
- }
- return false;
- };
- /*}}}*/
- function activateHandlers(move,done)/* {{{ */
- {
- btndown = true;
- onMove = move;
- onDone = done;
- toFront();
- return false;
- };
- /* }}} */
- function setCursor(t) { $trk.css('cursor',t); };
- $img.before($trk);
- return {
- activateHandlers: activateHandlers,
- setCursor: setCursor
- };
- }();
- /*}}}*/
- var KeyManager = function()/*{{{*/
- {
- var $keymgr = $('<input type="radio" />')
- .css({ position: 'absolute', left: '-30px' })
- .keypress(parseKey)
- .blur(onBlur),
- $keywrap = $('<div />')
- .css({
- position: 'absolute',
- overflow: 'hidden'
- })
- .append($keymgr)
- ;
- function watchKeys()/*{{{*/
- {
- if (options.keySupport)
- {
- $keymgr.show();
- $keymgr.focus();
- }
- };
- /*}}}*/
- function onBlur(e)/*{{{*/
- {
- $keymgr.hide();
- };
- /*}}}*/
- function doNudge(e,x,y)/*{{{*/
- {
- if (options.allowMove) {
- Coords.moveOffset([x,y]);
- Selection.updateVisible();
- };
- e.preventDefault();
- e.stopPropagation();
- };
- /*}}}*/
- function parseKey(e)/*{{{*/
- {
- if (e.ctrlKey) return true;
- 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;
- }
- return nothing(e);
- };
- /*}}}*/
-
- if (options.keySupport) $keywrap.insertBefore($img);
- return {
- watchKeys: watchKeys
- };
- }();
- /*}}}*/
- // }}}
- // Internal Methods {{{
- function px(n) { return '' + parseInt(n) + 'px'; };
- function pct(n) { return '' + parseInt(n) + '%'; };
- function cssClass(cl) { return options.baseClass + '-' + cl; };
- function getPos(obj)/*{{{*/
- {
- // Updated in v0.9.4 to use built-in dimensions plugin
- var pos = $(obj).offset();
- return [ pos.left, pos.top ];
- };
- /*}}}*/
- function mouseAbs(e)/*{{{*/
- {
- return [ (e.pageX - docOffset[0]), (e.pageY - docOffset[1]) ];
- };
- /*}}}*/
- function myCursor(type)/*{{{*/
- {
- if (type != lastcurs)
- {
- Tracker.setCursor(type);
- //Handles.xsetCursor(type);
- lastcurs = type;
- }
- };
- /*}}}*/
- function startDragMode(mode,pos)/*{{{*/
- {
- docOffset = getPos($img);
- Tracker.setCursor(mode=='move'?mode:mode+'-resize');
- if (mode == 'move')
- return Tracker.activateHandlers(createMover(pos), doneSelect);
- 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);
- };
- /*}}}*/
- function dragmodeHandler(mode,f)/*{{{*/
- {
- 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;
- }
- Coords.setCurrent(pos);
- Selection.update();
- };
- };
- /*}}}*/
- function createMover(pos)/*{{{*/
- {
- var lloc = pos;
- KeyManager.watchKeys();
- return function(pos)
- {
- Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);
- lloc = pos;
-
- Selection.update();
- };
- };
- /*}}}*/
- function oppLockCorner(ord)/*{{{*/
- {
- 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';
- };
- };
- /*}}}*/
- function createDragger(ord)/*{{{*/
- {
- return function(e) {
- if (options.disabled) return false;
- if ((ord == 'move') && !options.allowMove) return false;
- btndown = true;
- startDragMode(ord,mouseAbs(e));
- e.stopPropagation();
- e.preventDefault();
- return false;
- };
- };
- /*}}}*/
- function presize($obj,w,h)/*{{{*/
- {
- var nw = $obj.width(), nh = $obj.height();
- if ((nw > w) && w > 0)
- {
- nw = w;
- nh = (w/$obj.width()) * $obj.height();
- }
- if ((nh > h) && h > 0)
- {
- nh = h;
- nw = (h/$obj.height()) * $obj.width();
- }
- xscale = $obj.width() / nw;
- yscale = $obj.height() / nh;
- $obj.width(nw).height(nh);
- };
- /*}}}*/
- function unscale(c)/*{{{*/
- {
- return {
- x: parseInt(c.x * xscale), y: parseInt(c.y * yscale),
- x2: parseInt(c.x2 * xscale), y2: parseInt(c.y2 * yscale),
- w: parseInt(c.w * xscale), h: parseInt(c.h * yscale)
- };
- };
- /*}}}*/
- function doneSelect(pos)/*{{{*/
- {
- var c = Coords.getFixed();
- if (c.w > options.minSelect[0] && c.h > options.minSelect[1])
- {
- Selection.enableHandles();
- Selection.done();
- }
- else
- {
- Selection.release();
- }
- Tracker.setCursor( options.allowSelect?'crosshair':'default' );
- };
- /*}}}*/
- function newSelection(e)/*{{{*/
- {
- if (options.disabled) return false;
- if (!options.allowSelect) return false;
- btndown = true;
- docOffset = getPos($img);
- Selection.disableHandles();
- myCursor('crosshair');
- var pos = mouseAbs(e);
- Coords.setPressed(pos);
- Tracker.activateHandlers(selectDrag,doneSelect);
- KeyManager.watchKeys();
- Selection.update();
- e.stopPropagation();
- e.preventDefault();
- return false;
- };
- /*}}}*/
- function selectDrag(pos)/*{{{*/
- {
- Coords.setCurrent(pos);
- Selection.update();
- };
- /*}}}*/
- function newTracker()
- {
- var trk = $('<div></div>').addClass(cssClass('tracker'));
- $.browser.msie && trk.css({ opacity: 0, backgroundColor: 'white' });
- return trk;
- };
- // }}}
- // API methods {{{
-
- function animateTo(a)/*{{{*/
- {
- var x1 = a[0] / xscale,
- y1 = a[1] / yscale,
- x2 = a[2] / xscale,
- y2 = a[3] / yscale;
- if (animating) return;
- var animto = Coords.flipCoords(x1,y1,x2,y2);
- var c = Coords.getFixed();
- var animat = initcr = [ c.x, c.y, c.x2, c.y2 ];
- var interv = options.animationDelay;
- var x = animat[0];
- var y = animat[1];
- var x2 = animat[2];
- var y2 = animat[3];
- var ix1 = animto[0] - initcr[0];
- var iy1 = animto[1] - initcr[1];
- var ix2 = animto[2] - initcr[2];
- var iy2 = animto[3] - initcr[3];
- var pcent = 0;
- var velocity = options.swingSpeed;
- Selection.animMode(true);
- 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 < 100) animateStart();
- else Selection.done();
- if (pcent >= 99.8) pcent = 100;
- setSelectRaw(animat);
- };
- }();
- function animateStart()
- { window.setTimeout(animator,interv); };
- animateStart();
- };
- /*}}}*/
- function setSelect(rect)//{{{
- {
- setSelectRaw([rect[0]/xscale,rect[1]/yscale,rect[2]/xscale,rect[3]/yscale]);
- };
- //}}}
- function setSelectRaw(l) /*{{{*/
- {
- Coords.setPressed([l[0],l[1]]);
- Coords.setCurrent([l[2],l[3]]);
- Selection.update();
- };
- /*}}}*/
- function setOptions(opt)/*{{{*/
- {
- if (typeof(opt) != 'object') opt = { };
- options = $.extend(options,opt);
- if (typeof(options.onChange)!=='function')
- options.onChange = function() { };
- if (typeof(options.onSelect)!=='function')
- options.onSelect = function() { };
- };
- /*}}}*/
- function tellSelect()/*{{{*/
- {
- return unscale(Coords.getFixed());
- };
- /*}}}*/
- function tellScaled()/*{{{*/
- {
- return Coords.getFixed();
- };
- /*}}}*/
- function setOptionsNew(opt)/*{{{*/
- {
- setOptions(opt);
- interfaceUpdate();
- };
- /*}}}*/
- function disableCrop()//{{{
- {
- options.disabled = true;
- Selection.disableHandles();
- Selection.setCursor('default');
- Tracker.setCursor('default');
- };
- //}}}
- function enableCrop()//{{{
- {
- options.disabled = false;
- interfaceUpdate();
- };
- //}}}
- function cancelCrop()//{{{
- {
- Selection.done();
- Tracker.activateHandlers(null,null);
- };
- //}}}
- function destroy()//{{{
- {
- $div.remove();
- $origimg.show();
- };
- //}}}
- function interfaceUpdate(alt)//{{{
- // This method tweaks the interface based on options object.
- // Called when options are changed and at end of initialization.
- {
- options.allowResize ?
- alt?Selection.enableOnly():Selection.enableHandles():
- Selection.disableHandles();
- Tracker.setCursor( options.allowSelect? 'crosshair': 'default' );
- Selection.setCursor( options.allowMove? 'move': 'default' );
- $div.css('backgroundColor',options.bgColor);
- if ('setSelect' in options) {
- setSelect(opt.setSelect);
- Selection.done();
- delete(options.setSelect);
- }
- if ('trueSize' in options) {
- xscale = options.trueSize[0] / boundx;
- yscale = options.trueSize[1] / boundy;
- }
- xlimit = options.maxSize[0] || 0;
- ylimit = options.maxSize[1] || 0;
- xmin = options.minSize[0] || 0;
- ymin = options.minSize[1] || 0;
- if ('outerImage' in options)
- {
- $img.attr('src',options.outerImage);
- delete(options.outerImage);
- }
- Selection.refresh();
- };
- //}}}
- // }}}
- $hdl_holder.hide();
- interfaceUpdate(true);
-
- var api = {
- animateTo: animateTo,
- setSelect: setSelect,
- setOptions: setOptionsNew,
- tellSelect: tellSelect,
- tellScaled: tellScaled,
- disable: disableCrop,
- enable: enableCrop,
- cancel: cancelCrop,
- focus: KeyManager.watchKeys,
- getBounds: function() { return [ boundx * xscale, boundy * yscale ]; },
- getWidgetSize: function() { return [ boundx, boundy ]; },
- release: Selection.release,
- destroy: destroy
- };
- $origimg.data('Jcrop',api);
- return api;
- };
- $.fn.Jcrop = function(options)/*{{{*/
- {
- function attachWhenDone(from)/*{{{*/
- {
- var loadsrc = options.useImg || from.src;
- var img = new Image();
- img.onload = function() { $.Jcrop(from,options); };
- img.src = loadsrc;
- };
- /*}}}*/
- if (typeof(options) !== 'object') options = { };
- // Iterate over each object, attach Jcrop
- this.each(function()
- {
- // If we've already attached to this object
- if ($(this).data('Jcrop'))
- {
- // The API can be requested this way (undocumented)
- if (options == 'api') return $(this).data('Jcrop');
- // Otherwise, we just reset the options...
- else $(this).data('Jcrop').setOptions(options);
- }
- // If we haven't been attached, preload and attach
- else attachWhenDone(this);
- });
- // Return "this" so we're chainable a la jQuery plugin-style!
- return this;
- };
- /*}}}*/
- })(jQuery);
|