croppic.js 64 KB

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