uploader.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. (function( factory ) {
  2. if ( !window.jQuery ) {
  3. alert('jQuery is required.')
  4. }
  5. jQuery(function() {
  6. factory.call( null, jQuery );
  7. });
  8. })(function( $ ) {
  9. // -----------------------------------------------------
  10. // ------------ START ----------------------------------
  11. // -----------------------------------------------------
  12. // ---------------------------------
  13. // --------- Uploader -------------
  14. // ---------------------------------
  15. var Uploader = (function() {
  16. // -------setting-------
  17. // 如果使用原始大小,超大的图片可能会出现 Croper UI 卡顿,所以这里建议先缩小后再crop.
  18. var FRAME_WIDTH = 1600;
  19. var _ = WebUploader;
  20. var Uploader = _.Uploader;
  21. var uploaderContainer = $('.uploader-container');
  22. var uploader, file;
  23. if ( !Uploader.support() ) {
  24. alert( 'Web Uploader 不支持您的浏览器!');
  25. throw new Error( 'WebUploader does not support the browser you are using.' );
  26. }
  27. // hook,
  28. // 在文件开始上传前进行裁剪。
  29. Uploader.register({
  30. 'before-send-file': 'cropImage'
  31. }, {
  32. cropImage: function( file ) {
  33. var data = file._cropData,
  34. image, deferred;
  35. file = this.request( 'get-file', file );
  36. deferred = _.Deferred();
  37. image = new _.Lib.Image();
  38. deferred.always(function() {
  39. image.destroy();
  40. image = null;
  41. });
  42. image.once( 'error', deferred.reject );
  43. image.once( 'load', function() {
  44. image.crop( data.x, data.y, data.width, data.height, data.scale );
  45. });
  46. image.once( 'complete', function() {
  47. var blob, size;
  48. // 移动端 UC / qq 浏览器的无图模式下
  49. // ctx.getImageData 处理大图的时候会报 Exception
  50. // INDEX_SIZE_ERR: DOM Exception 1
  51. try {
  52. blob = image.getAsBlob();
  53. size = file.size;
  54. file.source = blob;
  55. file.size = blob.size;
  56. file.trigger( 'resize', blob.size, size );
  57. deferred.resolve();
  58. } catch ( e ) {
  59. console.log( e );
  60. // 出错了直接继续,让其上传原始图片
  61. deferred.resolve();
  62. }
  63. });
  64. file._info && image.info( file._info );
  65. file._meta && image.meta( file._meta );
  66. image.loadFromBlob( file.source );
  67. return deferred.promise();
  68. }
  69. });
  70. return {
  71. init: function( selectCb ) {
  72. uploader = new Uploader({
  73. pick: {
  74. id: '#filePicker',
  75. multiple: false
  76. },
  77. // 设置用什么方式去生成缩略图。
  78. thumb: {
  79. quality: 70,
  80. // 不允许放大
  81. allowMagnify: false,
  82. // 是否采用裁剪模式。如果采用这样可以避免空白内容。
  83. crop: false
  84. },
  85. // 禁掉分块传输,默认是开起的。
  86. chunked: false,
  87. // 禁掉上传前压缩功能,因为会手动裁剪。
  88. compress: false,
  89. // fileSingleSizeLimit: 2 * 1024 * 1024,
  90. server: '../../server/fileupload.php',
  91. swf: '../../dist/Uploader.swf',
  92. fileNumLimit: 1,
  93. onError: function() {
  94. var args = [].slice.call(arguments, 0);
  95. alert(args.join('\n'));
  96. }
  97. });
  98. uploader.on('fileQueued', function( _file ) {
  99. file = _file;
  100. uploader.makeThumb( file, function( error, src ) {
  101. if ( error ) {
  102. alert('不能预览');
  103. return;
  104. }
  105. selectCb( src );
  106. }, FRAME_WIDTH, 1 ); // 注意这里的 height 值是 1,被当成了 100% 使用。
  107. });
  108. },
  109. crop: function( data ) {
  110. var scale = Croper.getImageSize().width / file._info.width;
  111. data.scale = scale;
  112. file._cropData = {
  113. x: data.x1,
  114. y: data.y1,
  115. width: data.width,
  116. height: data.height,
  117. scale: data.scale
  118. };
  119. },
  120. upload: function() {
  121. uploader.upload();
  122. }
  123. }
  124. })();
  125. // ---------------------------------
  126. // --------- Crpper ---------------
  127. // ---------------------------------
  128. var Croper = (function() {
  129. var container = $('.cropper-wraper');
  130. var $image = container.find('.img-container img');
  131. var btn = $('.upload-btn');
  132. var isBase64Supported, callback;
  133. $image.cropper({
  134. aspectRatio: 16 / 9,
  135. preview: ".img-preview",
  136. done: function(data) {
  137. // console.log(data);
  138. }
  139. });
  140. function srcWrap( src, cb ) {
  141. // we need to check this at the first time.
  142. if (typeof isBase64Supported === 'undefined') {
  143. (function() {
  144. var data = new Image();
  145. var support = true;
  146. data.onload = data.onerror = function() {
  147. if( this.width != 1 || this.height != 1 ) {
  148. support = false;
  149. }
  150. }
  151. data.src = src;
  152. isBase64Supported = support;
  153. })();
  154. }
  155. if ( isBase64Supported ) {
  156. cb( src );
  157. } else {
  158. // otherwise we need server support.
  159. // convert base64 to a file.
  160. $.ajax('../../server/preview.php', {
  161. method: 'POST',
  162. data: src,
  163. dataType:'json'
  164. }).done(function( response ) {
  165. if (response.result) {
  166. cb( response.result );
  167. } else {
  168. alert("预览出错");
  169. }
  170. });
  171. }
  172. }
  173. btn.on('click', function() {
  174. callback && callback($image.cropper("getData"));
  175. return false;
  176. });
  177. return {
  178. setSource: function( src ) {
  179. // 处理 base64 不支持的情况。
  180. // 一般出现在 ie6-ie8
  181. srcWrap( src, function( src ) {
  182. $image.cropper("setImgSrc", src);
  183. });
  184. container.removeClass('webuploader-element-invisible');
  185. return this;
  186. },
  187. getImageSize: function() {
  188. var img = $image.get(0);
  189. return {
  190. width: img.naturalWidth,
  191. height: img.naturalHeight
  192. }
  193. },
  194. setCallback: function( cb ) {
  195. callback = cb;
  196. return this;
  197. },
  198. disable: function() {
  199. $image.cropper("disable");
  200. return this;
  201. },
  202. enable: function() {
  203. $image.cropper("enable");
  204. return this;
  205. }
  206. }
  207. })();
  208. // ------------------------------
  209. // -----------logic--------------
  210. // ------------------------------
  211. var container = $('.uploader-container');
  212. Uploader.init(function( src ) {
  213. Croper.setSource( src );
  214. // 隐藏选择按钮。
  215. container.addClass('webuploader-element-invisible');
  216. // 当用户选择上传的时候,开始上传。
  217. Croper.setCallback(function( data ) {
  218. Uploader.crop(data);
  219. Uploader.upload();
  220. });
  221. });
  222. // -----------------------------------------------------
  223. // ------------ END ------------------------------------
  224. // -----------------------------------------------------
  225. });