croppic.js 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  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. // DEFAULT OPTIONS
  15. that.options = {
  16. uploadUrl:'',
  17. uploadData:{},
  18. cropUrl:'',
  19. cropData:{},
  20. outputUrlId:'',
  21. //styles
  22. imgEyecandy:true,
  23. imgEyecandyOpacity:0.2,
  24. initialZoom:40,
  25. zoomFactor:10,
  26. rotateFactor:5,
  27. doubleZoomControls:true,
  28. rotateControls: true,
  29. modal:false,
  30. customUploadButtonId:'',
  31. customSaveButtonId:'',
  32. loaderHtml:'',
  33. scaleToFill: true,
  34. processInline: false,
  35. loadPicture:'',
  36. onReset: null,
  37. enableMousescroll: false,
  38. //callbacks
  39. onBeforeImgUpload: null,
  40. onAfterImgUpload: null,
  41. onImgDrag: null,
  42. onImgZoom: null,
  43. onImgRotate: null,
  44. onBeforeImgCrop: null,
  45. onAfterImgCrop: null,
  46. onBeforeRemoveCroppedImg: null,
  47. onAfterRemoveCroppedImg: null,
  48. onError: null,
  49. };
  50. // OVERWRITE DEFAULT OPTIONS
  51. for (i in options) that.options[i] = options[i];
  52. // INIT THE WHOLE DAMN THING!!!
  53. that.init();
  54. };
  55. Croppic.prototype = {
  56. id:'',
  57. imgInitW:0,
  58. imgInitH:0,
  59. imgW:0,
  60. imgH:0,
  61. actualRotationImgW:0,
  62. actualRotationImgH:0,
  63. objW:0,
  64. objH:0,
  65. actualRotation: 0,
  66. windowW:0,
  67. windowH:$(window).height(),
  68. obj:{},
  69. outputDiv:{},
  70. outputUrlObj:{},
  71. img:{},
  72. defaultImg:{},
  73. croppedImg:{},
  74. imgEyecandy:{},
  75. form:{},
  76. iframeform: {},
  77. iframeobj: {},
  78. cropControlsUpload:{},
  79. cropControlsCrop:{},
  80. cropControlZoomMuchIn:{},
  81. cropControlZoomMuchOut:{},
  82. cropControlZoomIn:{},
  83. cropControlZoomOut:{},
  84. cropControlCrop:{},
  85. cropControlReset:{},
  86. cropControlRemoveCroppedImage:{},
  87. cropControlOriginal:{},
  88. modal:{},
  89. loader:{},
  90. cropSaveControl:{},
  91. init: function () {
  92. var that = this;
  93. that.objW = that.obj.width();
  94. that.objH = that.obj.height();
  95. // reset rotation
  96. that.actualRotation = 0;
  97. that.actualRotationImgH=0;
  98. that.actualRotationImgW=0;
  99. if( $.isEmptyObject(that.defaultImg)){ that.defaultImg = that.obj.find('img'); }
  100. that.createImgUploadControls();
  101. if( $.isEmptyObject(that.options.loadPicture)){
  102. that.bindImgUploadControl();
  103. }else{
  104. that.loadExistingImage();
  105. }
  106. },
  107. createImgUploadControls: function(){
  108. var that = this;
  109. var cropControlUpload = '';
  110. if(that.options.customUploadButtonId ===''){ cropControlUpload = '<i class="cropControlUpload"></i>'; }
  111. var cropControlRemoveCroppedImage = '<i class="cropControlRemoveCroppedImage"></i>';
  112. var cropControlOriginal = '<i class="cropControlOriginal"></i>';
  113. if( $.isEmptyObject(that.croppedImg))
  114. {
  115. cropControlRemoveCroppedImage='';
  116. cropControlOriginal='';
  117. }
  118. if( !$.isEmptyObject(that.options.loadPicture)){ cropControlUpload='';}
  119. var html = '<div class="cropControls cropControlsUpload"> ' + cropControlUpload + cropControlOriginal + cropControlRemoveCroppedImage + ' </div>';
  120. that.outputDiv.append(html);
  121. that.cropControlsUpload = that.outputDiv.find('.cropControlsUpload');
  122. if(that.options.customUploadButtonId ===''){ that.imgUploadControl = that.outputDiv.find('.cropControlUpload'); }
  123. else{ that.imgUploadControl = $('#'+that.options.customUploadButtonId); that.imgUploadControl.show(); }
  124. if(that.options.customSaveButtonId !==''){
  125. that.cropSaveControl= $('#'+that.options.customSaveButtonId); that.cropSaveControl.hide();
  126. }
  127. if( !$.isEmptyObject(that.croppedImg)){
  128. that.cropControlRemoveCroppedImage = that.outputDiv.find('.cropControlRemoveCroppedImage');
  129. that.cropControlOriginal = that.outputDiv.find('.cropControlOriginal');
  130. }
  131. },
  132. bindImgUploadControl: function(){
  133. var that = this;
  134. // CREATE UPLOAD IMG FORM
  135. var formHtml = '<form class="' + that.id + '_imgUploadForm" style="visibility: hidden;"> <input type="file" name="img" id="' + that.id + '_imgUploadField"> </form>';
  136. that.outputDiv.append(formHtml);
  137. that.form = that.outputDiv.find('.'+that.id+'_imgUploadForm');
  138. // CREATE FALLBACK IE9 IFRAME
  139. var fileUploadId = that.CreateFallbackIframe();
  140. that.imgUploadControl.off('click');
  141. that.imgUploadControl.on('click',function(){
  142. if (fileUploadId === "") {
  143. that.form.find('input[type="file"]').trigger('click');
  144. } else {
  145. //Trigger iframe file input click, otherwise access restriction error
  146. that.iframeform.find('input[type="file"]').trigger('click');
  147. }
  148. });
  149. that.cropSaveControl.off('click');
  150. that.cropSaveControl.on('click',function(){
  151. var res = confirm('您确定要使用编辑好的图片吗?\n\r' +
  152. '[确认]使用图片\n\r' +
  153. '[取消]继续编辑');
  154. if (res) {
  155. that.destroy();
  156. window.location.href="https://wwww.croppic.com?"+that.saveImgUrl;
  157. }
  158. });
  159. if( !$.isEmptyObject(that.croppedImg)){
  160. that.cropControlRemoveCroppedImage.on('click',function(){
  161. if (typeof (that.options.onBeforeRemoveCroppedImg) === typeof(Function)) {
  162. that.options.onBeforeRemoveCroppedImg.call(that);
  163. }
  164. var res = confirm('您是要使用当前图片还是重新选择图片?\n\r' +
  165. '[确认]使用当前图片\n\r' +
  166. '[取消]重新选择图片');
  167. var width= that.imgInitW;
  168. var height= that.imgInitH;
  169. that.croppedImg.remove();
  170. that.croppedImg = {};
  171. $(this).hide();
  172. that.cropSaveControl.hide();
  173. that.cropControlOriginal.hide();
  174. if (typeof (that.options.onAfterRemoveCroppedImg) === typeof(Function)) {
  175. that.options.onAfterRemoveCroppedImg.call(that);
  176. }
  177. if( !$.isEmptyObject(that.defaultImg)){
  178. that.obj.append(that.defaultImg);
  179. }
  180. if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(''); }
  181. that.imgUploadControl.show();
  182. if (res) {
  183. that.showLoader();
  184. that.imgUploadControl.hide();
  185. if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); }
  186. that.imgInitW = that.imgW = width;
  187. that.imgInitH = that.imgH = height;
  188. that.saveImgUrl="";
  189. that.obj.append('<img src="'+that.imgUrl+'">');
  190. that.initCropper();
  191. that.hideLoader();
  192. }
  193. });
  194. that.cropControlOriginal.on('click',function(){
  195. if (that.imgUrl=='')
  196. {
  197. alert('请选择图片' );
  198. return;
  199. }
  200. var res = confirm('您确定要使用原图吗?\n\r' +
  201. '[确认]使用原图\n\r' +
  202. '[取消]继续编辑');
  203. if (res) {
  204. that.destroy();
  205. window.location.href="https://wwww.croppic.com?"+that.imgUrl;
  206. }
  207. });
  208. }
  209. that.form.find('input[type="file"]').change(function(){
  210. if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that);
  211. that.showLoader();
  212. that.imgUploadControl.hide();
  213. if(that.options.processInline){
  214. // Checking Browser Support for FileReader API
  215. if (typeof FileReader == "undefined"){
  216. if (that.options.onError) that.options.onError.call(that,"processInline is not supported by your Browser");
  217. that.reset();
  218. }else{
  219. var filePath=that.form.find('input[type="file"]')[0].files[0];
  220. if( !$.isEmptyObject(that.croppedImg)){
  221. that.destroy();
  222. }
  223. var reader = new FileReader();
  224. reader.onload = function (e) {
  225. var image = new Image();
  226. image.src = e.target.result;
  227. image.onload = function(){
  228. that.imgInitW = that.imgW = image.width;
  229. that.imgInitH = that.imgH = image.height;
  230. if(that.options.modal){ that.createModal(); }
  231. if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); }
  232. that.imgUrl=image.src;
  233. that.saveImgUrl="";
  234. that.obj.append('<img src="'+image.src+'">');
  235. that.initCropper();
  236. that.hideLoader();
  237. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  238. }
  239. };
  240. reader.readAsDataURL(filePath);
  241. }
  242. } else {
  243. try {
  244. // other modern browsers
  245. formData = new FormData(that.form[0]);
  246. } catch(e) {
  247. // IE10 MUST have all form items appended as individual form key / value pairs
  248. formData = new FormData();
  249. formData.append('img', that.form.find("input[type=file]")[0].files[0]);
  250. }
  251. for (var key in that.options.uploadData) {
  252. if( that.options.uploadData.hasOwnProperty(key) ) {
  253. formData.append( key , that.options.uploadData[key] );
  254. }
  255. }
  256. $.ajax({
  257. url: that.options.uploadUrl,
  258. data: formData,
  259. context: document.body,
  260. cache: false,
  261. contentType: false,
  262. processData: false,
  263. type: 'POST'
  264. }).always(function (data) {
  265. that.afterUpload(data);
  266. });
  267. }
  268. });
  269. },
  270. loadExistingImage: function(){
  271. var that = this;
  272. if( $.isEmptyObject(that.croppedImg)){
  273. if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that);
  274. that.showLoader();
  275. if(that.options.modal){ that.createModal(); }
  276. if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); }
  277. that.imgUrl=that.options.loadPicture ;
  278. var img =$('<img src="'+ that.options.loadPicture +'">');
  279. that.obj.append(img);
  280. img.load(function() {
  281. that.imgInitW = that.imgW = this.width;
  282. that.imgInitH = that.imgH = this.height;
  283. that.initCropper();
  284. that.hideLoader();
  285. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  286. });
  287. }else{
  288. that.cropControlRemoveCroppedImage.on('click',function(){
  289. var res = confirm('您是要使用当前图片还是重新选择图片?\n\r' +
  290. '[确认]使用当前图片\n\r' +
  291. '[取消]重新选择图片');
  292. var width= that.imgInitW;
  293. var height= that.imgInitH;
  294. that.croppedImg.remove();
  295. $(this).hide();
  296. that.cropSaveControl.hide();
  297. that.cropControlOriginal.hide();
  298. if( !$.isEmptyObject(that.defaultImg)){
  299. that.obj.append(that.defaultImg);
  300. }
  301. if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(''); }
  302. that.croppedImg = '';
  303. that.reset();
  304. if (res) {
  305. that.showLoader();
  306. that.imgUploadControl.hide();
  307. if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); }
  308. that.imgInitW = that.imgW = width;
  309. that.imgInitH = that.imgH = height;
  310. that.saveImgUrl="";
  311. that.obj.append('<img src="'+that.imgUrl+'">');
  312. that.initCropper();
  313. that.hideLoader();
  314. }
  315. });
  316. }
  317. },
  318. afterUpload: function(data){
  319. var that = this;
  320. response = typeof data =='object' ? data : jQuery.parseJSON(data);
  321. if (response.status == 'success') {
  322. that.imgInitW = that.imgW = response.width;
  323. that.imgInitH = that.imgH = response.height;
  324. if (that.options.modal) { that.createModal(); }
  325. if (!$.isEmptyObject(that.croppedImg)) { that.croppedImg.remove(); }
  326. that.imgUrl = response.url;
  327. var img = $('<img src="'+response.url+'">')
  328. that.obj.append(img);
  329. img.load(function(){
  330. that.initCropper();
  331. that.hideLoader();
  332. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  333. });
  334. if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that);
  335. }
  336. if (response.status == 'error') {
  337. alert(response.message);
  338. if (that.options.onError) that.options.onError.call(that,response.message);
  339. that.hideLoader();
  340. // setTimeout( function(){ that.reset(); },2000)
  341. }
  342. },
  343. createModal: function(){
  344. var that = this;
  345. var marginTop = that.windowH/2-that.objH/2;
  346. 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>';
  347. $('body').append(modalHTML);
  348. that.modal = $('#croppicModal');
  349. that.obj = $('#croppicModalObj');
  350. },
  351. destroyModal: function(){
  352. var that = this;
  353. that.obj = that.outputDiv;
  354. that.modal.remove();
  355. that.modal = {};
  356. },
  357. initCropper: function(){
  358. var that = this;
  359. /*SET UP SOME VARS*/
  360. that.img = that.obj.find('img');
  361. that.img.wrap('<div class="cropImgWrapper" style="overflow:hidden; z-index:1; position:absolute; width:'+that.objW+'px; height:'+that.objH+'px;"></div>');
  362. /*INIT DRAGGING*/
  363. that.createCropControls();
  364. if(that.options.imgEyecandy){ that.createEyecandy(); }
  365. that.initDrag();
  366. that.initialScaleImg();
  367. },
  368. createEyecandy: function(){
  369. var that = this;
  370. that.imgEyecandy = that.img.clone();
  371. that.imgEyecandy.css({'z-index':'0','opacity':that.options.imgEyecandyOpacity}).appendTo(that.obj);
  372. },
  373. destroyEyecandy: function(){
  374. var that = this;
  375. that.imgEyecandy.remove();
  376. },
  377. initialScaleImg:function(){
  378. var that = this;
  379. that.zoom(-that.imgInitW);
  380. that.zoom(that.options.initialZoom);
  381. // Adding mousewheel zoom capabilities
  382. if (that.options.enableMousescroll){
  383. that.img.on('mousewheel', function(event) {
  384. event.preventDefault();
  385. that.zoom(that.options.zoomFactor*event.deltaY);
  386. });
  387. }
  388. // initial center image
  389. that.img.css({'left': -(that.imgW -that.objW)/2, 'top': -(that.imgH -that.objH)/2, 'position':'relative'});
  390. if(that.options.imgEyecandy){ that.imgEyecandy.css({'left': -(that.imgW -that.objW)/2, 'top': -(that.imgH -that.objH)/2, 'position':'relative'}); }
  391. },
  392. createCropControls: function(){
  393. var that = this;
  394. // CREATE CONTROLS
  395. var cropControlZoomMuchIn = '';
  396. var cropControlZoomIn = '<i class="cropControlZoomIn"></i>';
  397. var cropControlZoomOut = '<i class="cropControlZoomOut"></i>';
  398. var cropControlZoomMuchOut = '';
  399. var cropControlRotateLeft = '';
  400. var cropControlRotateRight = '';
  401. var cropControlCrop = '<i class="cropControlCrop"></i>';
  402. var cropControlReset = '<i class="cropControlReset"></i>';
  403. var cropControlOriginal = '<i class="cropControlOriginal"></i>';
  404. var html;
  405. if(that.options.doubleZoomControls){
  406. cropControlZoomMuchIn = '<i class="cropControlZoomMuchIn"></i>';
  407. cropControlZoomMuchOut = '<i class="cropControlZoomMuchOut"></i>';
  408. }
  409. if(that.options.rotateControls){
  410. cropControlRotateLeft = '<i class="cropControlRotateLeft"></i>';
  411. cropControlRotateRight = '<i class="cropControlRotateRight"></i>';
  412. }
  413. html = '<div class="cropControls cropControlsCrop">'+ cropControlZoomMuchIn + cropControlZoomIn + cropControlZoomOut + cropControlZoomMuchOut + cropControlRotateLeft + cropControlRotateRight + cropControlCrop + '</div>';
  414. that.obj.append(html);
  415. html = '<div class="cropControls cropControlsCrop cropControlsUpload">' + cropControlOriginal + cropControlReset + '</div>';
  416. that.obj.append(html);
  417. that.cropControlsCrop = that.obj.find('.cropControlsCrop');
  418. // CACHE AND BIND CONTROLS
  419. if(that.options.doubleZoomControls){
  420. that.cropControlZoomMuchIn = that.cropControlsCrop.find('.cropControlZoomMuchIn');
  421. that.cropControlZoomMuchIn.on('click',function(){ that.zoom( that.options.zoomFactor*10 ); });
  422. that.cropControlZoomMuchOut = that.cropControlsCrop.find('.cropControlZoomMuchOut');
  423. that.cropControlZoomMuchOut.on('click',function(){ that.zoom(-that.options.zoomFactor*10); });
  424. }
  425. that.cropControlZoomIn = that.cropControlsCrop.find('.cropControlZoomIn');
  426. that.cropControlZoomIn.on('click',function(){ that.zoom(that.options.zoomFactor); });
  427. that.cropControlZoomOut = that.cropControlsCrop.find('.cropControlZoomOut');
  428. that.cropControlZoomOut.on('click',function(){ that.zoom(-that.options.zoomFactor); });
  429. that.cropControlRotateLeft = that.cropControlsCrop.find('.cropControlRotateLeft');
  430. that.touchtimeLeft = new Date().getTime();
  431. that.cropControlRotateLeft.on('click', function() {
  432. if(new Date().getTime()-that.touchtimeLeft > 300 ){
  433. that.rotate(-that.options.rotateFactor);
  434. that.touchtimeLeft = new Date().getTime();
  435. }else{
  436. that.rotate(-45);
  437. }
  438. });
  439. that.cropControlRotateRight = that.cropControlsCrop.find('.cropControlRotateRight');
  440. that.touchtimeRight = new Date().getTime();
  441. that.cropControlRotateRight.on('click', function() {
  442. if(new Date().getTime()-that.touchtimeRight > 300 ){
  443. that.rotate(that.options.rotateFactor);
  444. that.touchtimeRight = new Date().getTime();
  445. }else{
  446. that.rotate(45);
  447. }
  448. });
  449. that.cropControlCrop = that.cropControlsCrop.find('.cropControlCrop');
  450. that.cropControlCrop.on('click',function(){ that.crop(); });
  451. that.cropControlReset = that.cropControlsCrop.find('.cropControlReset');
  452. that.cropControlReset.on('click',function(){
  453. var res = confirm('您是要使用当前图片还是重新选择图片?\n\r' +
  454. '[确认]使用当前图片\n\r' +
  455. '[取消]重新选择图片');
  456. var width= that.imgInitW;
  457. var height= that.imgInitH;
  458. that.reset();
  459. if (res) {
  460. that.showLoader();
  461. that.imgUploadControl.hide();
  462. if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); }
  463. that.imgInitW = that.imgW = width;
  464. that.imgInitH = that.imgH = height;
  465. that.saveImgUrl="";
  466. that.obj.append('<img src="'+that.imgUrl+'">');
  467. that.initCropper();
  468. that.hideLoader();
  469. }
  470. });
  471. that.cropControlOriginal = that.cropControlsCrop.find('.cropControlOriginal');
  472. that.cropControlOriginal.on('click',function(){
  473. if (that.imgUrl=='')
  474. {
  475. alert('请选择图片' );
  476. return;
  477. }
  478. var res = confirm('您确定要使用原图吗?\n\r' +
  479. '[确认]使用原图\n\r' +
  480. '[取消]继续编辑');
  481. if (res) {
  482. that.destroy();
  483. window.location.href="https://wwww.croppic.com?"+that.imgUrl;
  484. }
  485. });
  486. },
  487. initDrag:function(){
  488. var that = this;
  489. that.img.on("mousedown touchstart", function(e) {
  490. e.preventDefault(); // disable selection
  491. var pageX;
  492. var pageY;
  493. var userAgent = window.navigator.userAgent;
  494. if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i) || userAgent.match(/android/i) || (e.pageY && e.pageX) == undefined) {
  495. pageX = e.originalEvent.touches[0].pageX;
  496. pageY = e.originalEvent.touches[0].pageY;
  497. } else {
  498. pageX = e.pageX;
  499. pageY = e.pageY;
  500. }
  501. var z_idx = that.img.css('z-index'),
  502. drg_h = that.img.outerHeight(),
  503. drg_w = that.img.outerWidth(),
  504. pos_y = that.img.offset().top + drg_h - pageY,
  505. pos_x = that.img.offset().left + drg_w - pageX;
  506. that.img.css('z-index', 1000).on("mousemove touchmove", function(e) {
  507. var imgTop;
  508. var imgLeft;
  509. if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i) || userAgent.match(/android/i) || (e.pageY && e.pageX) == undefined) {
  510. imgTop = e.originalEvent.touches[0].pageY + pos_y - drg_h;
  511. imgLeft = e.originalEvent.touches[0].pageX + pos_x - drg_w;
  512. } else {
  513. imgTop = e.pageY + pos_y - drg_h;
  514. imgLeft = e.pageX + pos_x - drg_w;
  515. }
  516. that.img.offset({
  517. top:imgTop,
  518. left:imgLeft
  519. }).on("mouseup", function() {
  520. $(this).removeClass('draggable').css('z-index', z_idx);
  521. });
  522. if(that.options.imgEyecandy){ that.imgEyecandy.offset({ top:imgTop, left:imgLeft }); }
  523. var top=that.actualRotationImgH;
  524. var left=that.actualRotationImgW;
  525. // var top=0;
  526. // var left=0;
  527. if (that.objH < that.imgH+top*2) {
  528. if (parseInt(that.img.css('top')) > top) { that.img.css('top', top); if (that.options.imgEyecandy) { that.imgEyecandy.css('top', top);}}
  529. var maxTop = -( that.imgH - that.objH+top); if (parseInt(that.img.css('top')) < maxTop) { that.img.css('top', maxTop); if (that.options.imgEyecandy) { that.imgEyecandy.css('top', maxTop); }}
  530. }else{
  531. if (parseInt(that.img.css('top')) < -top) { that.img.css('top', -top); if (that.options.imgEyecandy) { that.imgEyecandy.css('top', top); }}
  532. var maxTop = that.objH - that.imgH+top; if (parseInt(that.img.css('top')) > maxTop) { that.img.css('top', maxTop);if (that.options.imgEyecandy) {that.imgEyecandy.css('top', maxTop); }}
  533. }
  534. if (that.objW < that.imgW+2*left) {
  535. if( parseInt( that.img.css('left')) > left ){ that.img.css('left',left); if(that.options.imgEyecandy){ that.imgEyecandy.css('left', left); }}
  536. var maxLeft = -( that.imgW-that.objW+left); if( parseInt( that.img.css('left')) < maxLeft){ that.img.css('left', maxLeft); if(that.options.imgEyecandy){ that.imgEyecandy.css('left', maxLeft); } }
  537. }else{
  538. if( parseInt( that.img.css('left')) < -left ){ that.img.css('left',-left); if(that.options.imgEyecandy){ that.imgEyecandy.css('left', 0); }}
  539. var maxLeft = ( that.objW - that.imgW+left); if( parseInt( that.img.css('left')) > maxLeft){ that.img.css('left', maxLeft); if(that.options.imgEyecandy){ that.imgEyecandy.css('left', maxLeft); } }
  540. }
  541. if (that.options.onImgDrag) that.options.onImgDrag.call(that);
  542. });
  543. }).on("mouseup", function() {
  544. that.img.off("mousemove");
  545. }).on("mouseout", function() {
  546. that.img.off("mousemove");
  547. });
  548. },
  549. rotate: function(x) {
  550. var that = this;
  551. that.actualRotation += x;
  552. that.img.css({
  553. '-webkit-transform': 'rotate(' + that.actualRotation + 'deg)',
  554. '-moz-transform': 'rotate(' + that.actualRotation + 'deg)',
  555. 'transform': 'rotate(' + that.actualRotation + 'deg)',
  556. });
  557. if(that.options.imgEyecandy) {
  558. that.imgEyecandy.css({
  559. '-webkit-transform': 'rotate(' + that.actualRotation + 'deg)',
  560. '-moz-transform': 'rotate(' + that.actualRotation + 'deg)',
  561. 'transform': 'rotate(' + that.actualRotation + 'deg)',
  562. });
  563. }
  564. // that.actualRotationImgH=0;
  565. // that.actualRotationImgW=0;
  566. // if (that.actualRotation!=0)
  567. // {
  568. // if (that.actualRotation==90||that.actualRotation==270)
  569. // {
  570. // if(that.imgH>that.imgW)
  571. // {
  572. // that.actualRotationImgW=parseInt((that.imgH-that.imgW)/2);
  573. //
  574. // }else if(that.imgH<that.imgW)
  575. // {
  576. // that.actualRotationImgH=parseInt((that.imgW-that.imgH)/2);
  577. // }
  578. // }else if (that.actualRotation!=180&&that.actualRotation!=360) {
  579. // var actualRotation=that.actualRotation;
  580. // if (actualRotation>180)
  581. // {
  582. // actualRotation=actualRotation-180;
  583. // }
  584. // if (actualRotation>90)
  585. // {
  586. // actualRotation=180-actualRotation;
  587. // }
  588. // var radian = Math.tan(actualRotation * Math.PI / 180);
  589. // that.actualRotationImgW=parseInt(radian*(that.imgH/2));
  590. // that.actualRotationImgH=parseInt(radian*(that.imgW/2));
  591. // }
  592. // }
  593. if (typeof that.options.onImgRotate == 'function')
  594. that.options.onImgRotate.call(that);
  595. },
  596. zoom :function(x){
  597. var that = this;
  598. var ratio = that.imgW / that.imgH;
  599. var newWidth = that.imgW+x;
  600. var newHeight = newWidth/ratio;
  601. var doPositioning = true;
  602. if( newWidth < that.objW || newHeight < that.objH){
  603. if( newWidth - that.objW < newHeight - that.objH ){
  604. newWidth = that.objW;
  605. newHeight = newWidth/ratio;
  606. }else{
  607. newHeight = that.objH;
  608. newWidth = ratio * newHeight;
  609. }
  610. doPositioning = false;
  611. }
  612. if(!that.options.scaleToFill && (newWidth > that.imgInitW || newHeight > that.imgInitH)){
  613. if( newWidth - that.imgInitW < newHeight - that.imgInitH ){
  614. newWidth = that.imgInitW;
  615. newHeight = newWidth/ratio;
  616. }else{
  617. newHeight = that.imgInitH;
  618. newWidth = ratio * newHeight;
  619. }
  620. doPositioning = false;
  621. }
  622. that.imgW = newWidth;
  623. that.img.width(newWidth);
  624. that.imgH = newHeight;
  625. that.img.height(newHeight);
  626. var newTop = parseInt( that.img.css('top') ) - x/2;
  627. var newLeft = parseInt( that.img.css('left') ) - x/2;
  628. if( newTop>0 ){ newTop=0;}
  629. if( newLeft>0 ){ newLeft=0;}
  630. var maxTop = -( newHeight-that.objH); if( newTop < maxTop){ newTop = maxTop; }
  631. var maxLeft = -( newWidth-that.objW); if( newLeft < maxLeft){ newLeft = maxLeft; }
  632. if( doPositioning ){
  633. that.img.css({'top':newTop, 'left':newLeft});
  634. }
  635. if(that.options.imgEyecandy){
  636. that.imgEyecandy.width(newWidth);
  637. that.imgEyecandy.height(newHeight);
  638. if( doPositioning ){
  639. that.imgEyecandy.css({'top':newTop, 'left':newLeft});
  640. }
  641. }
  642. if (that.options.onImgZoom) that.options.onImgZoom.call(that);
  643. },
  644. crop:function(){
  645. var that = this;
  646. if (that.options.onBeforeImgCrop) that.options.onBeforeImgCrop.call(that);
  647. that.cropControlsCrop.hide();
  648. that.showLoader();
  649. var cropData = {
  650. imgUrl:that.imgUrl,
  651. imgInitW:that.imgInitW,
  652. imgInitH:that.imgInitH,
  653. imgW:that.imgW,
  654. imgH:that.imgH,
  655. imgY1:Math.abs( parseInt( that.img.css('top') ) ),
  656. imgX1:Math.abs( parseInt( that.img.css('left') ) ),
  657. // imgY1:parseInt( that.img.css('top') ),
  658. // imgX1: parseInt( that.img.css('left')),
  659. cropH:that.objH,
  660. cropW:that.objW,
  661. rotation:that.actualRotation
  662. };
  663. var formData;
  664. if(typeof FormData == 'undefined'){
  665. var XHR = new XMLHttpRequest();
  666. var urlEncodedData = "";
  667. var urlEncodedDataPairs = [];
  668. for(var key in cropData) {
  669. urlEncodedDataPairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(cropData[key]));
  670. }
  671. for(var key in that.options.cropData) {
  672. urlEncodedDataPairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(that.options.cropData[key]));
  673. }
  674. urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
  675. XHR.addEventListener('error', function(event) {
  676. if (that.options.onError) that.options.onError.call(that,"XHR Request failed");
  677. });
  678. XHR.onreadystatechange=function(){
  679. if (XHR.readyState==4 && XHR.status==200)
  680. {
  681. that.afterCrop(XHR.responseText);
  682. }
  683. }
  684. XHR.open('POST', that.options.cropUrl);
  685. XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  686. XHR.setRequestHeader('Content-Length', urlEncodedData.length);
  687. XHR.send(urlEncodedData);
  688. }else{
  689. formData = new FormData();
  690. for (var key in cropData) {
  691. if( cropData.hasOwnProperty(key) ) {
  692. formData.append( key , cropData[key] );
  693. }
  694. }
  695. for (var key in that.options.cropData) {
  696. if( that.options.cropData.hasOwnProperty(key) ) {
  697. formData.append( key , that.options.cropData[key] );
  698. }
  699. }
  700. $.ajax({
  701. url: that.options.cropUrl,
  702. data: formData,
  703. context: document.body,
  704. cache: false,
  705. contentType: false,
  706. processData: false,
  707. type: 'POST'
  708. }).always(function (data) {
  709. that.afterCrop(data);
  710. });
  711. }
  712. //
  713. },
  714. afterCrop: function (data) {
  715. var that = this;
  716. try {
  717. response = jQuery.parseJSON(data);
  718. }
  719. catch(err) {
  720. response = typeof data =='object' ? data : jQuery.parseJSON(data);
  721. }
  722. if (response.status == 'success') {
  723. if (that.options.imgEyecandy)
  724. that.imgEyecandy.hide();
  725. that.destroy();
  726. that.saveImgUrl=response.url;
  727. var croppedImg='<img class="croppedImg" src="' + response.url + '">';
  728. that.obj.append(croppedImg);
  729. if (that.options.outputUrlId !== '') { $('#' + that.options.outputUrlId).val(response.url); }
  730. that.croppedImg = that.obj.find('.croppedImg');
  731. that.croppedImg .width(that.objW+"px").height(that.objH+"px");
  732. that.init();
  733. that.hideLoader();
  734. that.imgUploadControl.hide();
  735. that.cropSaveControl.show();
  736. }
  737. if (response.status == 'error') {
  738. if (that.options.onError) that.options.onError.call(that,response.message);
  739. that.hideLoader();
  740. // setTimeout( function(){ that.reset(); },2000)
  741. }
  742. if (that.options.onAfterImgCrop) that.options.onAfterImgCrop.call(that, response);
  743. },
  744. showLoader:function(){
  745. var that = this;
  746. that.obj.append(that.options.loaderHtml);
  747. that.loader = that.obj.find('.loader');
  748. },
  749. hideLoader:function(){
  750. var that = this;
  751. that.loader.remove();
  752. },
  753. reset:function(){
  754. var that = this;
  755. that.destroy();
  756. that.init();
  757. that.imgUploadControl.show();
  758. if( !$.isEmptyObject(that.croppedImg)){
  759. that.obj.append(that.croppedImg);
  760. if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(that.croppedImg.attr('url')); }
  761. }
  762. if (typeof that.options.onReset == 'function')
  763. that.options.onReset.call(that);
  764. },
  765. destroy:function(){
  766. var that = this;
  767. if(that.options.modal && !$.isEmptyObject(that.modal) ){ that.destroyModal(); }
  768. if(that.options.imgEyecandy && !$.isEmptyObject(that.imgEyecandy) ){ that.destroyEyecandy(); }
  769. if( !$.isEmptyObject( that.cropControlsUpload ) ){ that.cropControlsUpload.remove(); }
  770. if( !$.isEmptyObject( that.cropControlsCrop ) ){ that.cropControlsCrop.remove(); }
  771. if( !$.isEmptyObject( that.loader ) ){ that.loader.remove(); }
  772. if( !$.isEmptyObject( that.form ) ){ that.form.remove(); }
  773. that.obj.html('');
  774. },
  775. isAjaxUploadSupported: function () {
  776. var input = document.createElement("input");
  777. input.type = "file";
  778. return (
  779. "multiple" in input &&
  780. typeof File != "undefined" &&
  781. typeof FormData != "undefined" &&
  782. typeof (new XMLHttpRequest()).upload != "undefined");
  783. },
  784. CreateFallbackIframe: function () {
  785. var that = this;
  786. if (!that.isAjaxUploadSupported()) {
  787. if (jQuery.isEmptyObject(that.iframeobj)) {
  788. var iframe = document.createElement("iframe");
  789. iframe.setAttribute("id", that.id + "_upload_iframe");
  790. iframe.setAttribute("name", that.id + "_upload_iframe");
  791. iframe.setAttribute("width", "0");
  792. iframe.setAttribute("height", "0");
  793. iframe.setAttribute("border", "0");
  794. iframe.setAttribute("src", "javascript:false;");
  795. iframe.style.display = "none";
  796. document.body.appendChild(iframe);
  797. } else {
  798. iframe = that.iframeobj[0];
  799. }
  800. var myContent = '<!DOCTYPE html>'
  801. + '<html><head><title>Uploading File</title></head>'
  802. + '<body>'
  803. + '<form '
  804. + 'class="' + that.id + '_upload_iframe_form" '
  805. + 'name="' + that.id + '_upload_iframe_form" '
  806. + 'action="' + that.options.uploadUrl + '" method="post" '
  807. + 'enctype="multipart/form-data" encoding="multipart/form-data" style="display:none;">'
  808. + $("#" + that.id + '_imgUploadField')[0].outerHTML
  809. + '</form></body></html>';
  810. iframe.contentWindow.document.open('text/htmlreplace');
  811. iframe.contentWindow.document.write(myContent);
  812. iframe.contentWindow.document.close();
  813. that.iframeobj = $("#" + that.id + "_upload_iframe");
  814. that.iframeform = that.iframeobj.contents().find("html").find("." + that.id + "_upload_iframe_form");
  815. that.iframeform.on("change", "input", function () {
  816. that.SubmitFallbackIframe(that);
  817. });
  818. that.iframeform.find("input")[0].attachEvent("onchange", function () {
  819. that.SubmitFallbackIframe(that);
  820. });
  821. var eventHandlermyFile = function () {
  822. if (iframe.detachEvent)
  823. iframe.detachEvent("onload", eventHandlermyFile);
  824. else
  825. iframe.removeEventListener("load", eventHandlermyFile, false);
  826. var response = that.getIframeContentJSON(iframe);
  827. if (jQuery.isEmptyObject(that.modal)) {
  828. that.afterUpload(response);
  829. }
  830. }
  831. if (iframe.addEventListener)
  832. iframe.addEventListener("load", eventHandlermyFile, true);
  833. if (iframe.attachEvent)
  834. iframe.attachEvent("onload", eventHandlermyFile);
  835. return "#" + that.id + '_imgUploadField';
  836. } else {
  837. return "";
  838. }
  839. },
  840. SubmitFallbackIframe: function (that) {
  841. that.showLoader();
  842. if(that.options.processInline && !that.options.uploadUrl){
  843. if (that.options.onError){
  844. that.options.onError.call(that,"processInline is not supported by your browser ");
  845. that.hideLoader();
  846. }
  847. }else{
  848. if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that);
  849. that.iframeform[0].submit();
  850. }
  851. },
  852. getIframeContentJSON: function (iframe) {
  853. try {
  854. var doc = iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document,
  855. response;
  856. var innerHTML = doc.body.innerHTML;
  857. if (innerHTML.slice(0, 5).toLowerCase() == "<pre>" && innerHTML.slice(-6).toLowerCase() == "</pre>") {
  858. innerHTML = doc.body.firstChild.firstChild.nodeValue;
  859. }
  860. response = jQuery.parseJSON(innerHTML);
  861. } catch (err) {
  862. response = { success: false };
  863. }
  864. return response;
  865. }
  866. };
  867. })(window, document);