Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save armikhael/de93cbb3faf1a28ea924 to your computer and use it in GitHub Desktop.
Save armikhael/de93cbb3faf1a28ea924 to your computer and use it in GitHub Desktop.
Multiple Image upload (including orientation variations) utilizing HTML5
<div class="container">
<h1>DEMO Multiple (or single) image uploader with Details and Crop Options</h1>
<h4>Currently supports /image/* type (yes .gif's work, just try your fancy loading.gif if you don't believe me</h4>
<p>@ToDo implement server side support for non-supported file types (i.e. .psd) but I will leave that up to you!</p>
<p>@ToDo get the pen out of demo mode and optimize as an actual form</p>
<h1 class="well">@ToDo ENJOY!!!</h1>
<form class="form-horizontal image-form" role="form">
<div>
<span class="btn btn-default btn-file btn-block">
Upload Image
<input name="filesToUpload[]" id="filesToUpload" type="file" multiple="" title="Select an image file" />
</span>
</div>
<div class="img-wrapper row">
</div>
</form>
</div>

Multiple Image upload (including orientation variations) utilizing HTML5

quick pen to show the utilization of the HTML file reader API as well as jCrop and twitter bootstrap to incorporate a multiple file image uploader with info and crop (including specified orientation) on a per image basis. YES, I know this isn't fully functional, nor is ot set up the best it could be, but I hope you get the point :)

(using jCrop)

Enjoy!

A Pen by Curt Husting on CodePen.

License.

$( function ()
{
// this should be handled different, but works for the demo
var template = '<div class="image well clearfix">' +
'<div class="crop-container col-xs-12 col-sm-6 pull-right">' +
'<h3>Select Desired Orientation</h3>' +
'<span class="crop btn btn-default" data-orientation="landscape" data-ratio="1.7778">Landscape</span>' +
'<span class="crop btn btn-default" data-orientation="portrait" data-ratio="0.5625">Portrait</span>' +
'<span class="crop btn btn-default" data-orientation="square" data-ratio="1.0000">Square</span>' +
'<h3>Select Desired Crop</h3>' +
'<img class="img-responsive" />' +
'</div>' +
'<div class="form-container col-xs-12 col-sm-6">' +
'<h3>Image Details</h3>' +
'' +
'<div class="form-group col-xs-12">' +
'<input class="form-control" type="text" name="name" placeholder="Name" required>' +
'</div>' +
'<div class="form-group col-xs-12">' +
'<input class="form-control" type="text" name="credit" placeholder="Credit">' +
'</div>' +
'<div class="form-group col-xs-12">' +
'<textarea class="form-control" name="caption" placeholder="Caption"></textarea>' +
'</div>' +
'<div class="form-group col-xs-6">' +
'<input class="form-control" type="text" name="origWidth" placeholder="Original Width" readonly>' +
'</div>' +
'<div class="form-group col-xs-6">' +
'<input class="form-control" type="text" name="origHeight" placeholder="Original Height" readonly>' +
'</div>' +
'<div class="form-group col-xs-6">' +
'<input class="form-control" type="text" name="width" placeholder="Width" readonly>' +
'</div>' +
'<div class="form-group col-xs-6">' +
'<input class="form-control" type="text" name="height" placeholder="Height" readonly>' +
'</div>' +
'<div class="form-group col-xs-3">' +
'<input class="form-control" type="text" name="x1" placeholder="x1" readonly>' +
'</div>' +
'<div class="form-group col-xs-3">' +
'<input class="form-control" type="text" name="y1" placeholder="y1" readonly>' +
'</div>' +
'<div class="form-group col-xs-3">' +
'<input class="form-control" type="text" name="x2" placeholder="x2" readonly>' +
'</div>' +
'<div class="form-group col-xs-3">' +
'<input class="form-control" type="text" name="y2" placeholder="y2" readonly>' +
'</div>' +
'<div class="form-group">' +
'<div class="col-xs-12">' +
'<button type="submit" class="btn btn-default">Save & Continue</button>' +
'</div>' +
'</div>' +
'' +
'</div>' +
'</div>';
var fileInput = $( '#filesToUpload' );
var fileDisplayArea = $( '.img-wrapper' );
function initCrop( el )
{
var target = el.nextAll( 'img' );
var form = el.parents( '.crop-container' ).nextAll( '.form-container' );
var cropContainer = $( '.crop-container' );
var imageData = new Image();
imageData.src = target.attr( "src" );
target.Jcrop(
{
onSelect: showCoords,
bgColor: 'black',
bgOpacity: .4,
setSelect: [ 100, 100, 50, 50 ],
trueSize: [ imageData.width, imageData.height ],
aspectRatio: el.data( 'ratio' ),
minSize: [ 320, 320 ],
} );
function showCoords( c )
{
form.find( 'input[name="origWidth"]' ).val( imageData.width );
form.find( 'input[name="origHeight"]' ).val( imageData.height );
form.find( 'input[name="x1"]' ).val( c.x );
form.find( 'input[name="y1"]' ).val( c.y );
form.find( 'input[name="x2"]' ).val( c.x2 );
form.find( 'input[name="y2"]' ).val( c.y2 );
form.find( 'input[name="width"]' ).val( c.w );
form.find( 'input[name="height"]' ).val( c.h );
};
}
function createImage( file )
{
var preview = $( template ),
image = $( 'img', preview );
var form = image.parents( '.crop-container' ).nextAll( '.form-container' );
var reader = new FileReader();
// var imageData = new Image();
// imageData.src = image.attr( "src" );
// var imageType = /image.*/;
// console.log( imageData, imageData.type, 'type' );
// if ( !imageData.type.match( imageType ) )
// {
// alert( 'unsupported format supplied' );
// return;
// }
reader.onload = function ( e )
{
image.attr( 'src', e.target.result );
image.attr( 'id', 'crop-' + file.name );
form.attr( 'id', 'form-' + file.name );
};
reader.readAsDataURL( file );
preview.prependTo( fileDisplayArea );
}
fileInput.on( 'change', function ( e )
{
var files = fileInput[ 0 ].files;
for ( var i = 0; i < files.length; i++ )
{
var file = files[ i ];
createImage( file );
}
} );
$( document ).on( 'click', 'span.crop', function ()
{
initCrop( $( this ) )
} )
$( document ).on( 'submit', '.image-form', function ( ev )
{
// Just for fun
var values = {};
$.each( $( this ).serializeArray(), function ( i, field )
{
values[ field.name ] = field.value;
} );
console.log( values );
ev.preventDefault();
} );
} )
/**
* jquery.Jcrop.js v0.9.12
* jQuery Image Cropping Plugin - released under MIT License
* Author: Kelly Hallman <khallman@gmail.com>
* http://github.com/tapmodo/Jcrop
* Copyright (c) 2008-2013 Tapmodo Interactive LLC {{{
*
* 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 )
{
var options = $.extend(
{}, $.Jcrop.defaults ),
docOffset,
_ua = navigator.userAgent.toLowerCase(),
is_msie = /msie/.test( _ua ),
ie6mode = /msie [1-6]\./.test( _ua );
// Internal Methods {{{
function px( n )
{
return Math.round( n ) + 'px';
}
function cssClass( cl )
{
return options.baseClass + '-' + cl;
}
function supportsColorFade()
{
return $.fx.step.hasOwnProperty( 'backgroundColor' );
}
function getPos( obj ) //{{{
{
var pos = $( obj ).offset();
return [ pos.left, pos.top ];
}
//}}}
function mouseAbs( e ) //{{{
{
return [ ( e.pageX - docOffset[ 0 ] ), ( e.pageY - docOffset[ 1 ] ) ];
}
//}}}
function setOptions( opt ) //{{{
{
if ( typeof ( opt ) !== 'object' ) opt = {};
options = $.extend( options, opt );
$.each( [ 'onChange', 'onSelect', 'onRelease', 'onDblClick' ], function ( i, e )
{
if ( typeof ( options[ e ] ) !== 'function' ) options[ e ] = function () {};
} );
}
//}}}
function startDragMode( mode, pos, touch ) //{{{
{
docOffset = getPos( $img );
Tracker.setCursor( mode === 'move' ? mode : mode + '-resize' );
if ( mode === 'move' )
{
return Tracker.activateHandlers( createMover( pos ), doneSelect, touch );
}
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, touch );
}
//}}}
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;
}
// Fix position of crop area when dragged the very first time.
// Necessary when crop image is in a hidden element when page is loaded.
docOffset = getPos( $img );
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: c.x * xscale,
y: c.y * yscale,
x2: c.x2 * xscale,
y2: c.y2 * yscale,
w: c.w * xscale,
h: 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();
Tracker.setCursor( 'crosshair' );
var pos = mouseAbs( e );
Coords.setPressed( pos );
Selection.update();
Tracker.activateHandlers( selectDrag, doneSelect, e.type.substring( 0, 5 ) === 'touch' );
KeyManager.watchKeys();
e.stopPropagation();
e.preventDefault();
return false;
}
//}}}
function selectDrag( pos ) //{{{
{
Coords.setCurrent( pos );
Selection.update();
}
//}}}
function newTracker() //{{{
{
var trk = $( '<div></div>' ).addClass( cssClass( 'tracker' ) );
if ( is_msie )
{
trk.css(
{
opacity: 0,
backgroundColor: 'white'
} );
}
return trk;
}
//}}}
// }}}
// Initialization {{{
// Sanitize some options {{{
if ( typeof ( obj ) !== 'object' )
{
obj = $( obj )[ 0 ];
}
if ( typeof ( opt ) !== 'object' )
{
opt = {};
}
// }}}
setOptions( opt );
// Initialize some jQuery objects {{{
// The values are SET on the image(s) for the interface
// If the original image has any of these set, they will be reset
// However, if you destroy() the Jcrop instance the original image's
// character in the DOM will be as you left it.
var img_css = {
border: 'none',
visibility: 'visible',
margin: 0,
padding: 0,
position: 'absolute',
top: 0,
left: 0
};
var $origimg = $( obj ),
img_mode = true;
if ( obj.tagName == 'IMG' )
{
// Fix size of crop image.
// Necessary when crop image is within a hidden element when page is loaded.
if ( $origimg[ 0 ].width != 0 && $origimg[ 0 ].height != 0 )
{
// Obtain dimensions from contained img element.
$origimg.width( $origimg[ 0 ].width );
$origimg.height( $origimg[ 0 ].height );
}
else
{
// Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0).
var tempImage = new Image();
tempImage.src = $origimg[ 0 ].src;
$origimg.width( tempImage.width );
$origimg.height( tempImage.height );
}
var $img = $origimg.clone().removeAttr( 'id' ).css( img_css ).show();
$img.width( $origimg.width() );
$img.height( $origimg.height() );
$origimg.after( $img ).hide();
}
else
{
$img = $origimg.css( img_css ).show();
img_mode = false;
if ( options.shade === null )
{
options.shade = true;
}
}
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 );
}
var $img2 = $( '<div />' ),
$img_holder = $( '<div />' )
.width( '100%' ).height( '100%' ).css(
{
zIndex: 310,
position: 'absolute',
overflow: 'hidden'
} ),
$hdl_holder = $( '<div />' )
.width( '100%' ).height( '100%' ).css( 'zIndex', 320 ),
$sel = $( '<div />' )
.css(
{
position: 'absolute',
zIndex: 600
} ).dblclick( function ()
{
var c = Coords.getFixed();
options.onDblClick.call( api, c );
} ).insertBefore( $img ).append( $img_holder, $hdl_holder );
if ( img_mode )
{
$img2 = $( '<img />' )
.attr( 'src', $img.attr( 'src' ) ).css( img_css ).width( boundx ).height( boundy ),
$img_holder.append( $img2 );
}
if ( ie6mode )
{
$sel.css(
{
overflowY: 'hidden'
} );
}
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 bgcolor = options.bgColor,
bgopacity = options.bgOpacity,
xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true,
btndown, animating, shift_down;
docOffset = getPos( $img );
// }}}
// }}}
// Internal Modules {{{
// Touch Module {{{
var Touch = ( function ()
{
// Touch support detection function adapted (under MIT License)
// from code by Jeffrey Sambells - http://github.com/iamamused/
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';
}
support[ events[ i ] ] = isSupported;
}
return support.touchstart && support.touchend && support.touchmove;
}
catch ( err )
{
return false;
}
}
function detectSupport()
{
if ( ( options.touchSupport === true ) || ( options.touchSupport === false ) ) return options.touchSupport;
else return hasTouchSupport();
}
return {
createDragger: function ( ord )
{
return function ( e )
{
if ( options.disabled )
{
return false;
}
if ( ( ord === 'move' ) && !options.allowMove )
{
return false;
}
docOffset = getPos( $img );
btndown = true;
startDragMode( ord, mouseAbs( Touch.cfilter( e ) ), true );
e.stopPropagation();
e.preventDefault();
return false;
};
},
newSelection: function ( e )
{
return newSelection( Touch.cfilter( e ) );
},
cfilter: function ( e )
{
e.pageX = e.originalEvent.changedTouches[ 0 ].pageX;
e.pageY = e.originalEvent.changedTouches[ 0 ].pageY;
return e;
},
isSupported: hasTouchSupport,
support: detectSupport()
};
}() );
// }}}
// Coords Module {{{
var Coords = ( function ()
{
var x1 = 0,
y1 = 0,
x2 = 0,
y2 = 0,
ox, oy;
function setPressed( pos ) //{{{
{
pos = rebound( pos );
x2 = x1 = pos[ 0 ];
y2 = y1 = pos[ 1 ];
}
//}}}
function setCurrent( pos ) //{{{
{
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, w, h;
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 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 [ Math.round( p[ 0 ] ), Math.round( 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 [ xa, ya, xb, yb ];
}
//}}}
function getRect() //{{{
{
var xsize = x2 - x1,
ysize = y2 - y1,
delta;
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 / yscale && ( Math.abs( ysize ) < ymin / yscale ) )
{
y2 = ( ysize > 0 ) ? ( y1 + ymin / yscale ) : ( y1 - ymin / yscale );
}
if ( xmin / xscale && ( Math.abs( xsize ) < xmin / xscale ) )
{
x2 = ( xsize > 0 ) ? ( x1 + xmin / xscale ) : ( x1 - xmin / xscale );
}
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 )
{
delta = x2 - boundx;
x1 -= delta;
x2 -= delta;
}
if ( y2 > boundy )
{
delta = y2 - boundy;
y1 -= delta;
y2 -= delta;
}
if ( x1 > boundx )
{
delta = x1 - boundy;
y2 -= delta;
y1 -= delta;
}
if ( y1 > boundy )
{
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
};
}() );
//}}}
// Shade Module {{{
var Shade = ( function ()
{
var enabled = false,
holder = $( '<div />' ).css(
{
position: 'absolute',
zIndex: 240,
opacity: 0
} ),
shades = {
top: createShade(),
left: createShade().height( boundy ),
right: createShade().height( boundy ),
bottom: createShade()
};
function resizeShades( w, h )
{
shades.left.css(
{
height: px( h )
} );
shades.right.css(
{
height: px( h )
} );
}
function updateAuto()
{
return updateShade( Coords.getFixed() );
}
function updateShade( c )
{
shades.top.css(
{
left: px( c.x ),
width: px( c.w ),
height: px( c.y )
} );
shades.bottom.css(
{
top: px( c.y2 ),
left: px( c.x ),
width: px( c.w ),
height: px( boundy - c.y2 )
} );
shades.right.css(
{
left: px( c.x2 ),
width: px( boundx - c.x2 )
} );
shades.left.css(
{
width: px( c.x )
} );
}
function createShade()
{
return $( '<div />' ).css(
{
position: 'absolute',
backgroundColor: options.shadeColor || options.bgColor
} ).appendTo( holder );
}
function enableShade()
{
if ( !enabled )
{
enabled = true;
holder.insertBefore( $img );
updateAuto();
Selection.setBgOpacity( 1, 0, 1 );
$img2.hide();
setBgColor( options.shadeColor || options.bgColor, 1 );
if ( Selection.isAwake() )
{
setOpacity( options.bgOpacity, 1 );
}
else setOpacity( 1, 1 );
}
}
function setBgColor( color, now )
{
colorChangeMacro( getShades(), color, now );
}
function disableShade()
{
if ( enabled )
{
holder.remove();
$img2.show();
enabled = false;
if ( Selection.isAwake() )
{
Selection.setBgOpacity( options.bgOpacity, 1, 1 );
}
else
{
Selection.setBgOpacity( 1, 1, 1 );
Selection.disableHandles();
}
colorChangeMacro( $div, 0, 1 );
}
}
function setOpacity( opacity, now )
{
if ( enabled )
{
if ( options.bgFade && !now )
{
holder.animate(
{
opacity: 1 - opacity
},
{
queue: false,
duration: options.fadeTime
} );
}
else holder.css(
{
opacity: 1 - opacity
} );
}
}
function refreshAll()
{
options.shade ? enableShade() : disableShade();
if ( Selection.isAwake() ) setOpacity( options.bgOpacity );
}
function getShades()
{
return holder.children();
}
return {
update: updateAuto,
updateRaw: updateShade,
getShades: getShades,
setBgColor: setBgColor,
enable: enableShade,
disable: disableShade,
resize: resizeShades,
refresh: refreshAll,
opacity: setOpacity
};
}() );
// }}}
// Selection Module {{{
var Selection = ( function ()
{
var awake,
hdep = 370,
borders = {},
handle = {},
dragbar = {},
seehandles = false;
// 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
} ).addClass( 'ord-' + ord );
if ( Touch.support )
{
jq.bind( 'touchstart.jcrop', Touch.createDragger( ord ) );
}
$hdl_holder.append( jq );
return jq;
}
//}}}
function insertHandle( ord ) //{{{
{
var hs = options.handleSize,
div = dragDiv( ord, hdep++ ).css(
{
opacity: options.handleOpacity
} ).addClass( cssClass( 'handle' ) );
if ( hs )
{
div.width( hs ).height( hs );
}
return div;
}
//}}}
function insertDragbar( ord ) //{{{
{
return dragDiv( ord, hdep++ ).addClass( 'jcrop-dragbar' );
}
//}}}
function createDragbars( li ) //{{{
{
var i;
for ( i = 0; i < li.length; i++ )
{
dragbar[ li[ i ] ] = insertDragbar( li[ i ] );
}
}
//}}}
function createBorders( li ) //{{{
{
var cl, i;
for ( i = 0; i < li.length; i++ )
{
switch ( li[ i ] )
{
case 'n':
cl = 'hline';
break;
case 's':
cl = 'hline bottom';
break;
case 'e':
cl = 'vline right';
break;
case 'w':
cl = 'vline';
break;
}
borders[ li[ i ] ] = insertBorder( cl );
}
}
//}}}
function createHandles( li ) //{{{
{
var i;
for ( i = 0; i < li.length; i++ )
{
handle[ li[ i ] ] = insertHandle( li[ i ] );
}
}
//}}}
function moveto( x, y ) //{{{
{
if ( !options.shade )
{
$img2.css(
{
top: px( -y ),
left: px( -x )
} );
}
$sel.css(
{
top: px( y ),
left: px( x )
} );
}
//}}}
function resize( w, h ) //{{{
{
$sel.width( Math.round( w ) ).height( Math.round( h ) );
}
//}}}
function refresh() //{{{
{
var c = Coords.getFixed();
Coords.setPressed( [ c.x, c.y ] );
Coords.setCurrent( [ c.x2, c.y2 ] );
updateVisible();
}
//}}}
// Internal Methods
function updateVisible( select ) //{{{
{
if ( awake )
{
return update( select );
}
}
//}}}
function update( select ) //{{{
{
var c = Coords.getFixed();
resize( c.w, c.h );
moveto( c.x, c.y );
if ( options.shade ) Shade.updateRaw( c );
awake || show();
if ( select )
{
options.onSelect.call( api, unscale( c ) );
}
else
{
options.onChange.call( api, unscale( c ) );
}
}
//}}}
function setBgOpacity( opacity, force, now ) //{{{
{
if ( !awake && !force ) return;
if ( options.bgFade && !now )
{
$img.animate(
{
opacity: opacity
},
{
queue: false,
duration: options.fadeTime
} );
}
else
{
$img.css( 'opacity', opacity );
}
}
//}}}
function show() //{{{
{
$sel.show();
if ( options.shade ) Shade.opacity( bgopacity );
else setBgOpacity( bgopacity, true );
awake = true;
}
//}}}
function release() //{{{
{
disableHandles();
$sel.hide();
if ( options.shade ) Shade.opacity( 1 );
else setBgOpacity( 1 );
awake = false;
options.onRelease.call( api );
}
//}}}
function showHandles() //{{{
{
if ( seehandles )
{
$hdl_holder.show();
}
}
//}}}
function enableHandles() //{{{
{
seehandles = true;
if ( options.allowResize )
{
$hdl_holder.show();
return true;
}
}
//}}}
function disableHandles() //{{{
{
seehandles = false;
$hdl_holder.hide();
}
//}}}
function animMode( v ) //{{{
{
if ( v )
{
animating = true;
disableHandles();
}
else
{
animating = false;
enableHandles();
}
}
//}}}
function done() //{{{
{
animMode( false );
refresh();
}
//}}}
// Insert draggable elements {{{
// Insert border divs for outline
if ( options.dragEdges && $.isArray( options.createDragbars ) )
createDragbars( options.createDragbars );
if ( $.isArray( options.createHandles ) )
createHandles( options.createHandles );
if ( options.drawBorders && $.isArray( options.createBorders ) )
createBorders( options.createBorders );
//}}}
// This is a hack for iOS5 to support drag/move touch functionality
$( document ).bind( 'touchstart.jcrop-ios', function ( e )
{
if ( $( e.currentTarget ).hasClass( 'jcrop-tracker' ) ) e.stopPropagation();
} );
var $track = newTracker().mousedown( createDragger( 'move' ) ).css(
{
cursor: 'move',
position: 'absolute',
zIndex: 360
} );
if ( Touch.support )
{
$track.bind( 'touchstart.jcrop', Touch.createDragger( 'move' ) );
}
$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,
setBgOpacity: setBgOpacity,
done: done
};
}() );
//}}}
// Tracker Module {{{
var Tracker = ( function ()
{
var onMove = function () {},
onDone = function () {},
trackDoc = options.trackDocument;
function toFront( touch ) //{{{
{
$trk.css(
{
zIndex: 450
} );
if ( touch )
$( document )
.bind( 'touchmove.jcrop', trackTouchMove )
.bind( 'touchend.jcrop', trackTouchEnd );
else if ( trackDoc )
$( document )
.bind( 'mousemove.jcrop', trackMove )
.bind( 'mouseup.jcrop', trackUp );
}
//}}}
function toBack() //{{{
{
$trk.css(
{
zIndex: 290
} );
$( document ).unbind( '.jcrop' );
}
//}}}
function trackMove( e ) //{{{
{
onMove( mouseAbs( e ) );
return false;
}
//}}}
function trackUp( e ) //{{{
{
e.preventDefault();
e.stopPropagation();
if ( btndown )
{
btndown = false;
onDone( mouseAbs( e ) );
if ( Selection.isAwake() )
{
options.onSelect.call( api, unscale( Coords.getFixed() ) );
}
toBack();
onMove = function () {};
onDone = function () {};
}
return false;
}
//}}}
function activateHandlers( move, done, touch ) //{{{
{
btndown = true;
onMove = move;
onDone = done;
toFront( touch );
return false;
}
//}}}
function trackTouchMove( e ) //{{{
{
onMove( mouseAbs( Touch.cfilter( e ) ) );
return false;
}
//}}}
function trackTouchEnd( e ) //{{{
{
return trackUp( Touch.cfilter( e ) );
}
//}}}
function setCursor( t ) //{{{
{
$trk.css( 'cursor', t );
}
//}}}
if ( !trackDoc )
{
$trk.mousemove( trackMove ).mouseup( trackUp ).mouseout( trackUp );
}
$img.before( $trk );
return {
activateHandlers: activateHandlers,
setCursor: setCursor
};
}() );
//}}}
// KeyManager Module {{{
var KeyManager = ( function ()
{
var $keymgr = $( '<input type="radio" />' ).css(
{
position: 'fixed',
left: '-120px',
width: '12px'
} ).addClass( 'jcrop-keymgr' ),
$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( true );
}
e.preventDefault();
e.stopPropagation();
}
//}}}
function parseKey( e ) //{{{
{
if ( e.ctrlKey || e.metaKey )
{
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:
if ( options.allowSelect ) Selection.release();
break;
case 9:
return true;
}
return false;
}
//}}}
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 );
}
}
return {
watchKeys: watchKeys
};
}() );
//}}}
// }}}
// API methods {{{
function setClass( cname ) //{{{
{
$div.removeClass().addClass( cssClass( 'holder' ) ).addClass( cname );
}
//}}}
function animateTo( a, callback ) //{{{
{
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 ),
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;
x1 = animat[ 0 ];
y1 = animat[ 1 ];
x2 = animat[ 2 ];
y2 = animat[ 3 ];
Selection.animMode( true );
var anim_timer;
function queueAnimator()
{
window.setTimeout( animator, interv );
}
var animator = ( function ()
{
return function ()
{
pcent += ( 100 - pcent ) / velocity;
animat[ 0 ] = Math.round( x1 + ( ( pcent / 100 ) * ix1 ) );
animat[ 1 ] = Math.round( y1 + ( ( pcent / 100 ) * iy1 ) );
animat[ 2 ] = Math.round( x2 + ( ( pcent / 100 ) * ix2 ) );
animat[ 3 ] = Math.round( y2 + ( ( pcent / 100 ) * iy2 ) );
if ( pcent >= 99.8 )
{
pcent = 100;
}
if ( pcent < 100 )
{
setSelectRaw( animat );
queueAnimator();
}
else
{
Selection.done();
Selection.animMode( false );
if ( typeof ( callback ) === 'function' )
{
callback.call( api );
}
}
};
}() );
queueAnimator();
}
//}}}
function setSelect( rect ) //{{{
{
setSelectRaw( [ rect[ 0 ] / xscale, rect[ 1 ] / yscale, rect[ 2 ] / xscale, rect[ 3 ] / yscale ] );
options.onSelect.call( api, unscale( Coords.getFixed() ) );
Selection.enableHandles();
}
//}}}
function setSelectRaw( l ) //{{{
{
Coords.setPressed( [ l[ 0 ], l[ 1 ] ] );
Coords.setCurrent( [ l[ 2 ], l[ 3 ] ] );
Selection.update();
}
//}}}
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();
$origimg.css( 'visibility', 'visible' );
$( obj ).removeData( 'Jcrop' );
}
//}}}
function setImage( src, callback ) //{{{
{
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 );
Shade.resize( boundx, boundy );
enableCrop();
if ( typeof ( callback ) === 'function' )
{
callback.call( api );
}
};
img.src = src;
}
//}}}
function colorChangeMacro( $obj, color, now )
{
var mycolor = color || options.bgColor;
if ( options.bgFade && supportsColorFade() && options.fadeTime && !now )
{
$obj.animate(
{
backgroundColor: mycolor
},
{
queue: false,
duration: options.fadeTime
} );
}
else
{
$obj.css( 'backgroundColor', mycolor );
}
}
function interfaceUpdate( alt ) //{{{
// This method tweaks the interface based on options object.
// Called when options are changed and at end of initialization.
{
if ( options.allowResize )
{
if ( alt )
{
Selection.enableOnly();
}
else
{
Selection.enableHandles();
}
}
else
{
Selection.disableHandles();
}
Tracker.setCursor( options.allowSelect ? 'crosshair' : 'default' );
Selection.setCursor( options.allowMove ? 'move' : 'default' );
if ( options.hasOwnProperty( 'trueSize' ) )
{
xscale = options.trueSize[ 0 ] / boundx;
yscale = options.trueSize[ 1 ] / boundy;
}
if ( options.hasOwnProperty( 'setSelect' ) )
{
setSelect( options.setSelect );
Selection.done();
delete( options.setSelect );
}
Shade.refresh();
if ( options.bgColor != bgcolor )
{
colorChangeMacro(
options.shade ? Shade.getShades() : $div,
options.shade ?
( options.shadeColor || options.bgColor ) :
options.bgColor
);
bgcolor = options.bgColor;
}
if ( bgopacity != options.bgOpacity )
{
bgopacity = options.bgOpacity;
if ( options.shade ) Shade.refresh();
else Selection.setBgOpacity( bgopacity );
}
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 );
}
Selection.refresh();
}
//}}}
//}}}
if ( Touch.support ) $trk.bind( 'touchstart.jcrop', Touch.newSelection );
$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 ];
},
getOptions: function ()
{
// careful: internal values are returned
return options;
},
ui:
{
holder: $div,
selection: $sel
}
};
if ( is_msie ) $div.bind( 'selectstart', function ()
{
return false;
} );
$origimg.data( 'Jcrop', api );
return api;
};
$.fn.Jcrop = function ( options, callback ) //{{{
{
var api;
// 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
{
if ( this.tagName == 'IMG' )
$.Jcrop.Loader( this, function ()
{
$( this ).css(
{
display: 'block',
visibility: 'hidden'
} );
api = $.Jcrop( this, options );
if ( $.isFunction( callback ) ) callback.call( api );
} );
else
{
$( this ).css(
{
display: 'block',
visibility: 'hidden'
} );
api = $.Jcrop( this, options );
if ( $.isFunction( callback ) ) callback.call( api );
}
}
} );
// Return "this" so the object is chainable (jQuery-style)
return this;
};
//}}}
// $.Jcrop.Loader - basic image loader {{{
$.Jcrop.Loader = function ( imgobj, success, error )
{
var $img = $( imgobj ),
img = $img[ 0 ];
function completeCheck()
{
if ( img.complete )
{
$img.unbind( '.jcloader' );
if ( $.isFunction( success ) ) success.call( img );
}
else window.setTimeout( completeCheck, 50 );
}
$img
.bind( 'load.jcloader', completeCheck )
.bind( 'error.jcloader', function ( e )
{
$img.unbind( '.jcloader' );
if ( $.isFunction( error ) ) error.call( img );
} );
if ( img.complete && $.isFunction( success ) )
{
$img.unbind( '.jcloader' );
success.call( img );
}
};
//}}}
// Global Defaults {{{
$.Jcrop.defaults = {
// Basic Settings
allowSelect: true,
allowMove: true,
allowResize: true,
trackDocument: true,
// Styling Options
baseClass: 'jcrop',
addClass: null,
bgColor: 'black',
bgOpacity: 0.6,
bgFade: false,
borderOpacity: 0.4,
handleOpacity: 0.5,
handleSize: null,
aspectRatio: 0,
keySupport: true,
createHandles: [ 'n', 's', 'e', 'w', 'nw', 'ne', 'se', 'sw' ],
createDragbars: [ 'n', 's', 'e', 'w' ],
createBorders: [ 'n', 's', 'e', 'w' ],
drawBorders: true,
dragEdges: true,
fixedSupport: true,
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 ],
// Callbacks / Event Handlers
onChange: function () {},
onSelect: function () {},
onDblClick: function () {},
onRelease: function () {}
};
// }}}
}( jQuery ) );
@import url("http://netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css");
@import url("http://netdna.bootstrapcdn.com/bootswatch/3.1.0/cosmo/bootstrap.min.css");
.btn-file {
position: relative;
overflow: hidden;
margin:0 0 20px;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 999px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
/* jquery.Jcrop.css v0.9.12 - MIT License */
/*
The outer-most container in a typical Jcrop instance
If you are having difficulty with formatting related to styles
on a parent element, place any fixes here or in a like selector
You can also style this element if you want to add a border, etc
A better method for styling can be seen below with .jcrop-light
(Add a class to the holder and style elements for that extended class)
*/
.jcrop-holder {
direction: ltr;
text-align: left;
/* IE10 touch compatibility */
-ms-touch-action: none;
}
/* Selection Border */
.jcrop-vline,
.jcrop-hline {
background: #ffffff url("Jcrop.gif");
font-size: 0;
position: absolute;
}
.jcrop-vline {
height: 100%;
width: 1px !important;
}
.jcrop-vline.right {
right: 0;
}
.jcrop-hline {
height: 1px !important;
width: 100%;
}
.jcrop-hline.bottom {
bottom: 0;
}
/* Invisible click targets */
.jcrop-tracker {
height: 100%;
width: 100%;
/* "turn off" link highlight */
-webkit-tap-highlight-color: transparent;
/* disable callout, image save panel */
-webkit-touch-callout: none;
/* disable cut copy paste */
-webkit-user-select: none;
}
/* Selection Handles */
.jcrop-handle {
background-color: #333333;
border: 1px #eeeeee solid;
width: 7px;
height: 7px;
font-size: 1px;
}
.jcrop-handle.ord-n {
left: 50%;
margin-left: -4px;
margin-top: -4px;
top: 0;
}
.jcrop-handle.ord-s {
bottom: 0;
left: 50%;
margin-bottom: -4px;
margin-left: -4px;
}
.jcrop-handle.ord-e {
margin-right: -4px;
margin-top: -4px;
right: 0;
top: 50%;
}
.jcrop-handle.ord-w {
left: 0;
margin-left: -4px;
margin-top: -4px;
top: 50%;
}
.jcrop-handle.ord-nw {
left: 0;
margin-left: -4px;
margin-top: -4px;
top: 0;
}
.jcrop-handle.ord-ne {
margin-right: -4px;
margin-top: -4px;
right: 0;
top: 0;
}
.jcrop-handle.ord-se {
bottom: 0;
margin-bottom: -4px;
margin-right: -4px;
right: 0;
}
.jcrop-handle.ord-sw {
bottom: 0;
left: 0;
margin-bottom: -4px;
margin-left: -4px;
}
/* Dragbars */
.jcrop-dragbar.ord-n,
.jcrop-dragbar.ord-s {
height: 7px;
width: 100%;
}
.jcrop-dragbar.ord-e,
.jcrop-dragbar.ord-w {
height: 100%;
width: 7px;
}
.jcrop-dragbar.ord-n {
margin-top: -4px;
}
.jcrop-dragbar.ord-s {
bottom: 0;
margin-bottom: -4px;
}
.jcrop-dragbar.ord-e {
margin-right: -4px;
right: 0;
}
.jcrop-dragbar.ord-w {
margin-left: -4px;
}
/* The "jcrop-light" class/extension */
.jcrop-light .jcrop-vline,
.jcrop-light .jcrop-hline {
background: #ffffff;
filter: alpha(opacity=70) !important;
opacity: .70!important;
}
.jcrop-light .jcrop-handle {
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
background-color: #000000;
border-color: #ffffff;
border-radius: 3px;
}
/* The "jcrop-dark" class/extension */
.jcrop-dark .jcrop-vline,
.jcrop-dark .jcrop-hline {
background: #000000;
filter: alpha(opacity=70) !important;
opacity: 0.7 !important;
}
.jcrop-dark .jcrop-handle {
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
background-color: #ffffff;
border-color: #000000;
border-radius: 3px;
}
/* Simple macro to turn off the antlines */
.solid-line .jcrop-vline,
.solid-line .jcrop-hline {
background: #ffffff;
}
/* Fix for twitter bootstrap et al. */
.jcrop-holder img,
img.jcrop-preview {
max-width: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment