croppic.js 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611
  1. /*
  2. * CROPPIC
  3. * dependancy: jQuery
  4. * author: Ognjen "Zmaj Džedaj" Božičković and Mat Steinlin
  5. */
  6. (function (window, document) {
  7. Croppic = function (id, options) {
  8. var that = this;
  9. that.id = id;
  10. that.obj = $('#' + id);
  11. that.outputDiv = that.obj;
  12. that.imgUrl = "";
  13. that.saveImgUrl = "";
  14. that.imgBackground = "";
  15. // DEFAULT OPTIONS
  16. that.options = {
  17. uploadUrl: '',
  18. uploadData: {},
  19. cropUrl: '',
  20. cropData: {},
  21. outputUrlId: '',
  22. absorptionUrl: '',
  23. //styles
  24. imgEyecandy: true,
  25. imgEyecandyOpacity: 0.2,
  26. initialZoom: 40,
  27. zoomFactor: 10,
  28. rotateFactor: 5,
  29. doubleZoomControls: true,
  30. rotateControls: true,
  31. modal: false,
  32. customUploadButtonId: '',
  33. customSaveButtonId: '',
  34. loaderHtml: '',
  35. scaleToFill: true,
  36. processInline: false,
  37. loadPicture: '',
  38. onReset: null,
  39. enableMousescroll: false,
  40. colorAbsorption: false,
  41. //callbacks
  42. onBeforeImgUpload: null,
  43. onAfterImgUpload: null,
  44. onImgDrag: null,
  45. onImgZoom: null,
  46. onImgRotate: null,
  47. onBeforeImgCrop: null,
  48. onAfterImgCrop: null,
  49. onBeforeRemoveCroppedImg: null,
  50. onAfterRemoveCroppedImg: null,
  51. onError: null,
  52. };
  53. // OVERWRITE DEFAULT OPTIONS
  54. for (i in options) that.options[i] = options[i];
  55. // INIT THE WHOLE DAMN THING!!!
  56. that.init();
  57. };
  58. Croppic.prototype = {
  59. id: '',
  60. imgInitW: 0,
  61. imgInitH: 0,
  62. imgW: 0,
  63. imgH: 0,
  64. actualRotationImgW: 0,
  65. actualRotationImgH: 0,
  66. objW: 0,
  67. objH: 0,
  68. actualRotation: 0,
  69. windowW: 0,
  70. windowH: $(window).height(),
  71. obj: {},
  72. outputDiv: {},
  73. outputUrlObj: {},
  74. img: {},
  75. defaultImg: {},
  76. croppedImg: {},
  77. imgEyecandy: {},
  78. form: {},
  79. iframeform: {},
  80. iframeobj: {},
  81. cropControlsUpload: {},
  82. cropControlsCrop: {},
  83. cropControlZoomMuchIn: {},
  84. cropControlZoomMuchOut: {},
  85. cropControlZoomIn: {},
  86. cropControlZoomOut: {},
  87. cropControlCrop: {},
  88. cropControlReset: {},
  89. cropControlRemoveCroppedImage: {},
  90. cropControlOriginal: {},
  91. modal: {},
  92. loader: {},
  93. cropSaveControl: {},
  94. ctx: {},
  95. imgName: '',
  96. init: function () {
  97. var that = this;
  98. that.objW = that.obj.width();
  99. that.objH = that.obj.height();
  100. // reset rotation
  101. that.actualRotation = 0;
  102. that.actualRotationImgH = 0;
  103. that.actualRotationImgW = 0;
  104. that.colorAbsorption = false;
  105. that.imgBackground = "";
  106. that.ctx = {};
  107. that.imgName = '';
  108. if ($.isEmptyObject(that.defaultImg)) {
  109. that.defaultImg = that.obj.find('img');
  110. }
  111. that.createImgUploadControls();
  112. if ($.isEmptyObject(that.options.loadPicture)) {
  113. that.bindImgUploadControl();
  114. } else {
  115. that.loadExistingImage();
  116. }
  117. },
  118. createImgUploadControls: function () {
  119. var that = this;
  120. var cropControlUpload = '';
  121. if (that.options.customUploadButtonId === '') {
  122. cropControlUpload = '<i class="cropControlUpload"></i>';
  123. }
  124. var cropControlRemoveCroppedImage = '<i class="cropControlRemoveCroppedImage"></i>';
  125. var cropControlOriginal = '<i class="cropControlOriginal"></i>';
  126. if ($.isEmptyObject(that.croppedImg)) {
  127. cropControlRemoveCroppedImage = '';
  128. cropControlOriginal = '';
  129. }
  130. if (!$.isEmptyObject(that.options.loadPicture)) {
  131. cropControlUpload = '';
  132. }
  133. var html = '<div class="cropControls cropControlsUpload"> ' + cropControlUpload + cropControlOriginal + cropControlRemoveCroppedImage + ' </div>';
  134. that.outputDiv.append(html);
  135. that.cropControlsUpload = that.outputDiv.find('.cropControlsUpload');
  136. if (that.options.customUploadButtonId === '') {
  137. that.imgUploadControl = that.outputDiv.find('.cropControlUpload');
  138. }
  139. else {
  140. that.imgUploadControl = $('#' + that.options.customUploadButtonId);
  141. that.imgUploadControl.show();
  142. }
  143. if (that.options.customSaveButtonId !== '') {
  144. that.cropSaveControl = $('#' + that.options.customSaveButtonId);
  145. that.cropSaveControl.hide();
  146. }
  147. if (!$.isEmptyObject(that.croppedImg)) {
  148. that.cropControlRemoveCroppedImage = that.outputDiv.find('.cropControlRemoveCroppedImage');
  149. that.cropControlOriginal = that.outputDiv.find('.cropControlOriginal');
  150. }
  151. },
  152. bindImgUploadControl: function () {
  153. var that = this;
  154. // CREATE UPLOAD IMG FORM
  155. var formHtml = '<form class="' + that.id + '_imgUploadForm" style="visibility: hidden;"> <input type="file" name="img" id="' + that.id + '_imgUploadField"> </form>';
  156. that.outputDiv.append(formHtml);
  157. that.form = that.outputDiv.find('.' + that.id + '_imgUploadForm');
  158. // CREATE FALLBACK IE9 IFRAME
  159. var fileUploadId = that.CreateFallbackIframe();
  160. that.imgUploadControl.off('click');
  161. that.imgUploadControl.on('click', function () {
  162. if (fileUploadId === "") {
  163. that.form.find('input[type="file"]').trigger('click');
  164. } else {
  165. //Trigger iframe file input click, otherwise access restriction error
  166. that.iframeform.find('input[type="file"]').trigger('click');
  167. }
  168. });
  169. that.cropSaveControl.off('click');
  170. that.cropSaveControl.on('click', function () {
  171. that.destroy();
  172. window.location.href = "https://wwww.croppic.com?" + that.saveImgUrl;
  173. });
  174. if (!$.isEmptyObject(that.croppedImg)) {
  175. that.cropControlRemoveCroppedImage.on('click', function () {
  176. if (typeof (that.options.onBeforeRemoveCroppedImg) === typeof(Function)) {
  177. that.options.onBeforeRemoveCroppedImg.call(that);
  178. }
  179. var res = confirm('您是要使用当前图片还是重新选择图片?\n\r' +
  180. '[确认] 使用当前图片\n\r' +
  181. '[取消] 重新选择图片');
  182. var width = that.imgInitW;
  183. var height = that.imgInitH;
  184. that.croppedImg.remove();
  185. that.croppedImg = {};
  186. $(this).hide();
  187. that.cropSaveControl.hide();
  188. that.cropControlOriginal.hide();
  189. if (typeof (that.options.onAfterRemoveCroppedImg) === typeof(Function)) {
  190. that.options.onAfterRemoveCroppedImg.call(that);
  191. }
  192. if (!$.isEmptyObject(that.defaultImg)) {
  193. that.obj.append(that.defaultImg);
  194. }
  195. if (that.options.outputUrlId !== '') {
  196. $('#' + that.options.outputUrlId).val('');
  197. }
  198. that.imgUploadControl.show();
  199. if (res) {
  200. that.showLoader();
  201. that.imgUploadControl.hide();
  202. if (!$.isEmptyObject(that.croppedImg)) {
  203. that.croppedImg.remove();
  204. }
  205. that.imgInitW = that.imgW = width;
  206. that.imgInitH = that.imgH = height;
  207. that.saveImgUrl = "";
  208. that.obj.append('<img src="' + that.imgUrl + '">');
  209. that.initCropper();
  210. that.hideLoader();
  211. }
  212. });
  213. that.cropControlOriginal.on('click', function () {
  214. if (that.imgUrl == '') {
  215. alert('请选择图片');
  216. return;
  217. }
  218. var res = confirm('您确定要使用原图吗?\n\r' +
  219. '[确认] 使用原图\n\r' +
  220. '[取消] 继续编辑');
  221. if (res) {
  222. // that.destroy();
  223. // window.location.href = "https://wwww.croppic.com?" + that.imgUrl;
  224. that.controlOriginal();
  225. }
  226. });
  227. }
  228. that.form.find('input[type="file"]').change(function () {
  229. if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that);
  230. that.showLoader();
  231. that.imgUploadControl.hide();
  232. if (that.options.processInline) {
  233. // Checking Browser Support for FileReader API
  234. if (typeof FileReader == "undefined") {
  235. if (that.options.onError) that.options.onError.call(that, "processInline is not supported by your Browser");
  236. that.reset();
  237. } else {
  238. var file = that.form.find('input[type="file"]')[0].files[0];
  239. var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
  240. if (!rFilter.test(file.type)) {
  241. alert("请选择jpeg、png格式的图片");
  242. that.imgUploadControl.show();
  243. that.hideLoader();
  244. return;
  245. }
  246. if (!$.isEmptyObject(that.croppedImg)) {
  247. that.destroy();
  248. }
  249. var Orientation = null;
  250. //获取照片方向角属性,用户旋转控制
  251. EXIF.getData(file, function () {
  252. EXIF.getAllTags(this);
  253. Orientation = EXIF.getTag(this, 'Orientation');
  254. // $('#exif').html(EXIF.pretty(this));
  255. // $('#exif').html(Orientation);
  256. });
  257. var reader = new FileReader();
  258. reader.onload = function (e) {
  259. if (Orientation != null && Orientation != "" && Orientation != 1
  260. && (Orientation == 8 || Orientation == 6 || Orientation == 3)) {
  261. that.takingCorrectJs2(e.target.result,Orientation);
  262. reader.clear();
  263. reader.destroy();
  264. return;
  265. }
  266. var image = new Image();
  267. image.src = e.target.result;
  268. image.onload = function () {
  269. that.imgInitW = that.imgW = image.width;
  270. that.imgInitH = that.imgH = image.height;
  271. that.imgUrl = image.src;
  272. if (that.options.modal) {
  273. that.createModal();
  274. }
  275. if (!$.isEmptyObject(that.croppedImg)) {
  276. that.croppedImg.remove();
  277. }
  278. that.saveImgUrl = "";
  279. that.obj.append('<img src="' + image.src + '">');
  280. that.initCropper();
  281. that.hideLoader();
  282. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  283. }
  284. };
  285. reader.readAsDataURL(file);
  286. }
  287. } else {
  288. try {
  289. // other modern browsers
  290. formData = new FormData(that.form[0]);
  291. } catch (e) {
  292. // IE10 MUST have all form items appended as individual form key / value pairs
  293. formData = new FormData();
  294. formData.append('img', that.form.find("input[type=file]")[0].files[0]);
  295. }
  296. for (var key in that.options.uploadData) {
  297. if (that.options.uploadData.hasOwnProperty(key)) {
  298. formData.append(key, that.options.uploadData[key]);
  299. }
  300. }
  301. $.ajax({
  302. url: that.options.uploadUrl,
  303. data: formData,
  304. context: document.body,
  305. cache: false,
  306. contentType: false,
  307. processData: false,
  308. type: 'POST'
  309. }).always(function (data) {
  310. that.afterUpload(data);
  311. });
  312. }
  313. });
  314. },
  315. takingCorrectJs: function (file) {
  316. var that = this;
  317. lrz(file, {quality: 1}).then(function (rst) {
  318. // console.log(rst.base64); //图片格式为base64;
  319. var image = new Image();
  320. image.src = rst.base64;
  321. image.onload = function () {
  322. that.imgInitW = that.imgW = image.width;
  323. that.imgInitH = that.imgH = image.height;
  324. that.imgUrl = image.src;
  325. if (that.options.modal) {
  326. that.createModal();
  327. }
  328. if (!$.isEmptyObject(that.croppedImg)) {
  329. that.croppedImg.remove();
  330. }
  331. that.saveImgUrl = "";
  332. that.obj.append('<img src="' + image.src + '">');
  333. that.initCropper();
  334. that.hideLoader();
  335. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  336. }
  337. }).catch(function (err) {
  338. alert("打开图片失败");
  339. // 处理失败会执行
  340. }).always(function () {
  341. // 不管是成功失败,都会执行
  342. });
  343. },
  344. // 此方法是旋转图片;
  345. takingCorrectJs2: function (img, dir) {
  346. var that = this;
  347. var image = new Image();
  348. image.onload = function () {
  349. var degree = 0, drawWidth, drawHeight, width, height;
  350. drawWidth = this.naturalWidth;
  351. drawHeight = this.naturalHeight;
  352. //以下改变一下图片大小
  353. // var maxSide = Math.max(drawWidth, drawHeight);
  354. // if (maxSide > 3072) {
  355. // var minSide = Math.min(drawWidth, drawHeight);
  356. // minSide = minSide / maxSide * 3072;
  357. // maxSide = 3072;
  358. // if (drawWidth > drawHeight) {
  359. // drawWidth = maxSide;
  360. // drawHeight = minSide;
  361. // } else {
  362. // drawWidth = minSide;
  363. // drawHeight = maxSide;
  364. // }
  365. // }
  366. var canvas = document.createElement('canvas');
  367. canvas.width = width = drawWidth;
  368. canvas.height = height = drawHeight;
  369. var context = canvas.getContext('2d');
  370. //判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
  371. switch (dir) {
  372. //iphone横屏拍摄,此时home键在左侧
  373. case 3:
  374. degree = 180;
  375. drawWidth = -width;
  376. drawHeight = -height;
  377. break;
  378. //iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)
  379. case 6:
  380. canvas.width = height;
  381. canvas.height = width;
  382. degree = 90;
  383. drawWidth = width;
  384. drawHeight = -height;
  385. break;
  386. //iphone竖屏拍摄,此时home键在上方
  387. case 8:
  388. canvas.width = height;
  389. canvas.height = width;
  390. degree = 270;
  391. drawWidth = -width;
  392. drawHeight = height;
  393. break;
  394. }
  395. //使用canvas旋转校正
  396. context.rotate(degree * Math.PI / 180);
  397. context.drawImage(this, 0, 0, drawWidth, drawHeight);
  398. // 判断图片 类型 (可增加判断的类型 此处只判断了 jpeg 和png)
  399. var imgtype = img.includes('image/png') ? "image/png" : "image/jpeg";
  400. //返回校正图片
  401. var imageNext = new Image();
  402. imageNext.onload = function () {
  403. that.imgInitW = that.imgW = imageNext.width;
  404. that.imgInitH = that.imgH = imageNext.height;
  405. that.imgUrl = imageNext.src;
  406. if (that.options.modal) {
  407. that.createModal();
  408. }
  409. if (!$.isEmptyObject(that.croppedImg)) {
  410. that.croppedImg.remove();
  411. }
  412. that.saveImgUrl = "";
  413. that.obj.append('<img src="' + imageNext.src + '">');
  414. that.initCropper();
  415. that.hideLoader();
  416. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  417. }
  418. imageNext.src = canvas.toDataURL(imgtype, 1);
  419. }
  420. image.src = img;
  421. },
  422. controlOriginal: function () {
  423. var that = this;
  424. that.showLoader();
  425. that.cropControlsCrop.hide();
  426. var formData = new FormData();
  427. formData.append("uploadOriginal","1");
  428. if (that.imgName != undefined&&that.imgName!=null&&that.imgName.length>0)
  429. {
  430. formData.append("imgName", that.imgName);
  431. }else {
  432. formData.append("imgUrl", that.convertBase64UrlToBlob(that.imgUrl));
  433. }
  434. $.ajax({
  435. url: that.options.absorptionUrl,
  436. data: formData,
  437. cache: false,
  438. contentType: false,
  439. processData: false,
  440. type: 'POST'
  441. }).always(function (data) {
  442. // if (that.options.onError) that.options.onError.call(that,JSON.stringify(data));
  443. var response;
  444. try {
  445. response = jQuery.parseJSON(data);
  446. }
  447. catch (err) {
  448. response = typeof data == 'object' ? data : jQuery.parseJSON(data);
  449. }
  450. if (response.status == 'success') {
  451. that.imgName = response.imgName;
  452. that.destroy();
  453. // prompt(that.imgUrl);
  454. window.location.href = "https://wwww.croppic.com?" +'product_image_crop_md5,' + that.imgName + ','+ that.imgUrl;
  455. return;
  456. } else if (response.status == 'error') {
  457. if (that.options.onError) that.options.onError.call(that, response.message);
  458. } else {
  459. if (that.options.onError) that.options.onError.call(that, "处理失败");
  460. }
  461. that.cropControlsCrop.show();
  462. that.hideLoader();
  463. });
  464. },
  465. takingCorrect: function (file) {
  466. var time = new Date(); // 程序计时的月从0开始取值后+1
  467. var t = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
  468. var meg = '开始上传:' + t;
  469. var that = this;
  470. var formData = new FormData();
  471. var mime = that.getFileMime(file);
  472. formData.append("imgUrl", that.convertBase64UrlToBlob(file));
  473. var xhr = new XMLHttpRequest();
  474. xhr.open("POST", "taking", true);
  475. xhr.responseType = "blob";
  476. xhr.timeout = 60000 * 5;
  477. xhr.onload = function () {
  478. if (xhr.readyState === 4 && xhr.status === 200) {
  479. var blob = this.response;
  480. var Error = this.getResponseHeader("Content-My-Error");
  481. if (Error != null) {
  482. var ErrorMeg = decodeURIComponent(atob(Error).split('').map(function (c) {
  483. return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  484. }).join(''));
  485. if (that.options.onError) that.options.onError.call(that, ErrorMeg);
  486. that.imgUploadControl.show();
  487. that.hideLoader();
  488. return;
  489. }
  490. var filename = xhr.getResponseHeader("Content-My-filename");
  491. if (filename != null) {
  492. that.imgName = filename;
  493. meg = meg + " \n\r" + '上传完成准备处理:' + xhr.getResponseHeader("Content-My-start");
  494. meg = meg + " \n\r" + '处理完成准备下载:' + xhr.getResponseHeader("Content-My-end");
  495. var time2 = new Date(); // 程序计时的月从0开始取值后+1
  496. var t2 = time2.getHours() + ":" + time2.getMinutes() + ":" + time2.getSeconds();
  497. meg = meg + " \n\r" + '下载完成:' + t2;
  498. }
  499. var reader = new FileReader();
  500. reader.onload = function (e) {
  501. var image = new Image();
  502. image.src = e.target.result;
  503. image.onload = function () {
  504. that.imgInitW = that.imgW = image.width;
  505. that.imgInitH = that.imgH = image.height;
  506. var arr = image.src.split(',');
  507. that.imgUrl = 'data:' + mime + ';base64,' + arr[1];
  508. if (that.options.modal) {
  509. that.createModal();
  510. }
  511. if (!$.isEmptyObject(that.croppedImg)) {
  512. that.croppedImg.remove();
  513. }
  514. that.saveImgUrl = "";
  515. that.obj.append('<img src="' + that.imgUrl + '">');
  516. that.initCropper();
  517. that.hideLoader();
  518. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  519. // alert(meg);
  520. }
  521. }
  522. reader.readAsDataURL(blob);
  523. } else {
  524. if (that.options.onError) that.options.onError.call(that, "处理失败,错误代码["+xhr.readyState+"]");
  525. that.imgUploadControl.show();
  526. that.hideLoader();
  527. }
  528. };
  529. xhr.send(formData);
  530. }
  531. , loadExistingImage: function () {
  532. var that = this;
  533. if ($.isEmptyObject(that.croppedImg)) {
  534. if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that);
  535. that.showLoader();
  536. if (that.options.modal) {
  537. that.createModal();
  538. }
  539. if (!$.isEmptyObject(that.croppedImg)) {
  540. that.croppedImg.remove();
  541. }
  542. that.imgUrl = that.options.loadPicture;
  543. var img = $('<img src="' + that.options.loadPicture + '">');
  544. that.obj.append(img);
  545. img.load(function () {
  546. that.imgInitW = that.imgW = this.width;
  547. that.imgInitH = that.imgH = this.height;
  548. that.initCropper();
  549. that.hideLoader();
  550. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  551. });
  552. } else {
  553. that.cropControlRemoveCroppedImage.on('click', function () {
  554. var res = confirm('您是要使用当前图片还是重新选择图片?\n\r' +
  555. '[确认] 使用当前图片\n\r' +
  556. '[取消] 重新选择图片');
  557. var width = that.imgInitW;
  558. var height = that.imgInitH;
  559. that.croppedImg.remove();
  560. $(this).hide();
  561. that.cropSaveControl.hide();
  562. that.cropControlOriginal.hide();
  563. if (!$.isEmptyObject(that.defaultImg)) {
  564. that.obj.append(that.defaultImg);
  565. }
  566. if (that.options.outputUrlId !== '') {
  567. $('#' + that.options.outputUrlId).val('');
  568. }
  569. that.croppedImg = '';
  570. that.reset();
  571. if (res) {
  572. that.showLoader();
  573. that.imgUploadControl.hide();
  574. if (!$.isEmptyObject(that.croppedImg)) {
  575. that.croppedImg.remove();
  576. }
  577. that.imgInitW = that.imgW = width;
  578. that.imgInitH = that.imgH = height;
  579. that.saveImgUrl = "";
  580. that.obj.append('<img src="' + that.imgUrl + '">');
  581. that.initCropper();
  582. that.hideLoader();
  583. }
  584. });
  585. }
  586. },
  587. afterUpload: function (data) {
  588. var that = this;
  589. response = typeof data == 'object' ? data : jQuery.parseJSON(data);
  590. if (response.status == 'success') {
  591. that.imgInitW = that.imgW = response.width;
  592. that.imgInitH = that.imgH = response.height;
  593. if (that.options.modal) {
  594. that.createModal();
  595. }
  596. if (!$.isEmptyObject(that.croppedImg)) {
  597. that.croppedImg.remove();
  598. }
  599. that.imgUrl = response.url;
  600. var img = $('<img src="' + response.url + '">')
  601. that.obj.append(img);
  602. img.load(function () {
  603. that.initCropper();
  604. that.hideLoader();
  605. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  606. });
  607. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  608. }
  609. if (response.status == 'error') {
  610. alert(response.message);
  611. if (that.options.onError) that.options.onError.call(that, response.message);
  612. that.hideLoader();
  613. // setTimeout( function(){ that.reset(); },2000)
  614. }
  615. },
  616. createModal: function () {
  617. var that = this;
  618. var marginTop = that.windowH / 2 - that.objH / 2;
  619. var modalHTML = '<div id="croppicModal">' + '<div id="croppicModalObj" style="width:' + that.objW + 'px; height:' + that.objH + 'px; margin:0 auto; margin-top:' + marginTop + 'px; position: relative;"> </div>' + '</div>';
  620. $('body').append(modalHTML);
  621. that.modal = $('#croppicModal');
  622. that.obj = $('#croppicModalObj');
  623. },
  624. destroyModal: function () {
  625. var that = this;
  626. that.obj = that.outputDiv;
  627. that.modal.remove();
  628. that.modal = {};
  629. },
  630. initCropper: function () {
  631. var that = this;
  632. /*SET UP SOME VARS*/
  633. that.img = that.obj.find('img');
  634. that.img.wrap('<div class="cropImgWrapper" style="overflow:hidden; z-index:1; position:absolute; width:' + that.objW + 'px; height:' + that.objH + 'px;"></div>');
  635. /*INIT DRAGGING*/
  636. that.createCropControls();
  637. if (that.options.imgEyecandy) {
  638. that.createEyecandy();
  639. }
  640. that.initDrag();
  641. that.initialScaleImg();
  642. },
  643. createEyecandy: function () {
  644. var that = this;
  645. that.imgEyecandy = that.img.clone();
  646. that.imgEyecandy.css({'z-index': '0', 'opacity': that.options.imgEyecandyOpacity}).appendTo(that.obj);
  647. },
  648. destroyEyecandy: function () {
  649. var that = this;
  650. that.imgEyecandy.remove();
  651. },
  652. initialScaleImg: function () {
  653. var that = this;
  654. that.zoom(0);
  655. that.zoom(that.options.initialZoom);
  656. // Adding mousewheel zoom capabilities
  657. if (that.options.enableMousescroll) {
  658. that.img.on('mousewheel', function (event) {
  659. event.preventDefault();
  660. if (that.colorAbsorption) {
  661. return;
  662. }
  663. that.zoom(that.options.zoomFactor * event.deltaY);
  664. });
  665. }
  666. // initial center image
  667. that.img.css({
  668. 'left': -(that.imgW - that.objW) / 2,
  669. 'top': -(that.imgH - that.objH) / 2,
  670. 'position': 'relative'
  671. });
  672. if (that.options.imgEyecandy) {
  673. that.imgEyecandy.css({
  674. 'left': -(that.imgW - that.objW) / 2,
  675. 'top': -(that.imgH - that.objH) / 2,
  676. 'position': 'relative'
  677. });
  678. }
  679. },
  680. createCropControls: function () {
  681. var that = this;
  682. // CREATE CONTROLS
  683. var cropControlZoomMuchIn = '';
  684. var cropControlZoomIn = '<i class="cropControlZoomIn"></i>';
  685. var cropControlZoomOut = '<i class="cropControlZoomOut"></i>';
  686. var cropControlZoomMuchOut = '';
  687. var cropControlRotateLeft = '';
  688. var cropControlRotateRight = '';
  689. var cropControlRotateMuchLeft = '';
  690. var cropControlRotateMuchRight = '';
  691. var cropControlCrop = '<i class="cropControlCrop"></i>';
  692. var cropControlReset = '<i class="cropControlReset"></i>';
  693. var cropControlOriginal = '<i class="cropControlOriginal"></i>';
  694. var cropControlXiColor = '<i class="cropControlXiColor"></i>';
  695. var cropControlXiColor2 = '<i class="cropControlXiColor2"></i>';
  696. var cropControlSetColor = '<i class="cropControlSetColor"></i>';
  697. var html;
  698. if (that.options.doubleZoomControls) {
  699. cropControlZoomMuchIn = '<i class="cropControlZoomMuchIn"></i>';
  700. cropControlZoomMuchOut = '<i class="cropControlZoomMuchOut"></i>';
  701. }
  702. if (that.options.rotateControls) {
  703. cropControlRotateLeft = '<i class="cropControlRotateLeft"></i>';
  704. cropControlRotateRight = '<i class="cropControlRotateRight"></i>';
  705. cropControlRotateMuchLeft = '<i class="cropControlRotateMuchLeft"></i>';
  706. cropControlRotateMuchRight = '<i class="cropControlRotateMuchRight"></i>';
  707. }
  708. html = '<div class="cropControls cropControlsCrop">' + cropControlZoomMuchIn + cropControlZoomIn + cropControlZoomOut + cropControlZoomMuchOut
  709. + cropControlRotateMuchLeft + cropControlRotateLeft + cropControlRotateRight + cropControlRotateMuchRight + cropControlCrop + '</div>';
  710. that.obj.append(html);
  711. html = '<div class="cropControls cropControlsCrop cropControlsUpload">' + cropControlXiColor2 + cropControlXiColor + cropControlSetColor + cropControlOriginal + cropControlReset + '</div>';
  712. that.obj.append(html);
  713. that.cropControlsCrop = that.obj.find('.cropControlsCrop');
  714. // CACHE AND BIND CONTROLS
  715. if (that.options.doubleZoomControls) {
  716. that.cropControlZoomMuchIn = that.cropControlsCrop.find('.cropControlZoomMuchIn');
  717. that.cropControlZoomMuchIn.on('click', function () {
  718. that.zoom(that.options.zoomFactor * 10);
  719. });
  720. that.cropControlZoomMuchOut = that.cropControlsCrop.find('.cropControlZoomMuchOut');
  721. that.cropControlZoomMuchOut.on('click', function () {
  722. that.zoom(-that.options.zoomFactor * 10);
  723. });
  724. }
  725. that.cropControlZoomIn = that.cropControlsCrop.find('.cropControlZoomIn');
  726. that.cropControlZoomIn.on('click', function () {
  727. that.zoom(that.options.zoomFactor);
  728. });
  729. that.cropControlZoomOut = that.cropControlsCrop.find('.cropControlZoomOut');
  730. that.cropControlZoomOut.on('click', function () {
  731. that.zoom(-that.options.zoomFactor);
  732. });
  733. that.cropControlRotateLeft = that.cropControlsCrop.find('.cropControlRotateLeft');
  734. that.cropControlRotateLeft.on('click', function () {
  735. that.rotate(-0.5);
  736. });
  737. that.cropControlRotateMuchLeft = that.cropControlsCrop.find('.cropControlRotateMuchLeft');
  738. that.cropControlRotateMuchLeft.on('click', function () {
  739. that.rotate(-10);
  740. });
  741. that.cropControlRotateRight = that.cropControlsCrop.find('.cropControlRotateRight');
  742. that.cropControlRotateRight.on('click', function () {
  743. that.rotate(0.5);
  744. });
  745. that.cropControlRotateMuchRight = that.cropControlsCrop.find('.cropControlRotateMuchRight');
  746. that.cropControlRotateMuchRight.on('click', function () {
  747. that.rotate(10);
  748. });
  749. that.cropControlCrop = that.cropControlsCrop.find('.cropControlCrop');
  750. that.cropControlCrop.on('click', function () {
  751. that.crop();
  752. });
  753. that.cropControlReset = that.cropControlsCrop.find('.cropControlReset');
  754. that.cropControlReset.on('click', function () {
  755. var res = confirm('您是要使用当前图片还是重新选择图片?\n\r' +
  756. '[确认] 使用当前图片\n\r' +
  757. '[取消] 重新选择图片');
  758. var width = that.imgInitW;
  759. var height = that.imgInitH;
  760. that.reset();
  761. if (res) {
  762. that.showLoader();
  763. that.imgUploadControl.hide();
  764. if (!$.isEmptyObject(that.croppedImg)) {
  765. that.croppedImg.remove();
  766. }
  767. that.imgInitW = that.imgW = width;
  768. that.imgInitH = that.imgH = height;
  769. that.saveImgUrl = "";
  770. that.obj.append('<img src="' + that.imgUrl + '">');
  771. that.initCropper();
  772. that.hideLoader();
  773. }
  774. });
  775. that.cropControlOriginal = that.cropControlsCrop.find('.cropControlOriginal');
  776. that.cropControlOriginal.on('click', function () {
  777. if (that.imgUrl == '') {
  778. alert('请选择图片');
  779. return;
  780. }
  781. var res = confirm('您确定要使用原图吗?\n\r' +
  782. '[确认] 使用原图\n\r' +
  783. '[取消] 继续编辑');
  784. if (res) {
  785. // that.destroy();
  786. // window.location.href = "https://wwww.croppic.com?" + that.imgUrl;
  787. that.controlOriginal();
  788. }
  789. });
  790. that.cropControlXiColor = that.cropControlsCrop.find('.cropControlXiColor');
  791. that.cropControlXiColor.on('click', function () {
  792. that.colorOnClick(false);
  793. });
  794. that.cropControlXiColor2 = that.cropControlsCrop.find('.cropControlXiColor2');
  795. that.cropControlXiColor2.on('click', function () {
  796. that.colorOnClick(false);
  797. });
  798. that.cropControlSetColor = that.cropControlsCrop.find('.cropControlSetColor');
  799. that.cropControlSetColor.on('click', function () {
  800. that.colorOnClick(true);
  801. });
  802. that.colpick = that.cropControlSetColor.colpick({
  803. onSubmit: function (hsb, hex, rgb, el) {
  804. var background = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
  805. that.obj.find('.cropImgWrapper').css('background', background);
  806. $(el).colpickHide();
  807. that.imgBackground = background;
  808. }
  809. });
  810. },
  811. colorOnClick: function (input) {
  812. var that = this;
  813. if (that.colorAbsorption || input) {
  814. that.cropControlsCrop.find('.cropControlXiColor').css("display", "block");
  815. that.cropControlsCrop.find('.cropControlXiColor2').css("display", "none");
  816. that.colorAbsorption = false;
  817. } else {
  818. that.cropControlsCrop.find('.cropControlXiColor').css("display", "none");
  819. that.cropControlsCrop.find('.cropControlXiColor2').css("display", "block");
  820. that.colorAbsorption = true;
  821. }
  822. },
  823. absorption: function (pageX, pageY) {
  824. var that = this;
  825. that.showLoader();
  826. that.cropControlsCrop.hide();
  827. var cropData = {
  828. imgInitW: that.imgInitW,
  829. imgInitH: that.imgInitH,
  830. imgW: that.imgW,
  831. imgH: that.imgH,
  832. imgY1: parseInt(that.img.css('top')),
  833. imgX1: parseInt(that.img.css('left')),
  834. cropH: that.objH,
  835. cropW: that.objW,
  836. rotation: that.actualRotation,
  837. pageX: pageX,
  838. pageY: pageY,
  839. imgBackground: that.imgBackground
  840. };
  841. var formData = new FormData();
  842. for (var key in cropData) {
  843. if (cropData.hasOwnProperty(key)) {
  844. formData.append(key, cropData[key]);
  845. }
  846. }
  847. if (that.imgName == '') {
  848. formData.append("imgUrl", that.convertBase64UrlToBlob(that.imgUrl));
  849. } else {
  850. formData.append("imgName", that.imgName);
  851. }
  852. $.ajax({
  853. url: that.options.absorptionUrl,
  854. data: formData,
  855. cache: false,
  856. contentType: false,
  857. processData: false,
  858. type: 'POST'
  859. }).always(function (data) {
  860. var response;
  861. try {
  862. response = jQuery.parseJSON(data);
  863. }
  864. catch (err) {
  865. response = typeof data == 'object' ? data : jQuery.parseJSON(data);
  866. }
  867. if (response.status == 'success') {
  868. that.imgName = response.imgName;
  869. var rgb = {r: response.r, g: response.g, b: response.b};
  870. var background = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
  871. that.obj.find('.cropImgWrapper').css("background", background);
  872. that.imgBackground = background;
  873. that.cropControlSetColor.colpickSetColor(rgb);
  874. } else if (response.status == 'error') {
  875. if (that.options.onError) that.options.onError.call(that, response.message);
  876. } else {
  877. if (that.options.onError) that.options.onError.call(that, "处理失败");
  878. }
  879. that.cropControlsCrop.show();
  880. that.hideLoader();
  881. });
  882. },
  883. initDrag: function () {
  884. var that = this;
  885. that.img.on("mousedown touchstart", function (e) {
  886. e.preventDefault(); // disable selection
  887. var pageX;
  888. var pageY;
  889. var userAgent = window.navigator.userAgent;
  890. if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i) || userAgent.match(/android/i) || (e.pageY && e.pageX) == undefined) {
  891. pageX = e.originalEvent.touches[0].pageX;
  892. pageY = e.originalEvent.touches[0].pageY;
  893. } else {
  894. pageX = e.pageX;
  895. pageY = e.pageY;
  896. }
  897. var z_idx = that.img.css('z-index'),
  898. drg_h = that.img.outerHeight(),
  899. drg_w = that.img.outerWidth(),
  900. pos_y = that.img.offset().top + drg_h - pageY,
  901. pos_x = that.img.offset().left + drg_w - pageX;
  902. that.z_idx = z_idx;
  903. that.drg_h = drg_h;
  904. that.drg_w = drg_w;
  905. that.pos_y = pos_y;
  906. that.pos_x = pos_x;
  907. if (that.colorAbsorption) {
  908. if (that.actualRotation !== 0) {
  909. that.absorption(pageX - 10, pageY - 50);
  910. return;
  911. }
  912. var ml = that.imgInitW / that.imgW;
  913. var x = pageX - parseInt(that.img.css('left')) - 10;
  914. var y = pageY - parseInt(that.img.css('top')) - 50;
  915. x = parseInt(x * ml);
  916. y = parseInt(y * ml);
  917. if (!(x < 0 || x > that.imgInitW || y < 0 || y > that.imgInitH)) {
  918. var imgData = {};
  919. if ($.isEmptyObject(that.ctx)) {
  920. var canvas = document.createElement("canvas");
  921. if (!canvas.getContext) {
  922. alert("浏览器版本太低无法使用吸色!");
  923. return;
  924. }
  925. that.ctx = canvas.getContext("2d");
  926. var newImg = new Image();
  927. newImg.onload = function () {
  928. canvas.width = that.imgInitW;
  929. canvas.height = that.imgInitH;
  930. that.ctx.drawImage(newImg, 0, 0);
  931. imgData = that.ctx.getImageData(x, y, 1, 1);
  932. var rgb = {r: imgData.data[0], g: imgData.data[1], b: imgData.data[2]};
  933. var background = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
  934. that.obj.find('.cropImgWrapper').css("background", background);
  935. that.imgBackground = background;
  936. that.cropControlSetColor.colpickSetColor(rgb);
  937. }
  938. newImg.src = that.imgUrl;
  939. } else {
  940. imgData = that.ctx.getImageData(x, y, 1, 1);
  941. var rgb = {r: imgData.data[0], g: imgData.data[1], b: imgData.data[2]};
  942. var background = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
  943. that.obj.find('.cropImgWrapper').css("background", background);
  944. that.imgBackground = background;
  945. that.cropControlSetColor.colpickSetColor(rgb);
  946. }
  947. }
  948. return;
  949. }
  950. }).on("mouseup", function () {
  951. that.img.off("mousemove");
  952. }).on("mouseout", function () {
  953. that.img.off("mousemove");
  954. });
  955. that.img.css('z-index', 1000).on("mousemove touchmove", function (e) {
  956. e.preventDefault();
  957. if (that.colorAbsorption) {
  958. return;
  959. }
  960. var z_idx = that.z_idx;
  961. var drg_h = that.drg_h;
  962. var drg_w = that.drg_w;
  963. var pos_y = that.pos_y;
  964. var pos_x = that.pos_x;
  965. var imgTop;
  966. var imgLeft;
  967. var userAgent = window.navigator.userAgent;
  968. if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i) || userAgent.match(/android/i) || (e.pageY && e.pageX) == undefined) {
  969. imgTop = e.originalEvent.touches[0].pageY + pos_y - drg_h;
  970. imgLeft = e.originalEvent.touches[0].pageX + pos_x - drg_w;
  971. } else {
  972. imgTop = e.pageY + pos_y - drg_h;
  973. imgLeft = e.pageX + pos_x - drg_w;
  974. }
  975. that.img.offset({
  976. top: imgTop,
  977. left: imgLeft
  978. }).on("mouseup", function () {
  979. $(this).removeClass('draggable').css('z-index', z_idx);
  980. });
  981. if (that.options.imgEyecandy) {
  982. that.imgEyecandy.offset({top: imgTop, left: imgLeft});
  983. }
  984. var top = that.actualRotationImgH;
  985. var left = that.actualRotationImgW;
  986. if (that.objH < that.imgH + top * 2) {
  987. if (parseInt(that.img.css('top')) > top) {
  988. that.img.css('top', top);
  989. if (that.options.imgEyecandy) {
  990. that.imgEyecandy.css('top', top);
  991. }
  992. }
  993. var maxTop = -(that.imgH - that.objH + top);
  994. if (parseInt(that.img.css('top')) < maxTop) {
  995. that.img.css('top', maxTop);
  996. if (that.options.imgEyecandy) {
  997. that.imgEyecandy.css('top', maxTop);
  998. }
  999. }
  1000. } else {
  1001. if (parseInt(that.img.css('top')) < -top) {
  1002. that.img.css('top', -top);
  1003. if (that.options.imgEyecandy) {
  1004. that.imgEyecandy.css('top', -top);
  1005. }
  1006. }
  1007. var maxTop = that.objH - that.imgH + top;
  1008. if (parseInt(that.img.css('top')) > maxTop) {
  1009. that.img.css('top', maxTop);
  1010. if (that.options.imgEyecandy) {
  1011. that.imgEyecandy.css('top', maxTop);
  1012. }
  1013. }
  1014. }
  1015. if (that.objW < that.imgW + 2 * left) {
  1016. if (parseInt(that.img.css('left')) > left) {
  1017. that.img.css('left', left);
  1018. if (that.options.imgEyecandy) {
  1019. that.imgEyecandy.css('left', left);
  1020. }
  1021. }
  1022. var maxLeft = -(that.imgW - that.objW + left);
  1023. if (parseInt(that.img.css('left')) < maxLeft) {
  1024. that.img.css('left', maxLeft);
  1025. if (that.options.imgEyecandy) {
  1026. that.imgEyecandy.css('left', maxLeft);
  1027. }
  1028. }
  1029. } else {
  1030. if (parseInt(that.img.css('left')) < -left) {
  1031. that.img.css('left', -left);
  1032. if (that.options.imgEyecandy) {
  1033. that.imgEyecandy.css('left', -left);
  1034. }
  1035. }
  1036. var maxLeft = (that.objW - that.imgW + left);
  1037. if (parseInt(that.img.css('left')) > maxLeft) {
  1038. that.img.css('left', maxLeft);
  1039. if (that.options.imgEyecandy) {
  1040. that.imgEyecandy.css('left', maxLeft);
  1041. }
  1042. }
  1043. }
  1044. if (that.options.onImgDrag) that.options.onImgDrag.call(that);
  1045. });
  1046. },
  1047. rotate: function (x) {
  1048. var that = this;
  1049. that.colorOnClick(true);
  1050. that.actualRotation += x;
  1051. that.img.css({
  1052. '-webkit-transform': 'rotate(' + that.actualRotation + 'deg)',
  1053. '-moz-transform': 'rotate(' + that.actualRotation + 'deg)',
  1054. 'transform': 'rotate(' + that.actualRotation + 'deg)',
  1055. });
  1056. if (that.options.imgEyecandy) {
  1057. that.imgEyecandy.css({
  1058. '-webkit-transform': 'rotate(' + that.actualRotation + 'deg)',
  1059. '-moz-transform': 'rotate(' + that.actualRotation + 'deg)',
  1060. 'transform': 'rotate(' + that.actualRotation + 'deg)',
  1061. });
  1062. }
  1063. that.actualRotationImgH = 0;
  1064. that.actualRotationImgW = 0;
  1065. if (that.actualRotation != 0) {
  1066. var actualRotation = that.actualRotation % 360;
  1067. if (actualRotation < 0) {
  1068. actualRotation = 0 - actualRotation;
  1069. }
  1070. if (actualRotation == 90 || actualRotation == 270) {
  1071. if (that.imgH > that.imgW) {
  1072. that.actualRotationImgW = parseInt((that.imgH - that.imgW) / 2);
  1073. } else if (that.imgH < that.imgW) {
  1074. that.actualRotationImgH = parseInt((that.imgW - that.imgH) / 2);
  1075. }
  1076. } else if (actualRotation != 180 && actualRotation != 360) {
  1077. if (actualRotation > 180) {
  1078. actualRotation = actualRotation - 180;
  1079. }
  1080. if (actualRotation > 90) {
  1081. actualRotation = 180 - actualRotation;
  1082. }
  1083. var radian = Math.sin(actualRotation * Math.PI / 180);
  1084. that.actualRotationImgW = parseInt(radian * (that.imgH) / 2);
  1085. that.actualRotationImgH = parseInt(radian * (that.imgW) / 2);
  1086. }
  1087. }
  1088. if (typeof that.options.onImgRotate == 'function')
  1089. that.options.onImgRotate.call(that);
  1090. },
  1091. zoom: function (x) {
  1092. var that = this;
  1093. that.colorOnClick(true);
  1094. var ratio = that.imgW / that.imgH;
  1095. var newWidth = that.imgW + x;
  1096. var newHeight = newWidth / ratio;
  1097. var doPositioning = true;
  1098. if (x == 0) {
  1099. if (newWidth - that.objW < newHeight - that.objH) {
  1100. newWidth = that.objW;
  1101. newHeight = newWidth / ratio;
  1102. } else {
  1103. newHeight = that.objH;
  1104. newWidth = ratio * newHeight;
  1105. }
  1106. }
  1107. if (newWidth < that.objW || newHeight < that.objH) {
  1108. doPositioning = false;
  1109. }
  1110. if (!that.options.scaleToFill && (newWidth > that.imgInitW || newHeight > that.imgInitH)) {
  1111. doPositioning = false;
  1112. }
  1113. that.imgW = newWidth;
  1114. that.img.width(newWidth);
  1115. that.imgH = newHeight;
  1116. that.img.height(newHeight);
  1117. var newTop = parseInt(that.img.css('top')) - x / 2;
  1118. var newLeft = parseInt(that.img.css('left')) - x / 2;
  1119. that.actualRotationImgH = 0;
  1120. that.actualRotationImgW = 0;
  1121. if (that.actualRotation != 0) {
  1122. var actualRotation = that.actualRotation % 360;
  1123. if (actualRotation < 0) {
  1124. actualRotation = 0 - actualRotation;
  1125. }
  1126. if (actualRotation == 90 || actualRotation == 270) {
  1127. if (that.imgH > that.imgW) {
  1128. that.actualRotationImgW = parseInt((that.imgH - that.imgW) / 2);
  1129. } else if (that.imgH < that.imgW) {
  1130. that.actualRotationImgH = parseInt((that.imgW - that.imgH) / 2);
  1131. }
  1132. } else if (actualRotation != 180 && actualRotation != 360) {
  1133. if (actualRotation > 180) {
  1134. actualRotation = actualRotation - 180;
  1135. }
  1136. if (actualRotation > 90) {
  1137. actualRotation = 180 - actualRotation;
  1138. }
  1139. var radian = Math.sin(actualRotation * Math.PI / 180);
  1140. that.actualRotationImgW = parseInt(radian * (that.imgH) / 2);
  1141. that.actualRotationImgH = parseInt(radian * (that.imgW) / 2);
  1142. }
  1143. }
  1144. if (newTop > -that.actualRotationImgH) {
  1145. newTop = -that.actualRotationImgH;
  1146. }
  1147. if (newLeft > -that.actualRotationImgW) {
  1148. newLeft = -that.actualRotationImgW;
  1149. }
  1150. var maxTop = -(newHeight - that.objH + that.actualRotationImgH);
  1151. if (newTop < maxTop) {
  1152. newTop = maxTop;
  1153. }
  1154. var maxLeft = -(newWidth - that.objW + that.actualRotationImgW);
  1155. if (newLeft < maxLeft) {
  1156. newLeft = maxLeft;
  1157. }
  1158. if (doPositioning) {
  1159. that.img.css({'top': newTop, 'left': newLeft});
  1160. }
  1161. if (that.options.imgEyecandy) {
  1162. that.imgEyecandy.width(newWidth);
  1163. that.imgEyecandy.height(newHeight);
  1164. if (doPositioning) {
  1165. that.imgEyecandy.css({'top': newTop, 'left': newLeft});
  1166. }
  1167. }
  1168. if (that.options.onImgZoom) that.options.onImgZoom.call(that);
  1169. },
  1170. crop: function () {
  1171. var that = this;
  1172. that.colorOnClick(true);
  1173. if (that.options.onBeforeImgCrop) that.options.onBeforeImgCrop.call(that);
  1174. that.cropControlsCrop.hide();
  1175. that.showLoader();
  1176. var cropData = {
  1177. imgInitW: that.imgInitW,
  1178. imgInitH: that.imgInitH,
  1179. imgW: that.imgW,
  1180. imgH: that.imgH,
  1181. imgY1: parseInt(that.img.css('top')),
  1182. imgX1: parseInt(that.img.css('left')),
  1183. cropH: that.objH,
  1184. cropW: that.objW,
  1185. rotation: that.actualRotation,
  1186. imgBackground: that.imgBackground
  1187. };
  1188. var formData = new FormData();
  1189. for (var key in cropData) {
  1190. if (cropData.hasOwnProperty(key)) {
  1191. formData.append(key, cropData[key]);
  1192. }
  1193. }
  1194. for (var key in that.options.cropData) {
  1195. if (that.options.cropData.hasOwnProperty(key)) {
  1196. formData.append(key, that.options.cropData[key]);
  1197. }
  1198. }
  1199. if (that.imgName == '') {
  1200. formData.append("imgUrl", that.convertBase64UrlToBlob(that.imgUrl));
  1201. } else {
  1202. formData.append("imgName", that.imgName);
  1203. }
  1204. var xhr = new XMLHttpRequest();
  1205. xhr.open("POST", that.options.cropUrl);
  1206. xhr.responseType = "blob";
  1207. xhr.timeout = 60000 * 5;
  1208. xhr.onload = function () {
  1209. that.afterCrop(xhr);
  1210. };
  1211. xhr.send(formData);
  1212. },
  1213. convertBase64UrlToBlob: function (urlData) {
  1214. var arr = urlData.split(',');
  1215. var mime = arr[0].match(/:(.*?);/)[1];
  1216. var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte
  1217. //处理异常,将ascii码小于0的转换为大于0
  1218. var ab = new ArrayBuffer(bytes.length);
  1219. var ia = new Uint8Array(ab);
  1220. for (var i = 0; i < bytes.length; i++) {
  1221. ia[i] = bytes.charCodeAt(i);
  1222. }
  1223. return new Blob([ab], {type: mime});
  1224. },
  1225. getFileMime: function (urlData) {
  1226. var arr = urlData.split(',');
  1227. return arr[0].match(/:(.*?);/)[1];
  1228. },
  1229. getFileExt: function (urlData) {
  1230. var arr = urlData.split(',');
  1231. var mime = arr[0].match(/:(.*?);/)[1];
  1232. var FileExt;
  1233. switch (mime) {
  1234. case "image/jpeg":
  1235. FileExt = "jpg";
  1236. break;
  1237. case "image/png":
  1238. FileExt = "png";
  1239. break;
  1240. case "image/gif":
  1241. FileExt = "gif";
  1242. break;
  1243. default:
  1244. FileExt = "jpg";
  1245. }
  1246. return FileExt;
  1247. },
  1248. afterCrop: function (xhr) {
  1249. var that = this;
  1250. if (xhr.readyState === 4 && xhr.status === 200) {
  1251. var Error = xhr.getResponseHeader("Content-My-Error");
  1252. if (Error != null) {
  1253. var ErrorMeg = decodeURIComponent(atob(Error).split('').map(function (c) {
  1254. return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  1255. }).join(''));
  1256. if (that.options.onError) that.options.onError.call(that, ErrorMeg);
  1257. that.cropControlsCrop.show();
  1258. that.hideLoader();
  1259. return;
  1260. }
  1261. if (that.options.imgEyecandy)
  1262. that.imgEyecandy.hide();
  1263. var filename = xhr.getResponseHeader("Content-My-filename");
  1264. var blob = xhr.response;
  1265. var reader = new FileReader();
  1266. reader.onload = function (e) {
  1267. that.destroy();
  1268. that.saveImgUrl = 'product_image_crop_md5,' + filename + ',' + e.target.result;
  1269. var croppedImg = '<img class="croppedImg" src="' + e.target.result + '">';
  1270. that.obj.append(croppedImg);
  1271. if (that.options.outputUrlId !== '') {
  1272. $('#' + that.options.outputUrlId).val(response.url);
  1273. }
  1274. that.croppedImg = that.obj.find('.croppedImg');
  1275. that.croppedImg.width(that.objW + "px").height(that.objH + "px");
  1276. that.init();
  1277. that.hideLoader();
  1278. that.imgUploadControl.hide();
  1279. that.cropSaveControl.show();
  1280. }
  1281. reader.readAsDataURL(blob);
  1282. } else {
  1283. if (that.options.onError) that.options.onError.call(that, "处理失败,错误代码["+xhr.readyState+"]=>"+ xhr.response.messageerror);
  1284. that.hideLoader();
  1285. that.cropControlsCrop.show();
  1286. }
  1287. if (that.options.onAfterImgCrop) that.options.onAfterImgCrop.call(that, xhr.response);
  1288. },
  1289. showLoader: function () {
  1290. var that = this;
  1291. that.obj.append(that.options.loaderHtml);
  1292. that.loader = that.obj.find('.loader');
  1293. },
  1294. hideLoader: function () {
  1295. var that = this;
  1296. that.loader.remove();
  1297. },
  1298. reset: function () {
  1299. var that = this;
  1300. that.destroy();
  1301. that.init();
  1302. that.imgUploadControl.show();
  1303. if (!$.isEmptyObject(that.croppedImg)) {
  1304. that.obj.append(that.croppedImg);
  1305. if (that.options.outputUrlId !== '') {
  1306. $('#' + that.options.outputUrlId).val(that.croppedImg.attr('url'));
  1307. }
  1308. }
  1309. if (typeof that.options.onReset == 'function')
  1310. that.options.onReset.call(that);
  1311. },
  1312. destroy: function () {
  1313. var that = this;
  1314. that.colorOnClick(true);
  1315. if (that.options.modal && !$.isEmptyObject(that.modal)) {
  1316. that.destroyModal();
  1317. }
  1318. if (that.options.imgEyecandy && !$.isEmptyObject(that.imgEyecandy)) {
  1319. that.destroyEyecandy();
  1320. }
  1321. if (!$.isEmptyObject(that.cropControlsUpload)) {
  1322. that.cropControlsUpload.remove();
  1323. }
  1324. if (!$.isEmptyObject(that.cropControlsCrop)) {
  1325. that.cropControlsCrop.remove();
  1326. }
  1327. if (!$.isEmptyObject(that.loader)) {
  1328. that.loader.remove();
  1329. }
  1330. if (!$.isEmptyObject(that.form)) {
  1331. that.form.remove();
  1332. }
  1333. that.obj.html('');
  1334. },
  1335. isAjaxUploadSupported: function () {
  1336. var input = document.createElement("input");
  1337. input.type = "file";
  1338. return (
  1339. "multiple" in input &&
  1340. typeof File != "undefined" &&
  1341. typeof FormData != "undefined" &&
  1342. typeof (new XMLHttpRequest()).upload != "undefined");
  1343. },
  1344. CreateFallbackIframe: function () {
  1345. var that = this;
  1346. if (!that.isAjaxUploadSupported()) {
  1347. if (jQuery.isEmptyObject(that.iframeobj)) {
  1348. var iframe = document.createElement("iframe");
  1349. iframe.setAttribute("id", that.id + "_upload_iframe");
  1350. iframe.setAttribute("name", that.id + "_upload_iframe");
  1351. iframe.setAttribute("width", "0");
  1352. iframe.setAttribute("height", "0");
  1353. iframe.setAttribute("border", "0");
  1354. iframe.setAttribute("src", "javascript:false;");
  1355. iframe.style.display = "none";
  1356. document.body.appendChild(iframe);
  1357. } else {
  1358. iframe = that.iframeobj[0];
  1359. }
  1360. var myContent = '<!DOCTYPE html>'
  1361. + '<html><head><title>Uploading File</title></head>'
  1362. + '<body>'
  1363. + '<form '
  1364. + 'class="' + that.id + '_upload_iframe_form" '
  1365. + 'name="' + that.id + '_upload_iframe_form" '
  1366. + 'action="' + that.options.uploadUrl + '" method="post" '
  1367. + 'enctype="multipart/form-data" encoding="multipart/form-data" style="display:none;">'
  1368. + $("#" + that.id + '_imgUploadField')[0].outerHTML
  1369. + '</form></body></html>';
  1370. iframe.contentWindow.document.open('text/htmlreplace');
  1371. iframe.contentWindow.document.write(myContent);
  1372. iframe.contentWindow.document.close();
  1373. that.iframeobj = $("#" + that.id + "_upload_iframe");
  1374. that.iframeform = that.iframeobj.contents().find("html").find("." + that.id + "_upload_iframe_form");
  1375. that.iframeform.on("change", "input", function () {
  1376. that.SubmitFallbackIframe(that);
  1377. });
  1378. that.iframeform.find("input")[0].attachEvent("onchange", function () {
  1379. that.SubmitFallbackIframe(that);
  1380. });
  1381. var eventHandlermyFile = function () {
  1382. if (iframe.detachEvent)
  1383. iframe.detachEvent("onload", eventHandlermyFile);
  1384. else
  1385. iframe.removeEventListener("load", eventHandlermyFile, false);
  1386. var response = that.getIframeContentJSON(iframe);
  1387. if (jQuery.isEmptyObject(that.modal)) {
  1388. that.afterUpload(response);
  1389. }
  1390. }
  1391. if (iframe.addEventListener)
  1392. iframe.addEventListener("load", eventHandlermyFile, true);
  1393. if (iframe.attachEvent)
  1394. iframe.attachEvent("onload", eventHandlermyFile);
  1395. return "#" + that.id + '_imgUploadField';
  1396. } else {
  1397. return "";
  1398. }
  1399. },
  1400. SubmitFallbackIframe: function (that) {
  1401. that.showLoader();
  1402. if (that.options.processInline && !that.options.uploadUrl) {
  1403. if (that.options.onError) {
  1404. that.options.onError.call(that, "processInline is not supported by your browser ");
  1405. that.hideLoader();
  1406. }
  1407. } else {
  1408. if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that);
  1409. that.iframeform[0].submit();
  1410. }
  1411. },
  1412. getIframeContentJSON: function (iframe) {
  1413. try {
  1414. var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document,
  1415. response;
  1416. var innerHTML = doc.body.innerHTML;
  1417. if (innerHTML.slice(0, 5).toLowerCase() == "<pre>" && innerHTML.slice(-6).toLowerCase() == "</pre>") {
  1418. innerHTML = doc.body.firstChild.firstChild.nodeValue;
  1419. }
  1420. response = jQuery.parseJSON(innerHTML);
  1421. } catch (err) {
  1422. response = {success: false};
  1423. }
  1424. return response;
  1425. },
  1426. hexadecimal: function (num) {
  1427. var r = parseInt(num).toString(16);
  1428. if (r.length == 1) {
  1429. return '0' + r;
  1430. }
  1431. return r.toUpperCase();
  1432. }
  1433. };
  1434. })(window, document);