├── .gitignore
├── Gruntfile.js
├── Jcrop.gif
├── README.md
├── dist
├── css
│ ├── mr-uploader.css
│ └── mr-uploader.min.css
└── js
│ ├── mr-uploader.all.js
│ ├── mr-uploader.all.min.js
│ └── mr-uploader.js
├── examples
├── aspect-ratio
│ └── index.html
├── simple
│ └── index.html
└── upload.php
├── package.json
├── src
├── style.css
└── uploader.coffee
└── vendors
├── jquery.Jcrop.min.css
└── jquery.Jcrop.min.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /* global module:false */
2 | module.exports = function(grunt) {
3 |
4 | // Project configuration.
5 | grunt.initConfig({
6 | // Metadata.
7 | meta: {
8 | version: '0.1.0'
9 | },
10 | banner: '/*! MrUploader - v<%= meta.version %> - ' +
11 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
12 | '* http://github.com/vinelab/mr-uploader\n' +
13 | '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +
14 | 'Vinelab; Licensed MIT */\n'
15 | });
16 |
17 | // Task configuration.
18 | grunt.loadNpmTasks('grunt-contrib-concat');
19 | grunt.config('concat', {
20 | options: {
21 | banner: '<%= banner %>',
22 | stripBanners: true
23 | },
24 | dist: {
25 | src: ['vendors/jquery.Jcrop.min.js', 'dist/js/mr-uploader.js'],
26 | dest: 'dist/js/mr-uploader.all.js'
27 | },
28 | css: {
29 | src: ['src/style.css', 'vendors/jquery.Jcrop.min.css'],
30 | dest: 'dist/css/mr-uploader.css'
31 | }
32 | });
33 |
34 | grunt.loadNpmTasks('grunt-contrib-uglify');
35 | grunt.config('uglify', {
36 | options: {
37 | banner: '<%= banner %>',
38 | mangle: false
39 | },
40 | all: {
41 | src: '<%= concat.dist.dest %>',
42 | dest: 'dist/js/mr-uploader.all.min.js'
43 | }
44 | });
45 |
46 | grunt.loadNpmTasks('grunt-contrib-coffee');
47 | grunt.config('coffee', {
48 | compile: {
49 | options: {bare: true},
50 | files: {'dist/js/mr-uploader.js': 'src/uploader.coffee'}
51 | }
52 | });
53 |
54 | grunt.loadNpmTasks('grunt-contrib-cssmin');
55 | grunt.config('cssmin', {
56 | style: {
57 | files: [{
58 | expand: true,
59 | cwd: 'dist/css',
60 | src: ['*.css'],
61 | dest: 'dist/css',
62 | ext: '.min.css'
63 | }]
64 | }
65 | });
66 |
67 | grunt.loadNpmTasks('grunt-contrib-watch');
68 | grunt.config('watch', {
69 | coffee: {
70 | files: ['src/**/*'],
71 | tasks: ['clean', 'coffee', 'concat', 'uglify', 'cssmin']
72 | }
73 | });
74 |
75 | grunt.loadNpmTasks('grunt-contrib-clean');
76 | grunt.config('clean', {
77 | css: {
78 | src: ['dist/css']
79 | }
80 | });
81 |
82 | };
83 |
--------------------------------------------------------------------------------
/Jcrop.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Vinelab/mr-uploader/31a36024cdb3836fad3733e51b430755c77ab62d/Jcrop.gif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mr. Uploader
2 | jQuery plugin for simplified photo cropping and uploading.
3 |
4 | ## Installation
5 |
6 | - jQuery is a requirement and must be loaded before the js file of this package.
7 | - Clone this repo
8 | - Copy the files from the `dist/` directory into the directory where you'll be serving your static assets
9 |
10 | ## Usage
11 |
12 | - Use `upload = $('selector').mrUploader({uploadUrl: '/upload'});` to start using this package.
13 |
14 | - Here's full snippet:
15 |
16 | ```html
17 |
18 |
19 |
20 | Mr. Uploader
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 | ```
36 |
37 | - The `upload` variable will now be a `MrUploader` instance
38 | - Access the photos uploaded using the `uploads` key on the instance
39 | - A sample of an `upload` is the following:
40 |
41 | ```javascript
42 | {
43 | "response": {}, // The upload response from the server
44 | "$image", // A jQuery image object representing the uploaded image
45 | "meta": {
46 | "width": 1920, // Original image width
47 | "height": 1080, // Original image height
48 | "size": 140210, // Original image size in bytes
49 | "type": 'image/png', // Image MIME type
50 | "name": 'my-image.png' // Original image file name on client's disk
51 | },
52 | "crop": {
53 | "width": 123, // Crop width
54 | "height": 456, // Crop height
55 | "x": 834, // Crop X
56 | "x2": 747, // Crop X2
57 | "y": 773, // Crop Y
58 | "y2": 836 // Crop Y2
59 | }
60 | }
61 | ```
62 |
63 | For more examples please check the `example` folder of this package.
64 |
65 | ## Event Handlers
66 | You may attach handlers to events to be notified when they occur.
67 |
68 | ### Events
69 |
70 | #### upload
71 | This event will be called when an upload is **successfully** completed
72 |
73 | ```javascript
74 | upload = $('element').mrUploader();
75 | upload.on('upload', function (event, data) {
76 | // e is the jQuery event
77 | // data is the upload data
78 | });
79 | ```
80 |
--------------------------------------------------------------------------------
/dist/css/mr-uploader.css:
--------------------------------------------------------------------------------
1 | /*! MrUploader - v0.1.0 - 2015-03-18
2 | * http://github.com/vinelab/mr-uploader
3 | * Copyright (c) 2015 Vinelab; Licensed MIT */
4 | .mr-uploader-fullscreen-mode {
5 | top: 0;
6 | left: 0;
7 | width: 100%;
8 | height: 100%;
9 | z-index: 99999;
10 | position: fixed;
11 | overflow: scroll;
12 | font-family: Arial;
13 | border: 0!important;
14 | padding: 15px 30px 15px;
15 | color: #272727;
16 | background: #FAFAFB!important;
17 | }
18 |
19 | .mr-uploader-fullscreen-close {
20 | float:left;
21 | font-size: 28px;
22 | cursor: pointer;
23 | font-color: #ededed;
24 | text-decoration: none;
25 | }
26 |
27 | #mr-uploader-file-input {
28 | margin: 0 auto;
29 | padding-bottom: 10px;
30 | }
31 |
32 | #mr-uploader-images {
33 | min-height: 200px;
34 | }
35 |
36 | #mr-uploader-images .jcrop-holder {
37 | text-align: : center;
38 | margin: 0 auto;
39 | }
40 |
41 | .mr-uploader-preview {
42 | position: relative;
43 | float: left;
44 | font-size: 30px;
45 | margin-left: 10px;
46 | overflow: hidden;
47 | background-color: transparent;
48 | box-shadow: 0px 0px 5px 1px #888;
49 | -moz-box-shadow: inset 0px 0px 5px 1px #888;
50 | -webkit-box-shadow: inset 0px 0px 5px 1px #888;
51 | }
52 |
53 | .mr-uploader-ar-landscape {
54 | width: 300px;
55 | height: 200px;
56 | }
57 |
58 | .mr-uploader-ar-portrait {
59 | width: 200px;
60 | height: 300px;
61 | }
62 |
63 | .mr-uploader-ar-square {
64 | width: 200px;
65 | height: 200px;
66 | }
67 |
68 | .mr-uploader-preview-overlay {
69 | position: absolute;
70 | width: 100%;
71 | height: 100%;
72 | opacity: 0.8;
73 | text-align: center;
74 | text-decoration: bold;
75 | color: green;
76 | vertical-align: middle;
77 | line-height: 200px;
78 | text-decoration: bold;
79 | background-color: #ededed;
80 | }
81 |
82 | .mr-uploader-preview .error {
83 | color: red;
84 | font-size: 22px;
85 | }
86 |
87 | .mr-uploader-spinner {
88 | margin: 0 auto;
89 | width: 70px;
90 | text-align: center;
91 | }
92 |
93 | .mr-uploader-spinner > div {
94 | width: 18px;
95 | height: 18px;
96 | background-color: #333;
97 |
98 | border-radius: 100%;
99 | display: inline-block;
100 | -webkit-animation: bouncedelay 0.8s infinite ease-in-out;
101 | animation: bouncedelay 0.8s infinite ease-in-out;
102 | /* Prevent first frame from flickering when animation starts */
103 | -webkit-animation-fill-mode: both;
104 | animation-fill-mode: both;
105 | }
106 |
107 | .mr-uploader-spinner-bounce1 {
108 | -webkit-animation-delay: -0.32s;
109 | animation-delay: -0.32s;
110 | }
111 |
112 | .mr-uploader-spinner-bounce2 {
113 | -webkit-animation-delay: -0.16s;
114 | animation-delay: -0.16s;
115 | }
116 |
117 | @-webkit-keyframes bouncedelay {
118 | 0%, 80%, 100% { -webkit-transform: scale(0.0) }
119 | 40% { -webkit-transform: scale(1.0) }
120 | }
121 |
122 | @keyframes bouncedelay {
123 | 0%, 80%, 100% {
124 | transform: scale(0.0);
125 | -webkit-transform: scale(0.0);
126 | } 40% {
127 | transform: scale(1.0);
128 | -webkit-transform: scale(1.0);
129 | }
130 | }
131 |
132 | .mr-uploader-ratio-options {
133 | margin: 30px 0px 30px 0px;
134 | }
135 |
136 | .jcrop-holder{direction:ltr;text-align:left;}
137 | .jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif);font-size:0;position:absolute;}
138 | .jcrop-vline{height:100%;width:1px!important;}
139 | .jcrop-vline.right{right:0;}
140 | .jcrop-hline{height:1px!important;width:100%;}
141 | .jcrop-hline.bottom{bottom:0;}
142 | .jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
143 | .jcrop-handle{background-color:#333;border:1px #EEE solid;font-size:1px;height:7px;width:7px;}
144 | .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
145 | .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
146 | .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
147 | .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
148 | .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
149 | .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
150 | .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
151 | .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
152 | .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
153 | .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
154 | .jcrop-dragbar.ord-n{margin-top:-4px;}
155 | .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
156 | .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
157 | .jcrop-dragbar.ord-w{margin-left:-4px;}
158 | .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.70!important;}
159 | .jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
160 | .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important;}
161 | .jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
162 | .solid-line .jcrop-vline,.solid-line .jcrop-hline{background:#FFF;}
163 | .jcrop-holder img,img.jcrop-preview{max-width:none;}
164 |
--------------------------------------------------------------------------------
/dist/css/mr-uploader.min.css:
--------------------------------------------------------------------------------
1 | /*! MrUploader - v0.1.0 - 2015-03-18
2 | * http://github.com/vinelab/mr-uploader
3 | * Copyright (c) 2015 Vinelab; Licensed MIT */.mr-uploader-fullscreen-mode{top:0;left:0;width:100%;height:100%;z-index:99999;position:fixed;overflow:scroll;font-family:Arial;border:0!important;padding:15px 30px;color:#272727;background:#FAFAFB!important}.mr-uploader-fullscreen-close{float:left;font-size:28px;cursor:pointer;font-color:#ededed;text-decoration:none}#mr-uploader-file-input{margin:0 auto;padding-bottom:10px}#mr-uploader-images{min-height:200px}#mr-uploader-images .jcrop-holder{text-align:center;margin:0 auto}.mr-uploader-preview{position:relative;float:left;font-size:30px;margin-left:10px;overflow:hidden;background-color:transparent;box-shadow:0 0 5px 1px #888;-moz-box-shadow:inset 0 0 5px 1px #888;-webkit-box-shadow:inset 0 0 5px 1px #888}.mr-uploader-ar-landscape{width:300px;height:200px}.mr-uploader-ar-portrait{width:200px;height:300px}.mr-uploader-ar-square{width:200px;height:200px}.mr-uploader-preview-overlay{position:absolute;width:100%;height:100%;opacity:.8;text-align:center;color:green;vertical-align:middle;line-height:200px;text-decoration:bold;background-color:#ededed}.mr-uploader-preview .error{color:red;font-size:22px}.mr-uploader-spinner{margin:0 auto;width:70px;text-align:center}.mr-uploader-spinner>div{width:18px;height:18px;background-color:#333;border-radius:100%;display:inline-block;-webkit-animation:bouncedelay .8s infinite ease-in-out;animation:bouncedelay .8s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.mr-uploader-spinner-bounce1{-webkit-animation-delay:-.32s;animation-delay:-.32s}.mr-uploader-spinner-bounce2{-webkit-animation-delay:-.16s;animation-delay:-.16s}@-webkit-keyframes bouncedelay{0%,100%,80%{-webkit-transform:scale(0)}40%{-webkit-transform:scale(1)}}@keyframes bouncedelay{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.mr-uploader-ratio-options{margin:30px 0}.jcrop-holder{direction:ltr;text-align:left}.jcrop-hline,.jcrop-vline{background:url(Jcrop.gif) #FFF;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}.jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%}.jcrop-handle{background-color:#333;border:1px solid #EEE;font-size:1px;height:7px;width:7px}.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}.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}.jcrop-light .jcrop-hline,.jcrop-light .jcrop-vline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.7!important}.jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px}.jcrop-dark .jcrop-hline,.jcrop-dark .jcrop-vline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important}.jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px}.solid-line .jcrop-hline,.solid-line .jcrop-vline{background:#FFF}.jcrop-holder img,img.jcrop-preview{max-width:none}
--------------------------------------------------------------------------------
/dist/js/mr-uploader.all.js:
--------------------------------------------------------------------------------
1 | /*! MrUploader - v0.1.0 - 2015-03-18
2 | * http://github.com/vinelab/mr-uploader
3 | * Copyright (c) 2015 Vinelab; Licensed MIT */
4 | (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
5 | (),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
6 | (0,5)==="touch"),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("").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],
7 | 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
8 | .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").
9 | 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("").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(""),I=a("").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("").width("100%").height("100%").css("zIndex",320),K=a("").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("
").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"
10 | ,"touchmove","touchend"],c=document.createElement("div"),d;try{for(d=0;da+f&&(f-=f+a),0>b+g&&(g-=g+b),FE&&(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-ah&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):rh&&(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 cP&&(c=d>0?a+P:a-P),Q&&Math.abs
12 | (f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)0?b+S/U:b-S/U),R/T&&Math.abs(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("").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.
13 | 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("").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("").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("").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,e=l(a,c++
14 | ).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("").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(
18 | 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:null,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
19 | :!0,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);
20 |
21 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
22 | __slice = [].slice;
23 |
24 | (function($, window) {
25 | var MrUploader;
26 | MrUploader = (function() {
27 | MrUploader.prototype.defaults = {
28 | multiple: true,
29 | cropping: true,
30 | onClick: true,
31 | uploadUrl: '/upload.php',
32 | aspectRatio: 'landscape',
33 | crop: {
34 | boxWidth: 800,
35 | aspectRatio: 3 / 2,
36 | keySupport: false,
37 | allowSelect: false,
38 | minSize: [300, 200],
39 | setSelect: [0, 0, 600, 400]
40 | }
41 | };
42 |
43 | function MrUploader(el, options) {
44 | this.hideFullscreen = __bind(this.hideFullscreen, this);
45 | this.setAspectRatio = __bind(this.setAspectRatio, this);
46 | this.setLandscapeAspectRatio = __bind(this.setLandscapeAspectRatio, this);
47 | this.setPortraitAspectRatio = __bind(this.setPortraitAspectRatio, this);
48 | this.setSquareAspectRatio = __bind(this.setSquareAspectRatio, this);
49 | this.show = __bind(this.show, this);
50 | this.showFullscreen = __bind(this.showFullscreen, this);
51 | this.onCloseClick = __bind(this.onCloseClick, this);
52 | this.getStagedFileMeta = __bind(this.getStagedFileMeta, this);
53 | this.changePreview = __bind(this.changePreview, this);
54 | this.getPreviewHeight = __bind(this.getPreviewHeight, this);
55 | this.getPreviewWidth = __bind(this.getPreviewWidth, this);
56 | this.onReaderLoad = __bind(this.onReaderLoad, this);
57 | this.onUploaderFileChanged = __bind(this.onUploaderFileChanged, this);
58 | this.onUploadClick = __bind(this.onUploadClick, this);
59 | this.onCancelClick = __bind(this.onCancelClick, this);
60 | this.resetCroppingArea = __bind(this.resetCroppingArea, this);
61 | this.setStaged = __bind(this.setStaged, this);
62 | this.onCroppingSelected = __bind(this.onCroppingSelected, this);
63 | this.showPhotoActionElements = __bind(this.showPhotoActionElements, this);
64 | this.hidePhotoActionElements = __bind(this.hidePhotoActionElements, this);
65 | this.getCroppingAreaContent = __bind(this.getCroppingAreaContent, this);
66 | this.getRatioOptions = __bind(this.getRatioOptions, this);
67 | this.getHeaderContent = __bind(this.getHeaderContent, this);
68 | this.onElementClick = __bind(this.onElementClick, this);
69 | this.on = __bind(this.on, this);
70 | this.$el = $(el);
71 | this.$options = $.extend(true, {}, this.defaults, options);
72 | this.photoActionsElements = [];
73 | this.addContent();
74 | if (this.$options.onClick === true) {
75 | this.$el.click(this.onElementClick);
76 | }
77 | this.setStaged(null);
78 | this.uploads = [];
79 | }
80 |
81 | MrUploader.prototype.on = function(event, callback) {
82 | return $(this).on(event, callback);
83 | };
84 |
85 | MrUploader.prototype.onElementClick = function(e) {
86 | e.preventDefault();
87 | return this.showFullscreen();
88 | };
89 |
90 | MrUploader.prototype.getHeaderContent = function() {
91 | var close, header, ratioOptions, title;
92 | header = $('');
93 | close = $('');
94 | close.click(this.onCloseClick);
95 | title = $('').text('Choose & Crop');
96 | ratioOptions = this.getRatioOptions();
97 | this.photoActionsElements.push(ratioOptions);
98 | header.append(close, title, ratioOptions);
99 | return header;
100 | };
101 |
102 | MrUploader.prototype.getRatioOptions = function() {
103 | var landscape, landscapeLabel, portrait, portraitLabel, square, squareLabel;
104 | squareLabel = $(' ');
105 | this.squareInput = $(' ');
106 | this.squareInput.click((function(_this) {
107 | return function() {
108 | return _this.setSquareAspectRatio();
109 | };
110 | })(this));
111 | if (this.$options.aspectRatio === 'square') {
112 | this.squareInput.attr('checked', true);
113 | }
114 | square = $('').append(squareLabel, this.squareInput);
115 | portraitLabel = $(' ');
116 | this.portraitInput = $(' ');
117 | if (this.$options.aspectRatio === 'portrait') {
118 | this.portraitInput.attr('checked', true);
119 | }
120 | this.portraitInput.click((function(_this) {
121 | return function() {
122 | return _this.setPortraitAspectRatio();
123 | };
124 | })(this));
125 | portrait = $('').append(portraitLabel, this.portraitInput);
126 | landscapeLabel = $(' ');
127 | this.landscapeInput = $(' ');
128 | if (this.$options.aspectRatio === 'landscape') {
129 | this.landscapeInput.attr('checked', true);
130 | }
131 | this.landscapeInput.click((function(_this) {
132 | return function() {
133 | return _this.setLandscapeAspectRatio();
134 | };
135 | })(this));
136 | landscape = $('').append(landscapeLabel, this.landscapeInput);
137 | return $('').append(square).append(portrait).append(landscape);
138 | };
139 |
140 | MrUploader.prototype.getCroppingAreaContent = function() {
141 | var cancel, crop, upload;
142 | crop = $('');
143 | this.$input = $('');
144 | this.$input.change(this.onUploaderFileChanged);
145 | crop.append(this.$input);
146 | this.$photos = $('
');
147 | crop.append(this.$photos);
148 | upload = $('');
149 | upload.click(this.onUploadClick);
150 | cancel = $('');
151 | cancel.click(this.onCancelClick);
152 | this.photoActionsElements.push(upload, cancel);
153 | crop.append(upload);
154 | crop.append(cancel);
155 | return crop;
156 | };
157 |
158 | MrUploader.prototype.addContent = function() {
159 | this.$container = $('').hide().addClass('mr-uploader-fullscreen-mode').css('text-align', 'center');
160 | this.$container.append(this.getHeaderContent());
161 | this.$croppingArea = this.getCroppingAreaContent();
162 | this.$container.append(this.$croppingArea);
163 | this.$container.append('
');
164 | this.$previews = $('');
165 | this.$container.append(this.$previews);
166 | this.hidePhotoActionElements();
167 | return $('body').append(this.$container);
168 | };
169 |
170 | MrUploader.prototype.hidePhotoActionElements = function() {
171 | var element, _i, _len, _ref, _results;
172 | _ref = this.photoActionsElements;
173 | _results = [];
174 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
175 | element = _ref[_i];
176 | _results.push(element.hide());
177 | }
178 | return _results;
179 | };
180 |
181 | MrUploader.prototype.showPhotoActionElements = function() {
182 | var element, _i, _len, _ref, _results;
183 | _ref = this.photoActionsElements;
184 | _results = [];
185 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
186 | element = _ref[_i];
187 | _results.push(element.show());
188 | }
189 | return _results;
190 | };
191 |
192 | MrUploader.prototype.onCroppingSelected = function(crop, image, meta) {
193 | crop = {
194 | x: Math.round(crop.x),
195 | y: Math.round(crop.y),
196 | x2: Math.round(crop.x2),
197 | y2: Math.round(crop.y2),
198 | width: Math.round(crop.w),
199 | height: Math.round(crop.h)
200 | };
201 | meta.width = image.width();
202 | meta.height = image.height();
203 | return this.setStaged({
204 | $image: image,
205 | meta: meta,
206 | crop: crop
207 | });
208 | };
209 |
210 | MrUploader.prototype.setStaged = function(staged) {
211 | this.staged = staged;
212 | };
213 |
214 | MrUploader.prototype.resetCroppingArea = function() {
215 | this.$croppingArea.html(this.getCroppingAreaContent());
216 | return this.hidePhotoActionElements();
217 | };
218 |
219 | MrUploader.prototype.onCancelClick = function(e) {
220 | this.resetCroppingArea();
221 | this.setStaged(null);
222 | return this.$preview.remove();
223 | };
224 |
225 | MrUploader.prototype.onUploadClick = function(e) {
226 | var $overlay, crop, meta, photo, request, url;
227 | e.preventDefault();
228 | if (this.staged == null) {
229 | return alert('Please choose a photo to upload');
230 | }
231 | url = this.$options.uploadUrl;
232 | photo = this.staged.$image.attr('src');
233 | meta = this.staged.meta;
234 | crop = this.staged.crop;
235 | $overlay = this.getPreviewOverlay();
236 | request = $.ajax({
237 | type: 'POST',
238 | url: url,
239 | cache: false,
240 | dataType: 'json',
241 | data: {
242 | photo: photo,
243 | meta: meta,
244 | crop: crop
245 | },
246 | beforeSend: (function(_this) {
247 | return function(xhr, settings) {
248 | _this.$preview.find('.mr-uploader-preview-overlay').each(function() {
249 | return this.remove();
250 | });
251 | _this.$preview.prepend($overlay);
252 | return _this.Jcrop.disable();
253 | };
254 | })(this)
255 | });
256 | request.done((function(_this) {
257 | return function(response, status, xhr) {
258 | _this.staged.response = response;
259 | _this.uploads.push(_this.staged);
260 | _this.resetCroppingArea();
261 | $overlay.html('✓');
262 | $(_this).trigger('upload', _this.staged);
263 | return _this.setStaged(null);
264 | };
265 | })(this));
266 | return request.fail((function(_this) {
267 | return function(xhr, status, error) {
268 | return $overlay.addClass('error').html('× Upload failed, please retry');
269 | };
270 | })(this));
271 | };
272 |
273 | MrUploader.prototype.getPreviewOverlay = function() {
274 | return $('').append('');
275 | };
276 |
277 | MrUploader.prototype.onUploaderFileChanged = function(e) {
278 | var file, input, reader, _i, _len, _ref;
279 | input = this.$input[0];
280 | if ((input.files != null) && input.files.length > 0) {
281 | reader = new FileReader();
282 | reader.onload = this.onReaderLoad;
283 | _ref = input.files;
284 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
285 | file = _ref[_i];
286 | reader.readAsDataURL(file);
287 | }
288 | this.$input.hide();
289 | return this.showPhotoActionElements();
290 | }
291 | };
292 |
293 | MrUploader.prototype.onReaderLoad = function(e) {
294 | var crop, img, meta, previewImage, self;
295 | img = $('
');
296 | crop = this.$options.crop;
297 | meta = this.getStagedFileMeta();
298 | this.$preview = $('');
299 | previewImage = $('
').attr('src', e.target.result);
300 | this.$preview.html(previewImage);
301 | this.$previews.prepend(this.$preview);
302 | crop.onSelect = (function(_this) {
303 | return function(crop) {
304 | return _this.onCroppingSelected(crop, img, meta);
305 | };
306 | })(this);
307 | crop.onChange = (function(_this) {
308 | return function(crop) {
309 | return _this.changePreview(crop, previewImage);
310 | };
311 | })(this);
312 | this.$photos.html(img);
313 | self = this;
314 | return img.Jcrop(crop, function() {
315 | return self.Jcrop = this;
316 | });
317 | };
318 |
319 | MrUploader.prototype.getPreviewWidth = function() {
320 | switch (this.$options.aspectRatio) {
321 | case 'square':
322 | case 'portrait':
323 | return 200;
324 | case 'landscape':
325 | return 300;
326 | }
327 | };
328 |
329 | MrUploader.prototype.getPreviewHeight = function() {
330 | switch (this.$options.aspectRatio) {
331 | case 'square':
332 | case 'landscape':
333 | return 200;
334 | case 'portrait':
335 | return 300;
336 | }
337 | };
338 |
339 | MrUploader.prototype.changePreview = function(crop, $thumbnail) {
340 | var height, rx, ry, width;
341 | if (this.staged != null) {
342 | width = this.getPreviewWidth();
343 | height = this.getPreviewHeight();
344 | rx = width / crop.w;
345 | ry = height / crop.h;
346 | return $thumbnail.css({
347 | marginTop: '-' + Math.round(ry * crop.y) + 'px',
348 | marginLeft: '-' + Math.round(rx * crop.x) + 'px',
349 | width: Math.round(rx * this.staged.meta.width) + 'px',
350 | height: Math.round(ry * this.staged.meta.height) + 'px'
351 | });
352 | }
353 | };
354 |
355 | MrUploader.prototype.getStagedFileMeta = function() {
356 | var file, input;
357 | input = this.$input[0];
358 | file = input.files[0];
359 | return {
360 | name: file.name,
361 | size: file.size,
362 | type: file.type
363 | };
364 | };
365 |
366 | MrUploader.prototype.onCloseClick = function() {
367 | return this.hideFullscreen();
368 | };
369 |
370 | MrUploader.prototype.showFullscreen = function() {
371 | return this.$container.fadeIn();
372 | };
373 |
374 | MrUploader.prototype.show = function() {
375 | return this.showFullscreen();
376 | };
377 |
378 | MrUploader.prototype.setSquareAspectRatio = function() {
379 | var _ref, _ref1, _ref2, _ref3;
380 | if (this.$options.aspectRatio !== 'square') {
381 | if ((_ref = this.$preview) != null) {
382 | _ref.removeClass('mr-uploader-ar-' + this.$options.aspectRatio);
383 | }
384 | this.$options.aspectRatio = 'square';
385 | this.$options.crop.aspectRatio = 2 / 2;
386 | this.$options.crop.minSize = [200, 200];
387 | if ((_ref1 = this.Jcrop) != null) {
388 | _ref1.setOptions(this.$options.crop);
389 | }
390 | if ((_ref2 = this.$preview) != null) {
391 | _ref2.addClass('mr-uploader-ar-' + this.$options.aspectRatio);
392 | }
393 | return (_ref3 = this.squareInput) != null ? _ref3.attr('checked', true) : void 0;
394 | }
395 | };
396 |
397 | MrUploader.prototype.setPortraitAspectRatio = function() {
398 | var _ref, _ref1, _ref2, _ref3;
399 | if (this.$options.aspectRatio !== 'portrait') {
400 | if ((_ref = this.$preview) != null) {
401 | _ref.removeClass('mr-uploader-ar-' + this.$options.aspectRatio);
402 | }
403 | this.$options.aspectRatio = 'portrait';
404 | this.$options.crop.aspectRatio = 2 / 3;
405 | this.$options.crop.minSize = [200, 300];
406 | if ((_ref1 = this.Jcrop) != null) {
407 | _ref1.setOptions(this.$options.crop);
408 | }
409 | if ((_ref2 = this.$preview) != null) {
410 | _ref2.addClass('mr-uploader-ar-' + this.$options.aspectRatio);
411 | }
412 | return (_ref3 = this.portraitInput) != null ? _ref3.attr('checked', true) : void 0;
413 | }
414 | };
415 |
416 | MrUploader.prototype.setLandscapeAspectRatio = function() {
417 | var _ref, _ref1, _ref2, _ref3;
418 | if (this.$options.aspectRatio !== 'landscape') {
419 | if ((_ref = this.$preview) != null) {
420 | _ref.removeClass('mr-uploader-ar-' + this.$options.aspectRatio);
421 | }
422 | this.$options.aspectRatio = 'landscape';
423 | this.$options.crop.aspectRatio = 3 / 2;
424 | this.$options.crop.minSize = [300, 200];
425 | if ((_ref1 = this.Jcrop) != null) {
426 | _ref1.setOptions(this.$options.crop);
427 | }
428 | if ((_ref2 = this.$preview) != null) {
429 | _ref2.addClass('mr-uploader-ar-' + this.$options.aspectRatio);
430 | }
431 | return (_ref3 = this.landscapeInput) != null ? _ref3.attr('checked', true) : void 0;
432 | }
433 | };
434 |
435 | MrUploader.prototype.setAspectRatio = function(aspectRatio) {
436 | switch (aspectRatio) {
437 | case 'square':
438 | return this.setSquareAspectRatio();
439 | case 'portrait':
440 | return this.setPortraitAspectRatio();
441 | case 'landscape':
442 | return this.setLandscapeAspectRatio();
443 | }
444 | };
445 |
446 | MrUploader.prototype.hideFullscreen = function() {
447 | return this.$container.fadeOut();
448 | };
449 |
450 | return MrUploader;
451 |
452 | })();
453 | return $.fn.extend({
454 | mrUploader: function() {
455 | var $this, args, data, option, upload;
456 | option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
457 | $this = this.first();
458 | data = $this.data('mrUploader');
459 | if (!data) {
460 | upload = new MrUploader(this, option);
461 | $this.data('mrUploader', (data = upload));
462 | return upload;
463 | }
464 | if (typeof option === 'string') {
465 | return data[optiokn].apply(data, args);
466 | }
467 | }
468 | });
469 | })(window.jQuery, window);
470 |
--------------------------------------------------------------------------------
/dist/js/mr-uploader.all.min.js:
--------------------------------------------------------------------------------
1 | /*! MrUploader - v0.1.0 - 2015-03-18
2 | * http://github.com/vinelab/mr-uploader
3 | * Copyright (c) 2015 Vinelab; Licensed MIT */
4 | !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){"object"!=typeof b&&(b={}),d=a.extend(d,b),a.each(["onChange","onSelect","onRelease","onDblClick"],function(a,b){"function"!=typeof d[b]&&(d[b]=function(){})})}function o(a,b,c){if(e=l(D),bc.setCursor("move"===a?a:a+"-resize"),"move"===a)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.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}else 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}_.setCurrent(c),bb.update()}}function q(a){var b=a;return bd.watchKeys(),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:"move"!==a||d.allowMove?(e=l(D),W=!0,o(a,m(b)),b.stopPropagation(),b.preventDefault(),!1):!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(){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,"touch"===a.type.substring(0,5)),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("").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){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 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),100>q?(bh(k),t()):(bb.done(),bb.animMode(!1),"function"==typeof b&&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],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+2*L).height(F+2*L),G.width(E).height(F),ba.resize(E,F),bm(),"function"==typeof b&&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.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 e,d=a.extend({},a.Jcrop.defaults),f=navigator.userAgent.toLowerCase(),g=/msie/.test(f),h=/msie [1-6]\./.test(f);"object"!=typeof b&&(b=a(b)[0]),"object"!=typeof c&&(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("IMG"==b.tagName){if(0!=A[0].width&&0!=A[0].height)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").css(z).show();D.width(A.width()),D.height(A.height()),A.after(D).hide()}else D=A.css(z).show(),B=!1,null===d.shade&&(d.shade=!0);t(D,d.boxWidth,d.boxHeight);var E=D.width(),F=D.height(),G=a("").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(""),I=a("").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("").width("100%").height("100%").css("zIndex",320),K=a("").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("
").attr("src",D.attr("src")).css(z).width(E).height(F),I.append(H)),h&&K.css({overflowY:"hidden"});var P,Q,R,S,T,U,W,X,Y,L=d.boundary,M=y().width(E+2*L).height(F+2*L).css({position:"absolute",top:i(-L),left:i(-L),zIndex:290}).mousedown(w),N=d.bgColor,O=d.bgOpacity;e=l(D);var Z=function(){function a(){var d,a={},b=["touchstart","touchmove","touchend"],c=document.createElement("div");try{for(d=0;da+f&&(f-=f+a),0>b+g&&(g-=g+b),e+g>F&&(g+=F-(e+g)),c+f>E&&(f+=E-(c+f)),a+=f,c+=f,b+=g,e+=g}function l(a){var b=m();switch(a){case"ne":return[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 r,s,t,u,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;return 0===h&&(h=10*E),0===i&&(i=10*F),f>n?(s=e,t=m*f,r=0>j?a-t:t+a,0>r?(r=0,u=Math.abs((r-a)/f),s=0>k?b-u:u+b):r>E&&(r=E,u=Math.abs((r-a)/f),s=0>k?b-u:u+b)):(r=c,u=l/f,s=0>k?b-u:b+u,0>s?(s=0,t=Math.abs((s-b)*f),r=0>j?a-t:t+a):s>F&&(s=F,t=Math.abs(s-b)*f,r=0>j?a-t:t+a)),r>a?(g>r-a?r=a+g:r-a>h&&(r=a+h),s=s>b?b+(r-a)/f:b-(r-a)/f):a>r&&(g>a-r?r=a-g:a-r>h&&(r=a-h),s=s>b?b+(a-r)/f:b-(a-r)/f),0>r?(a-=r,r=0):r>E&&(a-=r-E,r=E),0>s?(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 a>c&&(e=c,f=a),b>d&&(g=d,h=b),[e,g,f,h]}function p(){var g,d=c-a,f=e-b;return P&&Math.abs(d)>P&&(c=d>0?a+P:a-P),Q&&Math.abs(f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)0?b+S/U:b-S/U),R/T&&Math.abs(d)0?a+R/T:a-R/T),0>a&&(c-=a,a-=a),0>b&&(e-=b,b-=b),0>c&&(a-=c,c-=c),0>e&&(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 f,g,a=0,b=0,c=0,e=0;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("").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.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("").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("").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("").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,e=l(a,c++).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("").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("api"===b)return a(this).data("Jcrop");a(this).data("Jcrop").setOptions(b)}else"IMG"==this.tagName?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(){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:null,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,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);var __bind=function(fn,me){return function(){return fn.apply(me,arguments)}},__slice=[].slice;!function($){var MrUploader;return MrUploader=function(){function MrUploader(el,options){this.hideFullscreen=__bind(this.hideFullscreen,this),this.setAspectRatio=__bind(this.setAspectRatio,this),this.setLandscapeAspectRatio=__bind(this.setLandscapeAspectRatio,this),this.setPortraitAspectRatio=__bind(this.setPortraitAspectRatio,this),this.setSquareAspectRatio=__bind(this.setSquareAspectRatio,this),this.show=__bind(this.show,this),this.showFullscreen=__bind(this.showFullscreen,this),this.onCloseClick=__bind(this.onCloseClick,this),this.getStagedFileMeta=__bind(this.getStagedFileMeta,this),this.changePreview=__bind(this.changePreview,this),this.getPreviewHeight=__bind(this.getPreviewHeight,this),this.getPreviewWidth=__bind(this.getPreviewWidth,this),this.onReaderLoad=__bind(this.onReaderLoad,this),this.onUploaderFileChanged=__bind(this.onUploaderFileChanged,this),this.onUploadClick=__bind(this.onUploadClick,this),this.onCancelClick=__bind(this.onCancelClick,this),this.resetCroppingArea=__bind(this.resetCroppingArea,this),this.setStaged=__bind(this.setStaged,this),this.onCroppingSelected=__bind(this.onCroppingSelected,this),this.showPhotoActionElements=__bind(this.showPhotoActionElements,this),this.hidePhotoActionElements=__bind(this.hidePhotoActionElements,this),this.getCroppingAreaContent=__bind(this.getCroppingAreaContent,this),this.getRatioOptions=__bind(this.getRatioOptions,this),this.getHeaderContent=__bind(this.getHeaderContent,this),this.onElementClick=__bind(this.onElementClick,this),this.on=__bind(this.on,this),this.$el=$(el),this.$options=$.extend(!0,{},this.defaults,options),this.photoActionsElements=[],this.addContent(),this.$options.onClick===!0&&this.$el.click(this.onElementClick),this.setStaged(null),this.uploads=[]}return MrUploader.prototype.defaults={multiple:!0,cropping:!0,onClick:!0,uploadUrl:"/upload.php",aspectRatio:"landscape",crop:{boxWidth:800,aspectRatio:1.5,keySupport:!1,allowSelect:!1,minSize:[300,200],setSelect:[0,0,600,400]}},MrUploader.prototype.on=function(event,callback){return $(this).on(event,callback)},MrUploader.prototype.onElementClick=function(e){return e.preventDefault(),this.showFullscreen()},MrUploader.prototype.getHeaderContent=function(){var close,header,ratioOptions,title;return header=$(""),close=$(''),close.click(this.onCloseClick),title=$("").text("Choose & Crop"),ratioOptions=this.getRatioOptions(),this.photoActionsElements.push(ratioOptions),header.append(close,title,ratioOptions),header},MrUploader.prototype.getRatioOptions=function(){var landscape,landscapeLabel,portrait,portraitLabel,square,squareLabel;return squareLabel=$(' '),this.squareInput=$(' '),this.squareInput.click(function(_this){return function(){return _this.setSquareAspectRatio()}}(this)),"square"===this.$options.aspectRatio&&this.squareInput.attr("checked",!0),square=$("").append(squareLabel,this.squareInput),portraitLabel=$(' '),this.portraitInput=$(' '),"portrait"===this.$options.aspectRatio&&this.portraitInput.attr("checked",!0),this.portraitInput.click(function(_this){return function(){return _this.setPortraitAspectRatio()}}(this)),portrait=$("").append(portraitLabel,this.portraitInput),landscapeLabel=$(' '),this.landscapeInput=$(' '),"landscape"===this.$options.aspectRatio&&this.landscapeInput.attr("checked",!0),this.landscapeInput.click(function(_this){return function(){return _this.setLandscapeAspectRatio()}}(this)),landscape=$("").append(landscapeLabel,this.landscapeInput),$('').append(square).append(portrait).append(landscape)},MrUploader.prototype.getCroppingAreaContent=function(){var cancel,crop,upload;return crop=$(""),this.$input=$(''),this.$input.change(this.onUploaderFileChanged),crop.append(this.$input),this.$photos=$('
'),crop.append(this.$photos),upload=$(''),upload.click(this.onUploadClick),cancel=$(''),cancel.click(this.onCancelClick),this.photoActionsElements.push(upload,cancel),crop.append(upload),crop.append(cancel),crop},MrUploader.prototype.addContent=function(){return this.$container=$("").hide().addClass("mr-uploader-fullscreen-mode").css("text-align","center"),this.$container.append(this.getHeaderContent()),this.$croppingArea=this.getCroppingAreaContent(),this.$container.append(this.$croppingArea),this.$container.append("
"),this.$previews=$(""),this.$container.append(this.$previews),this.hidePhotoActionElements(),$("body").append(this.$container)},MrUploader.prototype.hidePhotoActionElements=function(){var element,_i,_len,_ref,_results;for(_ref=this.photoActionsElements,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)element=_ref[_i],_results.push(element.hide());return _results},MrUploader.prototype.showPhotoActionElements=function(){var element,_i,_len,_ref,_results;for(_ref=this.photoActionsElements,_results=[],_i=0,_len=_ref.length;_len>_i;_i++)element=_ref[_i],_results.push(element.show());return _results},MrUploader.prototype.onCroppingSelected=function(crop,image,meta){return crop={x:Math.round(crop.x),y:Math.round(crop.y),x2:Math.round(crop.x2),y2:Math.round(crop.y2),width:Math.round(crop.w),height:Math.round(crop.h)},meta.width=image.width(),meta.height=image.height(),this.setStaged({$image:image,meta:meta,crop:crop})},MrUploader.prototype.setStaged=function(staged){this.staged=staged},MrUploader.prototype.resetCroppingArea=function(){return this.$croppingArea.html(this.getCroppingAreaContent()),this.hidePhotoActionElements()},MrUploader.prototype.onCancelClick=function(){return this.resetCroppingArea(),this.setStaged(null),this.$preview.remove()},MrUploader.prototype.onUploadClick=function(e){var $overlay,crop,meta,photo,request,url;return e.preventDefault(),null==this.staged?alert("Please choose a photo to upload"):(url=this.$options.uploadUrl,photo=this.staged.$image.attr("src"),meta=this.staged.meta,crop=this.staged.crop,$overlay=this.getPreviewOverlay(),request=$.ajax({type:"POST",url:url,cache:!1,dataType:"json",data:{photo:photo,meta:meta,crop:crop},beforeSend:function(_this){return function(){return _this.$preview.find(".mr-uploader-preview-overlay").each(function(){return this.remove()}),_this.$preview.prepend($overlay),_this.Jcrop.disable()}}(this)}),request.done(function(_this){return function(response){return _this.staged.response=response,_this.uploads.push(_this.staged),_this.resetCroppingArea(),$overlay.html("✓"),$(_this).trigger("upload",_this.staged),_this.setStaged(null)}}(this)),request.fail(function(){return function(){return $overlay.addClass("error").html("× Upload failed, please retry")}}(this)))},MrUploader.prototype.getPreviewOverlay=function(){return $('').append('')},MrUploader.prototype.onUploaderFileChanged=function(){var file,input,reader,_i,_len,_ref;if(input=this.$input[0],null!=input.files&&input.files.length>0){for(reader=new FileReader,reader.onload=this.onReaderLoad,_ref=input.files,_i=0,_len=_ref.length;_len>_i;_i++)file=_ref[_i],reader.readAsDataURL(file);return this.$input.hide(),this.showPhotoActionElements()}},MrUploader.prototype.onReaderLoad=function(e){var crop,img,meta,previewImage,self;return img=$('
'),crop=this.$options.crop,meta=this.getStagedFileMeta(),this.$preview=$(''),previewImage=$("
").attr("src",e.target.result),this.$preview.html(previewImage),this.$previews.prepend(this.$preview),crop.onSelect=function(_this){return function(crop){return _this.onCroppingSelected(crop,img,meta)}}(this),crop.onChange=function(_this){return function(crop){return _this.changePreview(crop,previewImage)}}(this),this.$photos.html(img),self=this,img.Jcrop(crop,function(){return self.Jcrop=this})},MrUploader.prototype.getPreviewWidth=function(){switch(this.$options.aspectRatio){case"square":case"portrait":return 200;case"landscape":return 300}},MrUploader.prototype.getPreviewHeight=function(){switch(this.$options.aspectRatio){case"square":case"landscape":return 200;case"portrait":return 300}},MrUploader.prototype.changePreview=function(crop,$thumbnail){var height,rx,ry,width;return null!=this.staged?(width=this.getPreviewWidth(),height=this.getPreviewHeight(),rx=width/crop.w,ry=height/crop.h,$thumbnail.css({marginTop:"-"+Math.round(ry*crop.y)+"px",marginLeft:"-"+Math.round(rx*crop.x)+"px",width:Math.round(rx*this.staged.meta.width)+"px",height:Math.round(ry*this.staged.meta.height)+"px"})):void 0},MrUploader.prototype.getStagedFileMeta=function(){var file,input;return input=this.$input[0],file=input.files[0],{name:file.name,size:file.size,type:file.type}},MrUploader.prototype.onCloseClick=function(){return this.hideFullscreen()},MrUploader.prototype.showFullscreen=function(){return this.$container.fadeIn()},MrUploader.prototype.show=function(){return this.showFullscreen()},MrUploader.prototype.setSquareAspectRatio=function(){var _ref,_ref1,_ref2,_ref3;return"square"!==this.$options.aspectRatio?(null!=(_ref=this.$preview)&&_ref.removeClass("mr-uploader-ar-"+this.$options.aspectRatio),this.$options.aspectRatio="square",this.$options.crop.aspectRatio=1,this.$options.crop.minSize=[200,200],null!=(_ref1=this.Jcrop)&&_ref1.setOptions(this.$options.crop),null!=(_ref2=this.$preview)&&_ref2.addClass("mr-uploader-ar-"+this.$options.aspectRatio),null!=(_ref3=this.squareInput)?_ref3.attr("checked",!0):void 0):void 0},MrUploader.prototype.setPortraitAspectRatio=function(){var _ref,_ref1,_ref2,_ref3;return"portrait"!==this.$options.aspectRatio?(null!=(_ref=this.$preview)&&_ref.removeClass("mr-uploader-ar-"+this.$options.aspectRatio),this.$options.aspectRatio="portrait",this.$options.crop.aspectRatio=2/3,this.$options.crop.minSize=[200,300],null!=(_ref1=this.Jcrop)&&_ref1.setOptions(this.$options.crop),null!=(_ref2=this.$preview)&&_ref2.addClass("mr-uploader-ar-"+this.$options.aspectRatio),null!=(_ref3=this.portraitInput)?_ref3.attr("checked",!0):void 0):void 0},MrUploader.prototype.setLandscapeAspectRatio=function(){var _ref,_ref1,_ref2,_ref3;return"landscape"!==this.$options.aspectRatio?(null!=(_ref=this.$preview)&&_ref.removeClass("mr-uploader-ar-"+this.$options.aspectRatio),this.$options.aspectRatio="landscape",this.$options.crop.aspectRatio=1.5,this.$options.crop.minSize=[300,200],null!=(_ref1=this.Jcrop)&&_ref1.setOptions(this.$options.crop),null!=(_ref2=this.$preview)&&_ref2.addClass("mr-uploader-ar-"+this.$options.aspectRatio),null!=(_ref3=this.landscapeInput)?_ref3.attr("checked",!0):void 0):void 0},MrUploader.prototype.setAspectRatio=function(aspectRatio){switch(aspectRatio){case"square":return this.setSquareAspectRatio();case"portrait":return this.setPortraitAspectRatio();case"landscape":return this.setLandscapeAspectRatio()}},MrUploader.prototype.hideFullscreen=function(){return this.$container.fadeOut()},MrUploader}(),$.fn.extend({mrUploader:function(){var $this,args,data,option,upload;return option=arguments[0],args=2<=arguments.length?__slice.call(arguments,1):[],$this=this.first(),data=$this.data("mrUploader"),data?"string"==typeof option?data[optiokn].apply(data,args):void 0:(upload=new MrUploader(this,option),$this.data("mrUploader",data=upload),upload)}})}(window.jQuery,window);
--------------------------------------------------------------------------------
/dist/js/mr-uploader.js:
--------------------------------------------------------------------------------
1 | var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
2 | __slice = [].slice;
3 |
4 | (function($, window) {
5 | var MrUploader;
6 | MrUploader = (function() {
7 | MrUploader.prototype.defaults = {
8 | multiple: true,
9 | cropping: true,
10 | onClick: true,
11 | uploadUrl: '/upload.php',
12 | aspectRatio: 'landscape',
13 | crop: {
14 | boxWidth: 800,
15 | aspectRatio: 3 / 2,
16 | keySupport: false,
17 | allowSelect: false,
18 | minSize: [300, 200],
19 | setSelect: [0, 0, 600, 400]
20 | }
21 | };
22 |
23 | function MrUploader(el, options) {
24 | this.hideFullscreen = __bind(this.hideFullscreen, this);
25 | this.setAspectRatio = __bind(this.setAspectRatio, this);
26 | this.setLandscapeAspectRatio = __bind(this.setLandscapeAspectRatio, this);
27 | this.setPortraitAspectRatio = __bind(this.setPortraitAspectRatio, this);
28 | this.setSquareAspectRatio = __bind(this.setSquareAspectRatio, this);
29 | this.show = __bind(this.show, this);
30 | this.showFullscreen = __bind(this.showFullscreen, this);
31 | this.onCloseClick = __bind(this.onCloseClick, this);
32 | this.getStagedFileMeta = __bind(this.getStagedFileMeta, this);
33 | this.changePreview = __bind(this.changePreview, this);
34 | this.getPreviewHeight = __bind(this.getPreviewHeight, this);
35 | this.getPreviewWidth = __bind(this.getPreviewWidth, this);
36 | this.onReaderLoad = __bind(this.onReaderLoad, this);
37 | this.onUploaderFileChanged = __bind(this.onUploaderFileChanged, this);
38 | this.onUploadClick = __bind(this.onUploadClick, this);
39 | this.onCancelClick = __bind(this.onCancelClick, this);
40 | this.resetCroppingArea = __bind(this.resetCroppingArea, this);
41 | this.setStaged = __bind(this.setStaged, this);
42 | this.onCroppingSelected = __bind(this.onCroppingSelected, this);
43 | this.showPhotoActionElements = __bind(this.showPhotoActionElements, this);
44 | this.hidePhotoActionElements = __bind(this.hidePhotoActionElements, this);
45 | this.getCroppingAreaContent = __bind(this.getCroppingAreaContent, this);
46 | this.getRatioOptions = __bind(this.getRatioOptions, this);
47 | this.getHeaderContent = __bind(this.getHeaderContent, this);
48 | this.onElementClick = __bind(this.onElementClick, this);
49 | this.on = __bind(this.on, this);
50 | this.$el = $(el);
51 | this.$options = $.extend(true, {}, this.defaults, options);
52 | this.photoActionsElements = [];
53 | this.addContent();
54 | if (this.$options.onClick === true) {
55 | this.$el.click(this.onElementClick);
56 | }
57 | this.setStaged(null);
58 | this.uploads = [];
59 | }
60 |
61 | MrUploader.prototype.on = function(event, callback) {
62 | return $(this).on(event, callback);
63 | };
64 |
65 | MrUploader.prototype.onElementClick = function(e) {
66 | e.preventDefault();
67 | return this.showFullscreen();
68 | };
69 |
70 | MrUploader.prototype.getHeaderContent = function() {
71 | var close, header, ratioOptions, title;
72 | header = $('');
73 | close = $('');
74 | close.click(this.onCloseClick);
75 | title = $('').text('Choose & Crop');
76 | ratioOptions = this.getRatioOptions();
77 | this.photoActionsElements.push(ratioOptions);
78 | header.append(close, title, ratioOptions);
79 | return header;
80 | };
81 |
82 | MrUploader.prototype.getRatioOptions = function() {
83 | var landscape, landscapeLabel, portrait, portraitLabel, square, squareLabel;
84 | squareLabel = $(' ');
85 | this.squareInput = $(' ');
86 | this.squareInput.click((function(_this) {
87 | return function() {
88 | return _this.setSquareAspectRatio();
89 | };
90 | })(this));
91 | if (this.$options.aspectRatio === 'square') {
92 | this.squareInput.attr('checked', true);
93 | }
94 | square = $('').append(squareLabel, this.squareInput);
95 | portraitLabel = $(' ');
96 | this.portraitInput = $(' ');
97 | if (this.$options.aspectRatio === 'portrait') {
98 | this.portraitInput.attr('checked', true);
99 | }
100 | this.portraitInput.click((function(_this) {
101 | return function() {
102 | return _this.setPortraitAspectRatio();
103 | };
104 | })(this));
105 | portrait = $('').append(portraitLabel, this.portraitInput);
106 | landscapeLabel = $(' ');
107 | this.landscapeInput = $(' ');
108 | if (this.$options.aspectRatio === 'landscape') {
109 | this.landscapeInput.attr('checked', true);
110 | }
111 | this.landscapeInput.click((function(_this) {
112 | return function() {
113 | return _this.setLandscapeAspectRatio();
114 | };
115 | })(this));
116 | landscape = $('').append(landscapeLabel, this.landscapeInput);
117 | return $('').append(square).append(portrait).append(landscape);
118 | };
119 |
120 | MrUploader.prototype.getCroppingAreaContent = function() {
121 | var cancel, crop, upload;
122 | crop = $('');
123 | this.$input = $('');
124 | this.$input.change(this.onUploaderFileChanged);
125 | crop.append(this.$input);
126 | this.$photos = $('
');
127 | crop.append(this.$photos);
128 | upload = $('');
129 | upload.click(this.onUploadClick);
130 | cancel = $('');
131 | cancel.click(this.onCancelClick);
132 | this.photoActionsElements.push(upload, cancel);
133 | crop.append(upload);
134 | crop.append(cancel);
135 | return crop;
136 | };
137 |
138 | MrUploader.prototype.addContent = function() {
139 | this.$container = $('').hide().addClass('mr-uploader-fullscreen-mode').css('text-align', 'center');
140 | this.$container.append(this.getHeaderContent());
141 | this.$croppingArea = this.getCroppingAreaContent();
142 | this.$container.append(this.$croppingArea);
143 | this.$container.append('
');
144 | this.$previews = $('');
145 | this.$container.append(this.$previews);
146 | this.hidePhotoActionElements();
147 | return $('body').append(this.$container);
148 | };
149 |
150 | MrUploader.prototype.hidePhotoActionElements = function() {
151 | var element, _i, _len, _ref, _results;
152 | _ref = this.photoActionsElements;
153 | _results = [];
154 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
155 | element = _ref[_i];
156 | _results.push(element.hide());
157 | }
158 | return _results;
159 | };
160 |
161 | MrUploader.prototype.showPhotoActionElements = function() {
162 | var element, _i, _len, _ref, _results;
163 | _ref = this.photoActionsElements;
164 | _results = [];
165 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
166 | element = _ref[_i];
167 | _results.push(element.show());
168 | }
169 | return _results;
170 | };
171 |
172 | MrUploader.prototype.onCroppingSelected = function(crop, image, meta) {
173 | crop = {
174 | x: Math.round(crop.x),
175 | y: Math.round(crop.y),
176 | x2: Math.round(crop.x2),
177 | y2: Math.round(crop.y2),
178 | width: Math.round(crop.w),
179 | height: Math.round(crop.h)
180 | };
181 | meta.width = image.width();
182 | meta.height = image.height();
183 | return this.setStaged({
184 | $image: image,
185 | meta: meta,
186 | crop: crop
187 | });
188 | };
189 |
190 | MrUploader.prototype.setStaged = function(staged) {
191 | this.staged = staged;
192 | };
193 |
194 | MrUploader.prototype.resetCroppingArea = function() {
195 | this.$croppingArea.html(this.getCroppingAreaContent());
196 | return this.hidePhotoActionElements();
197 | };
198 |
199 | MrUploader.prototype.onCancelClick = function(e) {
200 | this.resetCroppingArea();
201 | this.setStaged(null);
202 | return this.$preview.remove();
203 | };
204 |
205 | MrUploader.prototype.onUploadClick = function(e) {
206 | var $overlay, crop, meta, photo, request, url;
207 | e.preventDefault();
208 | if (this.staged == null) {
209 | return alert('Please choose a photo to upload');
210 | }
211 | url = this.$options.uploadUrl;
212 | photo = this.staged.$image.attr('src');
213 | meta = this.staged.meta;
214 | crop = this.staged.crop;
215 | $overlay = this.getPreviewOverlay();
216 | request = $.ajax({
217 | type: 'POST',
218 | url: url,
219 | cache: false,
220 | dataType: 'json',
221 | data: {
222 | photo: photo,
223 | meta: meta,
224 | crop: crop
225 | },
226 | beforeSend: (function(_this) {
227 | return function(xhr, settings) {
228 | _this.$preview.find('.mr-uploader-preview-overlay').each(function() {
229 | return this.remove();
230 | });
231 | _this.$preview.prepend($overlay);
232 | return _this.Jcrop.disable();
233 | };
234 | })(this)
235 | });
236 | request.done((function(_this) {
237 | return function(response, status, xhr) {
238 | _this.staged.response = response;
239 | _this.uploads.push(_this.staged);
240 | _this.resetCroppingArea();
241 | $overlay.html('✓');
242 | $(_this).trigger('upload', _this.staged);
243 | return _this.setStaged(null);
244 | };
245 | })(this));
246 | return request.fail((function(_this) {
247 | return function(xhr, status, error) {
248 | return $overlay.addClass('error').html('× Upload failed, please retry');
249 | };
250 | })(this));
251 | };
252 |
253 | MrUploader.prototype.getPreviewOverlay = function() {
254 | return $('').append('');
255 | };
256 |
257 | MrUploader.prototype.onUploaderFileChanged = function(e) {
258 | var file, input, reader, _i, _len, _ref;
259 | input = this.$input[0];
260 | if ((input.files != null) && input.files.length > 0) {
261 | reader = new FileReader();
262 | reader.onload = this.onReaderLoad;
263 | _ref = input.files;
264 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
265 | file = _ref[_i];
266 | reader.readAsDataURL(file);
267 | }
268 | this.$input.hide();
269 | return this.showPhotoActionElements();
270 | }
271 | };
272 |
273 | MrUploader.prototype.onReaderLoad = function(e) {
274 | var crop, img, meta, previewImage, self;
275 | img = $('
');
276 | crop = this.$options.crop;
277 | meta = this.getStagedFileMeta();
278 | this.$preview = $('');
279 | previewImage = $('
').attr('src', e.target.result);
280 | this.$preview.html(previewImage);
281 | this.$previews.prepend(this.$preview);
282 | crop.onSelect = (function(_this) {
283 | return function(crop) {
284 | return _this.onCroppingSelected(crop, img, meta);
285 | };
286 | })(this);
287 | crop.onChange = (function(_this) {
288 | return function(crop) {
289 | return _this.changePreview(crop, previewImage);
290 | };
291 | })(this);
292 | this.$photos.html(img);
293 | self = this;
294 | return img.Jcrop(crop, function() {
295 | return self.Jcrop = this;
296 | });
297 | };
298 |
299 | MrUploader.prototype.getPreviewWidth = function() {
300 | switch (this.$options.aspectRatio) {
301 | case 'square':
302 | case 'portrait':
303 | return 200;
304 | case 'landscape':
305 | return 300;
306 | }
307 | };
308 |
309 | MrUploader.prototype.getPreviewHeight = function() {
310 | switch (this.$options.aspectRatio) {
311 | case 'square':
312 | case 'landscape':
313 | return 200;
314 | case 'portrait':
315 | return 300;
316 | }
317 | };
318 |
319 | MrUploader.prototype.changePreview = function(crop, $thumbnail) {
320 | var height, rx, ry, width;
321 | if (this.staged != null) {
322 | width = this.getPreviewWidth();
323 | height = this.getPreviewHeight();
324 | rx = width / crop.w;
325 | ry = height / crop.h;
326 | return $thumbnail.css({
327 | marginTop: '-' + Math.round(ry * crop.y) + 'px',
328 | marginLeft: '-' + Math.round(rx * crop.x) + 'px',
329 | width: Math.round(rx * this.staged.meta.width) + 'px',
330 | height: Math.round(ry * this.staged.meta.height) + 'px'
331 | });
332 | }
333 | };
334 |
335 | MrUploader.prototype.getStagedFileMeta = function() {
336 | var file, input;
337 | input = this.$input[0];
338 | file = input.files[0];
339 | return {
340 | name: file.name,
341 | size: file.size,
342 | type: file.type
343 | };
344 | };
345 |
346 | MrUploader.prototype.onCloseClick = function() {
347 | return this.hideFullscreen();
348 | };
349 |
350 | MrUploader.prototype.showFullscreen = function() {
351 | return this.$container.fadeIn();
352 | };
353 |
354 | MrUploader.prototype.show = function() {
355 | return this.showFullscreen();
356 | };
357 |
358 | MrUploader.prototype.setSquareAspectRatio = function() {
359 | var _ref, _ref1, _ref2, _ref3;
360 | if (this.$options.aspectRatio !== 'square') {
361 | if ((_ref = this.$preview) != null) {
362 | _ref.removeClass('mr-uploader-ar-' + this.$options.aspectRatio);
363 | }
364 | this.$options.aspectRatio = 'square';
365 | this.$options.crop.aspectRatio = 2 / 2;
366 | this.$options.crop.minSize = [200, 200];
367 | if ((_ref1 = this.Jcrop) != null) {
368 | _ref1.setOptions(this.$options.crop);
369 | }
370 | if ((_ref2 = this.$preview) != null) {
371 | _ref2.addClass('mr-uploader-ar-' + this.$options.aspectRatio);
372 | }
373 | return (_ref3 = this.squareInput) != null ? _ref3.attr('checked', true) : void 0;
374 | }
375 | };
376 |
377 | MrUploader.prototype.setPortraitAspectRatio = function() {
378 | var _ref, _ref1, _ref2, _ref3;
379 | if (this.$options.aspectRatio !== 'portrait') {
380 | if ((_ref = this.$preview) != null) {
381 | _ref.removeClass('mr-uploader-ar-' + this.$options.aspectRatio);
382 | }
383 | this.$options.aspectRatio = 'portrait';
384 | this.$options.crop.aspectRatio = 2 / 3;
385 | this.$options.crop.minSize = [200, 300];
386 | if ((_ref1 = this.Jcrop) != null) {
387 | _ref1.setOptions(this.$options.crop);
388 | }
389 | if ((_ref2 = this.$preview) != null) {
390 | _ref2.addClass('mr-uploader-ar-' + this.$options.aspectRatio);
391 | }
392 | return (_ref3 = this.portraitInput) != null ? _ref3.attr('checked', true) : void 0;
393 | }
394 | };
395 |
396 | MrUploader.prototype.setLandscapeAspectRatio = function() {
397 | var _ref, _ref1, _ref2, _ref3;
398 | if (this.$options.aspectRatio !== 'landscape') {
399 | if ((_ref = this.$preview) != null) {
400 | _ref.removeClass('mr-uploader-ar-' + this.$options.aspectRatio);
401 | }
402 | this.$options.aspectRatio = 'landscape';
403 | this.$options.crop.aspectRatio = 3 / 2;
404 | this.$options.crop.minSize = [300, 200];
405 | if ((_ref1 = this.Jcrop) != null) {
406 | _ref1.setOptions(this.$options.crop);
407 | }
408 | if ((_ref2 = this.$preview) != null) {
409 | _ref2.addClass('mr-uploader-ar-' + this.$options.aspectRatio);
410 | }
411 | return (_ref3 = this.landscapeInput) != null ? _ref3.attr('checked', true) : void 0;
412 | }
413 | };
414 |
415 | MrUploader.prototype.setAspectRatio = function(aspectRatio) {
416 | switch (aspectRatio) {
417 | case 'square':
418 | return this.setSquareAspectRatio();
419 | case 'portrait':
420 | return this.setPortraitAspectRatio();
421 | case 'landscape':
422 | return this.setLandscapeAspectRatio();
423 | }
424 | };
425 |
426 | MrUploader.prototype.hideFullscreen = function() {
427 | return this.$container.fadeOut();
428 | };
429 |
430 | return MrUploader;
431 |
432 | })();
433 | return $.fn.extend({
434 | mrUploader: function() {
435 | var $this, args, data, option, upload;
436 | option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
437 | $this = this.first();
438 | data = $this.data('mrUploader');
439 | if (!data) {
440 | upload = new MrUploader(this, option);
441 | $this.data('mrUploader', (data = upload));
442 | return upload;
443 | }
444 | if (typeof option === 'string') {
445 | return data[optiokn].apply(data, args);
446 | }
447 | }
448 | });
449 | })(window.jQuery, window);
450 |
--------------------------------------------------------------------------------
/examples/aspect-ratio/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mr. Uploader
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
35 |
36 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/examples/simple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mr. Uploader
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
16 |
17 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/upload.php:
--------------------------------------------------------------------------------
1 | $file, 'url' => "http://$_SERVER[HTTP_HOST]/$file"]);
20 |
21 | return true;
22 | }
23 |
24 | http_response_code(400);
25 | echo 'FAILED to upload';
26 |
27 | return false;
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mr-uploader",
3 | "version": "1.0.0",
4 | "description": "Photo cropping and upload made easy",
5 | "main": "Gruntfile.js",
6 | "dependencies": {
7 | "grunt": "^0.4.5"
8 | },
9 | "devDependencies": {
10 | "grunt-contrib-clean": "^0.6.0",
11 | "grunt-contrib-coffee": "^0.12.0",
12 | "grunt-contrib-concat": "^0.5.0",
13 | "grunt-contrib-cssmin": "^0.11.0",
14 | "grunt-contrib-uglify": "^0.7.0",
15 | "grunt-contrib-watch": "^0.6.1"
16 | },
17 | "scripts": {
18 | "test": "test"
19 | },
20 | "author": "Abed Halawi ",
21 | "license": "MIT"
22 | }
23 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | .mr-uploader-fullscreen-mode {
2 | top: 0;
3 | left: 0;
4 | width: 100%;
5 | height: 100%;
6 | z-index: 99999;
7 | position: fixed;
8 | overflow: scroll;
9 | font-family: Arial;
10 | border: 0!important;
11 | padding: 15px 30px 15px;
12 | color: #272727;
13 | background: #FAFAFB!important;
14 | }
15 |
16 | .mr-uploader-fullscreen-close {
17 | float:left;
18 | font-size: 28px;
19 | cursor: pointer;
20 | font-color: #ededed;
21 | text-decoration: none;
22 | }
23 |
24 | #mr-uploader-file-input {
25 | margin: 0 auto;
26 | padding-bottom: 10px;
27 | }
28 |
29 | #mr-uploader-images {
30 | min-height: 200px;
31 | }
32 |
33 | #mr-uploader-images .jcrop-holder {
34 | text-align: : center;
35 | margin: 0 auto;
36 | }
37 |
38 | .mr-uploader-preview {
39 | position: relative;
40 | float: left;
41 | font-size: 30px;
42 | margin-left: 10px;
43 | overflow: hidden;
44 | background-color: transparent;
45 | box-shadow: 0px 0px 5px 1px #888;
46 | -moz-box-shadow: inset 0px 0px 5px 1px #888;
47 | -webkit-box-shadow: inset 0px 0px 5px 1px #888;
48 | }
49 |
50 | .mr-uploader-ar-landscape {
51 | width: 300px;
52 | height: 200px;
53 | }
54 |
55 | .mr-uploader-ar-portrait {
56 | width: 200px;
57 | height: 300px;
58 | }
59 |
60 | .mr-uploader-ar-square {
61 | width: 200px;
62 | height: 200px;
63 | }
64 |
65 | .mr-uploader-preview-overlay {
66 | position: absolute;
67 | width: 100%;
68 | height: 100%;
69 | opacity: 0.8;
70 | text-align: center;
71 | text-decoration: bold;
72 | color: green;
73 | vertical-align: middle;
74 | line-height: 200px;
75 | text-decoration: bold;
76 | background-color: #ededed;
77 | }
78 |
79 | .mr-uploader-preview .error {
80 | color: red;
81 | font-size: 22px;
82 | }
83 |
84 | .mr-uploader-spinner {
85 | margin: 0 auto;
86 | width: 70px;
87 | text-align: center;
88 | }
89 |
90 | .mr-uploader-spinner > div {
91 | width: 18px;
92 | height: 18px;
93 | background-color: #333;
94 |
95 | border-radius: 100%;
96 | display: inline-block;
97 | -webkit-animation: bouncedelay 0.8s infinite ease-in-out;
98 | animation: bouncedelay 0.8s infinite ease-in-out;
99 | /* Prevent first frame from flickering when animation starts */
100 | -webkit-animation-fill-mode: both;
101 | animation-fill-mode: both;
102 | }
103 |
104 | .mr-uploader-spinner-bounce1 {
105 | -webkit-animation-delay: -0.32s;
106 | animation-delay: -0.32s;
107 | }
108 |
109 | .mr-uploader-spinner-bounce2 {
110 | -webkit-animation-delay: -0.16s;
111 | animation-delay: -0.16s;
112 | }
113 |
114 | @-webkit-keyframes bouncedelay {
115 | 0%, 80%, 100% { -webkit-transform: scale(0.0) }
116 | 40% { -webkit-transform: scale(1.0) }
117 | }
118 |
119 | @keyframes bouncedelay {
120 | 0%, 80%, 100% {
121 | transform: scale(0.0);
122 | -webkit-transform: scale(0.0);
123 | } 40% {
124 | transform: scale(1.0);
125 | -webkit-transform: scale(1.0);
126 | }
127 | }
128 |
129 | .mr-uploader-ratio-options {
130 | margin: 30px 0px 30px 0px;
131 | }
132 |
--------------------------------------------------------------------------------
/src/uploader.coffee:
--------------------------------------------------------------------------------
1 | (($, window) ->
2 |
3 | class MrUploader
4 |
5 | defaults:
6 | multiple: true
7 | cropping: true
8 | onClick: true
9 | uploadUrl: '/upload.php'
10 | aspectRatio: 'landscape'
11 | crop:
12 | boxWidth: 800
13 | aspectRatio: 3/2
14 | keySupport: false
15 | allowSelect: false
16 | minSize: [300, 200]
17 | setSelect: [0, 0, 600, 400]
18 |
19 | constructor: (el, options)->
20 | @$el = $(el)
21 | @$options = $.extend(true, {}, @defaults, options)
22 | # The elements that we need to keep hold of, so that we show/hide them based on whether there's
23 | # a photo staged (chosen for upload) or not, respectively.
24 | @photoActionsElements = []
25 | # add the content to the container
26 | @addContent()
27 |
28 | @$el.click(@onElementClick) if @$options.onClick is true
29 | @setStaged(null)
30 | # All the uploaded stuff will live here
31 | @uploads = []
32 |
33 | on: (event, callback)=> $(@).on(event, callback)
34 |
35 | onElementClick: (e)=>
36 | e.preventDefault()
37 | @showFullscreen()
38 |
39 | getHeaderContent: =>
40 | header = $('')
41 |
42 | close = $('')
43 | close.click(@onCloseClick)
44 |
45 | title = $('').text('Choose & Crop')
46 |
47 | ratioOptions = @getRatioOptions()
48 |
49 | @photoActionsElements.push(ratioOptions)
50 |
51 | header.append(close, title, ratioOptions)
52 |
53 | return header
54 |
55 | getRatioOptions: =>
56 | squareLabel = $(' ')
57 | @squareInput = $(' ')
58 | @squareInput.click => @setSquareAspectRatio()
59 | @squareInput.attr('checked', true) if @$options.aspectRatio is 'square'
60 | square = $('').append(squareLabel, @squareInput)
61 |
62 | portraitLabel = $(' ')
63 | @portraitInput = $(' ')
64 | @portraitInput.attr('checked', true) if @$options.aspectRatio is 'portrait'
65 | @portraitInput.click => @setPortraitAspectRatio()
66 | portrait = $('').append(portraitLabel, @portraitInput)
67 |
68 | landscapeLabel = $(' ')
69 | @landscapeInput = $(' ')
70 | @landscapeInput.attr('checked', true) if @$options.aspectRatio is 'landscape'
71 | @landscapeInput.click => @setLandscapeAspectRatio()
72 | landscape = $('').append(landscapeLabel, @landscapeInput)
73 |
74 | return $('')
75 | .append(square)
76 | .append(portrait)
77 | .append(landscape)
78 |
79 | getCroppingAreaContent: =>
80 | crop = $('')
81 |
82 | # Add input field
83 | @$input = $('')
84 | @$input.change @onUploaderFileChanged
85 | crop.append(@$input)
86 |
87 | # Add photos container
88 | @$photos = $('
')
89 | crop.append(@$photos)
90 |
91 | # Add upload button
92 | upload = $('')
93 | upload.click(@onUploadClick)
94 |
95 | cancel = $('')
96 | cancel.click(@onCancelClick)
97 |
98 | @photoActionsElements.push(upload, cancel)
99 |
100 | crop.append(upload)
101 | crop.append(cancel)
102 |
103 | return crop
104 |
105 | addContent: ->
106 | @$container = $('')
107 | .hide()
108 | .addClass('mr-uploader-fullscreen-mode')
109 | .css('text-align', 'center')
110 |
111 | # Add header
112 | @$container.append(@getHeaderContent())
113 | # draw the cropping area
114 | @$croppingArea = @getCroppingAreaContent()
115 | # Add the cropping area
116 | @$container.append(@$croppingArea)
117 | # separator
118 | @$container.append('
')
119 |
120 | @$previews = $('')
121 | # previews will be added dynamically when
122 | # the image has finished reading (onReaderLoad)
123 | @$container.append(@$previews)
124 |
125 | @hidePhotoActionElements()
126 |
127 | # Append content to the DOM
128 | $('body').append(@$container)
129 |
130 | hidePhotoActionElements: => element.hide() for element in @photoActionsElements
131 | showPhotoActionElements: => element.show() for element in @photoActionsElements
132 |
133 | onCroppingSelected: (crop, image, meta)=>
134 | crop = {
135 | x: Math.round(crop.x)
136 | y: Math.round(crop.y)
137 | x2: Math.round(crop.x2)
138 | y2: Math.round(crop.y2)
139 | width: Math.round(crop.w)
140 | height: Math.round(crop.h)
141 | }
142 |
143 | meta.width = image.width()
144 | meta.height = image.height()
145 |
146 | @setStaged({$image: image, meta: meta, crop: crop})
147 |
148 | setStaged: (@staged)=>
149 |
150 | resetCroppingArea: =>
151 | # reset the cropping area
152 | @$croppingArea.html(@getCroppingAreaContent())
153 | @hidePhotoActionElements()
154 |
155 | onCancelClick: (e)=>
156 | @resetCroppingArea()
157 | @setStaged(null)
158 | @$preview.remove()
159 |
160 | onUploadClick: (e)=>
161 | e.preventDefault()
162 | return alert('Please choose a photo to upload') if not @staged?
163 |
164 | url = @$options.uploadUrl
165 | photo = @staged.$image.attr('src')
166 | meta = @staged.meta
167 | crop = @staged.crop
168 |
169 | $overlay = @getPreviewOverlay()
170 |
171 | request = $.ajax({
172 | type: 'POST',
173 | url: url,
174 | cache: false
175 | dataType: 'json'
176 | data: {photo: photo, meta: meta, crop: crop}
177 | beforeSend: (xhr, settings)=>
178 | # remove any previous overlays (if any)
179 | @$preview.find('.mr-uploader-preview-overlay').each -> this.remove()
180 | # add the overlay to the preview
181 | @$preview.prepend($overlay)
182 | # disable cropping
183 | @Jcrop.disable()
184 | })
185 |
186 | request.done (response, status, xhr)=>
187 | @staged.response = response
188 | # remove staged photo
189 | @uploads.push(@staged)
190 | # reset the cropping area, preparing for another one
191 | @resetCroppingArea()
192 | # display success on uploaded image's overlay
193 | $overlay.html('✓')
194 | # tell listeners about the upload
195 | $(@).trigger('upload', @staged);
196 | # clear the stage
197 | @setStaged(null)
198 | request.fail (xhr, status, error)=>
199 | $overlay.addClass('error').html('× Upload failed, please retry')
200 |
201 | getPreviewOverlay: ->
202 | $('')
203 | .append('')
204 |
205 | onUploaderFileChanged: (e)=>
206 | input = @$input[0]
207 | if input.files? and input.files.length > 0
208 | reader = new FileReader()
209 | reader.onload = @onReaderLoad
210 | reader.readAsDataURL(file) for file in input.files
211 | @$input.hide()
212 | @showPhotoActionElements()
213 |
214 | onReaderLoad: (e)=>
215 | img = $('
')
216 | crop = @$options.crop
217 | meta = @getStagedFileMeta()
218 |
219 | @$preview = $('')
220 |
221 | previewImage = $('
').attr('src', e.target.result)
222 | @$preview.html(previewImage)
223 |
224 | @$previews.prepend(@$preview)
225 |
226 | crop.onSelect = (crop)=> @onCroppingSelected(crop, img, meta)
227 | crop.onChange = (crop)=> @changePreview(crop, previewImage)
228 |
229 | @$photos.html(img)
230 |
231 | self = @
232 | img.Jcrop crop, -> self.Jcrop = this
233 |
234 | getPreviewWidth: =>
235 | switch @$options.aspectRatio
236 | when 'square', 'portrait' then 200
237 | when 'landscape' then 300
238 |
239 | getPreviewHeight: =>
240 | switch @$options.aspectRatio
241 | when 'square', 'landscape' then 200
242 | when 'portrait' then 300
243 |
244 | changePreview: (crop, $thumbnail)=>
245 | if @staged?
246 | width = @getPreviewWidth()
247 | height = @getPreviewHeight()
248 | rx = width / crop.w
249 | ry = height / crop.h
250 |
251 | $thumbnail.css({
252 | marginTop: '-' + Math.round(ry * crop.y) + 'px',
253 | marginLeft: '-' + Math.round(rx * crop.x) + 'px',
254 | width: Math.round(rx * @staged.meta.width) + 'px',
255 | height: Math.round(ry * @staged.meta.height) + 'px'
256 | })
257 |
258 | getStagedFileMeta: =>
259 | input = @$input[0]
260 | file = input.files[0]
261 | return {
262 | name: file.name
263 | size: file.size
264 | type: file.type
265 | }
266 |
267 | onCloseClick: => @hideFullscreen()
268 |
269 | showFullscreen: => @$container.fadeIn()
270 |
271 | show: => @showFullscreen()
272 |
273 | setSquareAspectRatio: =>
274 | if @$options.aspectRatio isnt 'square'
275 | @$preview?.removeClass('mr-uploader-ar-'+@$options.aspectRatio)
276 | @$options.aspectRatio = 'square'
277 | @$options.crop.aspectRatio = 2/2
278 | @$options.crop.minSize = [200, 200]
279 | @Jcrop?.setOptions(@$options.crop)
280 | @$preview?.addClass('mr-uploader-ar-'+@$options.aspectRatio)
281 | @squareInput?.attr('checked', true)
282 |
283 | setPortraitAspectRatio: =>
284 | if @$options.aspectRatio isnt 'portrait'
285 | @$preview?.removeClass('mr-uploader-ar-'+@$options.aspectRatio)
286 | @$options.aspectRatio = 'portrait'
287 | @$options.crop.aspectRatio = 2/3
288 | @$options.crop.minSize = [200, 300]
289 | @Jcrop?.setOptions(@$options.crop)
290 | @$preview?.addClass('mr-uploader-ar-'+@$options.aspectRatio)
291 | @portraitInput?.attr('checked', true)
292 |
293 | setLandscapeAspectRatio: =>
294 | if @$options.aspectRatio isnt 'landscape'
295 | @$preview?.removeClass('mr-uploader-ar-'+@$options.aspectRatio)
296 | @$options.aspectRatio = 'landscape'
297 | @$options.crop.aspectRatio = 3/2
298 | @$options.crop.minSize = [300, 200]
299 | @Jcrop?.setOptions(@$options.crop)
300 | @$preview?.addClass('mr-uploader-ar-'+@$options.aspectRatio)
301 | @landscapeInput?.attr('checked', true)
302 |
303 | setAspectRatio: (aspectRatio)=>
304 | switch aspectRatio
305 | when 'square' then @setSquareAspectRatio()
306 | when 'portrait' then @setPortraitAspectRatio()
307 | when 'landscape' then @setLandscapeAspectRatio()
308 |
309 | hideFullscreen: => @$container.fadeOut()
310 |
311 | # Define the plugin
312 | $.fn.extend mrUploader: (option, args...) ->
313 | $this = @first()
314 | data = $this.data('mrUploader')
315 |
316 | if !data
317 | upload = new MrUploader(this, option)
318 | $this.data 'mrUploader', (data = upload)
319 | return upload
320 | if typeof option == 'string'
321 | data[optiokn].apply(data, args)
322 |
323 | )(window.jQuery, window)
324 |
--------------------------------------------------------------------------------
/vendors/jquery.Jcrop.min.css:
--------------------------------------------------------------------------------
1 | /* jquery.Jcrop.min.css v0.9.12 (build:20130126) */
2 | .jcrop-holder{direction:ltr;text-align:left;}
3 | .jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif);font-size:0;position:absolute;}
4 | .jcrop-vline{height:100%;width:1px!important;}
5 | .jcrop-vline.right{right:0;}
6 | .jcrop-hline{height:1px!important;width:100%;}
7 | .jcrop-hline.bottom{bottom:0;}
8 | .jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
9 | .jcrop-handle{background-color:#333;border:1px #EEE solid;font-size:1px;height:7px;width:7px;}
10 | .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
11 | .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
12 | .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
13 | .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
14 | .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
15 | .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
16 | .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
17 | .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
18 | .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
19 | .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
20 | .jcrop-dragbar.ord-n{margin-top:-4px;}
21 | .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
22 | .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
23 | .jcrop-dragbar.ord-w{margin-left:-4px;}
24 | .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.70!important;}
25 | .jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
26 | .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important;}
27 | .jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
28 | .solid-line .jcrop-vline,.solid-line .jcrop-hline{background:#FFF;}
29 | .jcrop-holder img,img.jcrop-preview{max-width:none;}
30 |
--------------------------------------------------------------------------------
/vendors/jquery.Jcrop.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jquery.Jcrop.min.js v0.9.12 (build:20130202)
3 | * jQuery Image Cropping Plugin - released under MIT License
4 | * Copyright (c) 2008-2013 Tapmodo Interactive LLC
5 | * https://github.com/tapmodo/Jcrop
6 | */
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("").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("").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(""),I=a("").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("").width("100%").height("100%").css("zIndex",320),K=a("").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("
").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;da+f&&(f-=f+a),0>b+g&&(g-=g+b),FE&&(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-ah&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):rh&&(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 cP&&(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)0?b+S/U:b-S/U),R/T&&Math.abs(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("").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("").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("").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("").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,e=l(a,c++
17 | ).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("").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:null,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
22 | :!0,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);
23 |
--------------------------------------------------------------------------------