zhiqim_image_clipper.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. * 图片裁切
  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.ImageClipper");
  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. var html = '<div id="ZImageClipper_'+this.id+'" class="z-relative" style="width:620px;height:460px;">'
  45. + ' <div id="ZImageClipper_image_'+this.id+'" class="z-relative z-w400 z-h400 z-bd z-overflow-hidden z-bg-white" style="cursor:move;background-repeat: no-repeat;">'
  46. + ' <div id="ZImageClipper_square_'+this.id+'" class="z-absolute z-w200 z-h200 z-bd" style="top:100px;left:100px;box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);"></div>'
  47. + ' <div id="ZImageClipper_loading_'+this.id+'" class="z-absolute-center-middle z-w60 z-h30 z-hide">加载中...</div>'
  48. + ' </div>'
  49. + ' <div class="z-w400 z-h30 z-mg-t10">'
  50. + ' <button type="button" class="z-button z-cyan z-w120 z-h50 zi-px20" id="ZImageClipper_upload_'+this.id+'">上传图像 </button>'
  51. + ' <button type="button" class="z-button z-cyan z-w50 z-h50 zi-px30" id="ZImageClipper_zoomIn_'+this.id+'">+</button>'
  52. + ' <button type="button" class="z-button z-cyan z-w50 z-h50 zi-px30" id="ZImageClipper_zoomOut_'+this.id+'">-</button>'
  53. + ' <button type="button" class="z-button z-cyan z-w80 z-h50 zi-px20" id="ZImageClipper_clip_'+this.id+'">裁切</button>'
  54. + ' <button type="button" class="z-button z-cyan z-w80 z-h50 zi-px20" id="ZImageClipper_save_'+this.id+'">保存</button>'
  55. + ' </div>'
  56. + ' <div id="ZImageClipper_clipped_'+this.id+'" class="z-absolute z-w200 z-text-center z-pd-t20 z-bd" style="top:0;right:0;height:460px;"></button>'
  57. + '</div>';
  58. this.$elem.html(html);
  59. this.$imageBox = this.$elem.find("#ZImageClipper_image_"+this.id);
  60. this.$square = this.$elem.find("#ZImageClipper_square_"+this.id);
  61. this.$loading = this.$elem.find("#ZImageClipper_loading_"+this.id).show();
  62. this.image = new Image();
  63. Z(this.image).load(function()
  64. {
  65. this.$loading.hide();
  66. this.setBackground();
  67. this.$imageBox.mousedown(this.onMouseDown, this).mousemove(this.onMouseMove, this);
  68. Z(window).mouseup(this.onMouseUp, this);
  69. }, this);
  70. this.image.src = this.img;
  71. Z("#ZImageClipper_zoomIn_"+this.id).click(this.onZoomIn, this);
  72. Z("#ZImageClipper_zoomOut_"+this.id).click(this.onZoomOut, this);
  73. this.$file = Z("<input id='ZImageClipper_upload_file_"+this.id+"' type='file' accept='image/jpg,image/jpeg,image/png' class='z-hide' single>");
  74. this.$file.appendTo("body").change(function()
  75. {
  76. var file = this.$file[0].files[0];
  77. var reader = new FileReader();
  78. reader.onload = Z.bind(function(e)
  79. {
  80. this.img = e.target.result;
  81. this.image.src = this.img;
  82. }, this);
  83. reader.readAsDataURL(file);
  84. }, this);
  85. Z("#ZImageClipper_upload_"+this.id).click(function(){this.$file[0].click();}, this);
  86. Z("#ZImageClipper_clip_"+this.id).click(function()
  87. {
  88. var imgData = this.getDataURL();
  89. var imgDiv = '';
  90. Z.each(this.clipWidth, function(elem){
  91. imgDiv += '<div class="z-w200 z-mg-b20"><img src="'+imgData+'" class="z-bd-rd50p" style="width:'+elem+'px;"><br>'+elem+' * '+elem+'</div>'
  92. });
  93. Z("#ZImageClipper_clipped_"+this.id).html(imgDiv);
  94. }, this);
  95. if (Z.T.isFunction(this.save)){
  96. Z("#ZImageClipper_save_"+this.id).click(this.save, this);
  97. }
  98. },
  99. setBackground: function()
  100. {
  101. var w = parseInt(this.image.width) * this.ratio;
  102. var h = parseInt(this.image.height) * this.ratio;
  103. var pw = (400 - w) / 2;
  104. var ph = (400 - h) / 2;
  105. this.$imageBox.css({
  106. "background-image": "url(" + this.image.src + ")",
  107. "background-size": w +"px " + h + "px",
  108. "background-position": pw + "px " + ph + "px",
  109. "background-repeat": "no-repeat"});
  110. },
  111. onMouseDown: function(e)
  112. {
  113. Z.E.stop(e);
  114. this.state.dragging = true;
  115. this.state.mouseX = e.clientX;
  116. this.state.mouseY = e.clientY;
  117. },
  118. onMouseMove: function(e)
  119. {
  120. Z.E.stop(e);
  121. if (!this.state.dragging)
  122. return;
  123. var x = e.clientX - this.state.mouseX;
  124. var y = e.clientY - this.state.mouseY;
  125. var bg = this.$imageBox.css('background-position').split(' ');
  126. var bgX = x + parseInt(bg[0]);
  127. var bgY = y + parseInt(bg[1]);
  128. this.$imageBox.css('background-position', bgX +'px ' + bgY + 'px');
  129. this.state.mouseX = e.clientX;
  130. this.state.mouseY = e.clientY;
  131. },
  132. onMouseUp: function(e)
  133. {
  134. Z.E.stop(e);
  135. this.state.dragging = false;
  136. },
  137. onZoomIn: function()
  138. {
  139. this.ratio *= 1.1;
  140. this.setBackground();
  141. },
  142. onZoomOut: function()
  143. {
  144. this.ratio *= 0.9;
  145. this.setBackground();
  146. },
  147. getDataURL: function()
  148. {
  149. var width = this.$square.offsetWidth(),
  150. height = this.$square.offsetHeight(),
  151. canvas = document.createElement("canvas"),
  152. dim = this.$imageBox.css('background-position').split(' '),
  153. size = this.$imageBox.css('background-size').split(' '),
  154. dx = parseInt(dim[0]) - this.$imageBox.offsetWidth()/2 + width/2,
  155. dy = parseInt(dim[1]) - this.$imageBox.offsetHeight()/2 + height/2,
  156. dw = parseInt(size[0]),
  157. dh = parseInt(size[1]),
  158. sh = parseInt(this.image.height),
  159. sw = parseInt(this.image.width);
  160. canvas.width = width;
  161. canvas.height = height;
  162. var context = canvas.getContext("2d");
  163. context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
  164. var imageData = canvas.toDataURL('image/png');
  165. return imageData;
  166. },
  167. getBlob: function()
  168. {
  169. var imageData = this.getDataURL();
  170. var b64 = imageData.replace('data:image/png;base64,','');
  171. var binary = atob(b64);
  172. var array = [];
  173. for (var i = 0; i < binary.length; i++) {
  174. array.push(binary.charCodeAt(i));
  175. }
  176. return new Blob([new Uint8Array(array)], {type: 'image/png'});
  177. }
  178. }
  179. //END
  180. })(zhiqim);