zhiqim_image_clipper.mobile.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
  3. *
  4. * 指定登记&发行网站: https://www.zhiqim.com/ 欢迎加盟知启蒙,[编程有你,知启蒙一路随行]。
  5. *
  6. * 本文采用《知启蒙许可证》,除非符合许可证,否则不可使该文件!
  7. * 1、您可以免费使用、修改、合并、出版发行和分发,再授权软件、软件副本及衍生软件;
  8. * 2、您用于商业用途时,必须在原作者指定的登记网站进行实名登记;
  9. * 3、您在使用、修改、合并、出版发行和分发时,必须包含版权声明、许可声明,及保留原作者的著作权、商标和专利等知识产权;
  10. * 4、您在互联网、移动互联网等大众网络下发行和分发再授权软件、软件副本及衍生软件时,必须在原作者指定的发行网站进行发行和分发;
  11. * 5、您可以在以下链接获取一个完整的许可证副本。
  12. *
  13. * 许可证链接:http://zhiqim.org/licenses/LICENSE.htm
  14. *
  15. * 除非法律需要或书面同意,软件由原始码方式提供,无任何明示或暗示的保证和条件。详见完整许可证的权限和限制。
  16. */
  17. +(function(Z)
  18. {
  19. //BEGIN
  20. /**
  21. * mobile 端图片裁切
  22. */
  23. Z.ImageClipper = Z.Class.newInstance();
  24. Z.ImageClipper.prototype =
  25. {
  26. defaults:
  27. {
  28. elem : null,
  29. ratio: 1,
  30. state : {},
  31. img: null,
  32. clipWidth: [50, 100, 150],
  33. save: null
  34. },
  35. execute: function()
  36. {
  37. this.$elem = Z.$elem(this.elem, "Z.Floater");
  38. if (this.clipWidth == null || this.clipWidth.length == 0)
  39. {
  40. Z.alert("[Z.ImageClipper]没有设置clipWidth,或不是数组");
  41. return;
  42. }
  43. this.id = Z.random(10);
  44. //判断是不是手机端
  45. this.width = this.$elem.offsetWidth();
  46. var html = '<div id="ZImageClipper_'+this.id+'" class="z-relative z-w100p">'
  47. + ' <div id="ZImageClipper_image_'+this.id+'" class="z-relative z-w100p z-bd z-overflow-hidden z-bg-white" style="cursor:move;background-repeat:no-repeat;height:'+this.width+'px;">'
  48. + ' <div id="ZImageClipper_square_'+this.id+'" class="z-absolute z-w50p z-h50p z-bd" style="top:25%;left:25%;box-shadow:0 0 0 1000px rgba(0, 0, 0, 0.5);"></div>'
  49. + ' <div id="ZImageClipper_loading_'+this.id+'" class="z-absolute-center-middle z-w60 z-h30 z-hide">加载中...</div>'
  50. + ' <div id="ZImageClipper_clipped_'+this.id+'" class="z-absolute z-w100p z-l0 z-t0 z-text-center z-pd-t20 z-bd z-hide" style="height:'+this.width+'px;"></div>'
  51. + ' </div>'
  52. + ' <div class="z-button-row z-w100p z-mg-t10">'
  53. + ' <button type="button" class="z-button-flex z-h50 zi-rem14" id="ZImageClipper_upload_'+this.id+'">上传图像 </button>'
  54. + ' <button type="button" class="z-button-flex z-h50 zi-rem16" id="ZImageClipper_zoomIn_'+this.id+'">+</button>'
  55. + ' <button type="button" class="z-button-flex z-h50 zi-rem16" id="ZImageClipper_zoomOut_'+this.id+'">-</button>'
  56. + ' <button type="button" class="z-button-flex z-h50 zi-rem14" id="ZImageClipper_save_'+this.id+'">确定</button>'
  57. + ' </div>'
  58. + '</div>';
  59. this.$elem.html(html);
  60. this.$imageBox = this.$elem.find("#ZImageClipper_image_"+this.id);
  61. this.$square = this.$elem.find("#ZImageClipper_square_"+this.id);
  62. this.$loading = this.$elem.find("#ZImageClipper_loading_"+this.id).show();
  63. this.$$button = this.$elem.find("button");
  64. this.image = new Image();
  65. Z(this.image).load(function()
  66. {
  67. this.$loading.hide();
  68. this.setBackground();
  69. this.$imageBox.on("touchstart", this.onTouchStart, this)
  70. .on("touchmove", this.onTouchMove, this)
  71. .on("mouseup mouseleave", this.onTouchEnd, this);
  72. }, this);
  73. this.image.src = this.img;
  74. Z("#ZImageClipper_zoomIn_"+this.id).on("touchstart", this.onZoomIn, this);
  75. Z("#ZImageClipper_zoomOut_"+this.id).on("touchstart", this.onZoomOut, this);
  76. this.$file = Z("<input id='ZImageClipper_upload_file_"+this.id+"' type='file' accept='image/jpg,image/jpeg,image/png' class='z-hide' single>");
  77. this.$file.appendTo("body").change(function()
  78. {
  79. var file = this.$file[0].files[0];
  80. var reader = new FileReader();
  81. reader.onload = Z.bind(function(e)
  82. {
  83. this.img = e.target.result;
  84. this.image.src = this.img;
  85. }, this);
  86. reader.readAsDataURL(file);
  87. }, this);
  88. Z("#ZImageClipper_upload_"+this.id).on("touchstart",function(){this.$file[0].click();}, this);
  89. if (Z.T.isFunction(this.save)){
  90. Z("#ZImageClipper_save_"+this.id).on("touchstart", this.save, this);
  91. }
  92. },
  93. setBackground: function()
  94. {
  95. var w = parseInt(this.image.width) * this.ratio;
  96. var h = parseInt(this.image.height) * this.ratio;
  97. var pw = (400 - w) / 2;
  98. var ph = (400 - h) / 2;
  99. this.$imageBox.css({
  100. "background-image": "url(" + this.image.src + ")",
  101. "background-size": w +"px " + h + "px",
  102. "background-position": pw + "px " + ph + "px",
  103. "background-repeat": "no-repeat"});
  104. },
  105. onTouchStart: function(e)
  106. {
  107. Z.E.forbidden(e);
  108. this.state.dragging = true;
  109. var theTouch = e.touches[0];
  110. this.state.mouseX = theTouch.clientX;
  111. this.state.mouseY = theTouch.clientY;
  112. },
  113. onTouchMove: function(e)
  114. {
  115. Z.E.forbidden(e);
  116. if (!this.state.dragging)
  117. return;
  118. var theTouch = e.touches[0];
  119. var x = theTouch.clientX - this.state.mouseX;
  120. var y = theTouch.clientY - this.state.mouseY;
  121. var bg = this.$imageBox.css('background-position').split(' ');
  122. var bgX = x + parseInt(bg[0]);
  123. var bgY = y + parseInt(bg[1]);
  124. this.$imageBox.css('background-position', bgX +'px ' + bgY + 'px');
  125. this.state.mouseX = theTouch.clientX;
  126. this.state.mouseY = theTouch.clientY;
  127. },
  128. onTouchEnd: function(e)
  129. {
  130. Z.E.forbidden(e);
  131. this.state.dragging = false;
  132. },
  133. onZoomIn: function()
  134. {
  135. this.ratio *= 1.1;
  136. this.setBackground();
  137. },
  138. onZoomOut: function()
  139. {
  140. this.ratio *= 0.9;
  141. this.setBackground();
  142. },
  143. getDataURL: function()
  144. {
  145. var width = this.$square.offsetWidth(),
  146. height = this.$square.offsetHeight(),
  147. canvas = document.createElement("canvas"),
  148. dim = this.$imageBox.css('background-position').split(' '),
  149. size = this.$imageBox.css('background-size').split(' '),
  150. dx = parseInt(dim[0]) - this.$imageBox.offsetWidth()/2 + width/2,
  151. dy = parseInt(dim[1]) - this.$imageBox.offsetHeight()/2 + height/2,
  152. dw = parseInt(size[0]),
  153. dh = parseInt(size[1]),
  154. sh = parseInt(this.image.height),
  155. sw = parseInt(this.image.width);
  156. canvas.width = width;
  157. canvas.height = height;
  158. var context = canvas.getContext("2d");
  159. context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
  160. var imageData = canvas.toDataURL('image/png');
  161. return imageData;
  162. },
  163. getBlob: function()
  164. {
  165. var imageData = this.getDataURL();
  166. var b64 = imageData.replace('data:image/png;base64,','');
  167. var binary = atob(b64);
  168. var array = [];
  169. for (var i = 0; i < binary.length; i++) {
  170. array.push(binary.charCodeAt(i));
  171. }
  172. return new Blob([new Uint8Array(array)], {type: 'image/png'});
  173. }
  174. }
  175. //END
  176. })(zhiqim);