scrawl.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /**
  2. * Created by yangjian on 17-9-18.
  3. */
  4. (function($) {
  5. // 设置元素可用状态
  6. $.fn.enable = function() {
  7. $(this).addClass("active");
  8. $(this).removeAttr("disabled");
  9. }
  10. // 设置元素不可用状态
  11. $.fn.disable = function() {
  12. $(this).removeClass("active");
  13. $(this).attr("disabled", true);
  14. }
  15. var Canvas = function(options) {
  16. var configs = {
  17. width : 360,
  18. height : 300
  19. }; //默认配置
  20. options = options || {};
  21. $.extend(configs, options);
  22. var canvas = $("#"+configs.canvasId)[0]; //画布
  23. canvas.width = configs.width;
  24. canvas.height = configs.height;
  25. var context = canvas.getContext("2d"); //绘图环境
  26. context.lineCap = "round"; //设置线条两端为圆弧
  27. context.lineJoin = "round"; //设置线条转折为圆弧
  28. //设置默认颜色
  29. setColor();
  30. var $prevBtn = $("#J_prevStep"); //上一步
  31. var $nextBtn = $("#J_nextStep"); //下一步
  32. var $clearBtn = $("#J_clearBoard"); //清空画板
  33. var drawing = false; //是否正在绘制
  34. var erasering = false; //是否正在擦除
  35. var prevSteps = []; //返回上一步操作集合
  36. var nextSteps = []; //恢复下一步操作集合
  37. var o = {};
  38. $("#picBoard").css({
  39. width : configs.width + "px",
  40. height : configs.height + "px"
  41. });
  42. // 事件绑定
  43. canvas.onmousedown = startDrawing;
  44. canvas.onmouseup = stopDrawing;
  45. canvas.onmouseout = stopDrawing;
  46. canvas.onmousemove = doDrawing;
  47. $prevBtn.on("click", gotoPrevStep);
  48. $nextBtn.on("click", gotoNextStep);
  49. $clearBtn.on("click", clearBoard);
  50. // 清空设置
  51. $("#clearSetting").on("click", function() {
  52. context.lineWidth = 1;
  53. setColor($(".colorBar span:first").data("color"));
  54. context.shadowBlur = 0;
  55. alert("画笔已重新初始化,请重新配置画笔。");
  56. });
  57. //上传背景图片
  58. $("#J_canvas_bg").on("change", function() {
  59. if ($("#picBoard img").length > 0) {
  60. $("#picBoard img:eq(0)").attr("src", window.URL.createObjectURL(this.files[0]));
  61. return;
  62. }
  63. var $img = '<img src="'+window.URL.createObjectURL(this.files[0])+'" width="'+configs.width+'" height="'+configs.height+'" />';
  64. $("#picBoard").append($img);
  65. // 激活删除背景按钮
  66. $("#J_removeImg").enable();
  67. });
  68. // 删除背景图片
  69. $("#J_removeImg").on("click", function() {
  70. $("#picBoard").empty();
  71. $(this).disable();
  72. });
  73. //保存图片
  74. $('#J_saveImg').on("click", saveImage);
  75. // 设置笔刷大小
  76. $("#scrawl-main .brush-size").on("click", function() {
  77. context.restore(); //恢复到canvas的上一个状态
  78. context.lineWidth = parseInt($(this).text());
  79. erasering = false;
  80. });
  81. // 设置笔触虚化
  82. $("#scrawl-main .blur-size").on("click", function() {
  83. context.shadowBlur = parseInt($(this).text());
  84. });
  85. // 橡皮擦功能
  86. $("#scrawl-main .eraser-size").on("click", function() {
  87. if (erasering == true) {
  88. return;
  89. }
  90. erasering = true;
  91. context.save(); //保存canvas状态
  92. context.lineCap = "round"; //设置线条两端为圆弧
  93. context.lineJoin = "round"; //设置线条转折为圆弧
  94. context.lineWidth = 10;
  95. context.globalCompositeOperation = "destination-out";
  96. });
  97. //设置颜色
  98. $("#scrawl-main .colorBar span").on("click",function() {
  99. $("#scrawl-main .colorBar .active").removeClass("active");
  100. $(this).addClass("active");
  101. setColor($(this).data("color"));
  102. });
  103. // 开始绘制
  104. function startDrawing(e) {
  105. drawing = true;
  106. //记录上一步的数据
  107. prevSteps.push(context.getImageData(0, 0, configs.width, configs.height));
  108. // 创建一个新的绘图路径
  109. context.beginPath();
  110. // 把画笔移动到鼠标位置
  111. var offset = $(canvas).offset();
  112. context.moveTo(e.pageX - offset.left, e.pageY - offset.top);
  113. }
  114. // 停止绘制
  115. function stopDrawing() {
  116. drawing = false;
  117. //清空下一步的数据集合,从新开始记录
  118. nextSteps = [];
  119. $nextBtn.disable();
  120. if (prevSteps.length == 1) {
  121. $prevBtn.enable();
  122. $clearBtn.enable();
  123. }
  124. }
  125. //绘制图像
  126. function doDrawing(e) {
  127. if (drawing) {
  128. // 找到鼠标最新位置
  129. var offset = $(canvas).offset();
  130. var x = e.pageX - offset.left;
  131. var y = e.pageY - offset.top;
  132. // 画一条直线到鼠标最新位置
  133. context.lineTo(x, y);
  134. context.stroke();
  135. }
  136. }
  137. /**
  138. * 返回上一步操作
  139. */
  140. function gotoPrevStep() {
  141. if (prevSteps.length > 0) {
  142. //保存当前状态到下一步的操作历史库
  143. nextSteps.push(context.getImageData(0, 0, configs.width, configs.height));
  144. var popData = prevSteps.pop();
  145. context.putImageData(popData, 0, 0);
  146. $nextBtn.enable();
  147. if (prevSteps.length == 0) {
  148. $prevBtn.disable();
  149. }
  150. }
  151. }
  152. /**
  153. * 恢复下一步操作
  154. */
  155. function gotoNextStep() {
  156. if (nextSteps.length > 0) {
  157. //保存当前状态到上一步的操作历史库
  158. prevSteps.push(context.getImageData(0, 0, configs.width, configs.height));
  159. var imgData = nextSteps.pop();
  160. context.putImageData(imgData, 0, 0);
  161. $prevBtn.enable();
  162. if (nextSteps.length == 0) {
  163. $nextBtn.disable();
  164. }
  165. }
  166. }
  167. /**
  168. * 清空画板
  169. */
  170. function clearBoard() {
  171. context.clearRect(0, 0, context.canvas.width, context.canvas.height);
  172. prevSteps = [];
  173. nextSteps = [];
  174. $prevBtn.disable();
  175. $nextBtn.disable();
  176. $clearBtn.disable();
  177. }
  178. /**
  179. * 设置画笔颜色
  180. * @param color
  181. */
  182. function setColor(color) {
  183. if (!color) {
  184. color = $(".colorBar .active:eq(0)").data("color");
  185. }
  186. context.strokeStyle = color;
  187. context.shadowColor = color;
  188. }
  189. /**
  190. * 获取图片 base64 编码
  191. */
  192. function saveImage(callback) {
  193. if ($("#picBoard img").length > 0) {
  194. var image = new Image();
  195. image.src = $("#picBoard img:eq(0)").attr("src");
  196. image.onload = function() {
  197. context.save();
  198. context.shadowBlur = 0;
  199. context.shadowColor = '#FFF';
  200. context.globalCompositeOperation = "destination-atop";
  201. context.drawImage(this, 0, 0, configs.width, configs.height);
  202. context.restore();
  203. callback(canvas.toDataURL("image/png"));
  204. }
  205. } else {
  206. callback(canvas.toDataURL("image/png"));
  207. }
  208. }
  209. //要导出的API
  210. o.nextStep = gotoNextStep;
  211. o.prevStep = gotoNextStep;
  212. o.setColor = setColor;
  213. o.save = saveImage;
  214. o.isEmpty = function() {
  215. return prevSteps.length == 0;
  216. }
  217. return o;
  218. }
  219. window.Canvas = Canvas;
  220. })(jQuery);