当前位置:   article > 正文

HTML5Canvas实现简易画图工具(铅笔,直线,矩形,圆,文本框,橡皮擦等)_html 在canvas鼠标绘制矩形框

html 在canvas鼠标绘制矩形框

初学Canvas,用canvas做了简单的画图工具体会并熟悉了一下大致的实现方案。开发完也算是基本了解canvas的用法了。

HTML部分:

  1. <div class="app">
  2. <div class="menu">
  3. <div class="toollist">
  4. <button class="menu-item" style="width: fit-content;" onclick="clearCanvas()">clear</button>
  5. <button class="menu-item" onclick="restoreMouse()">
  6. <svg>//图标
  7. </svg>
  8. </button>
  9. <button class="menu-item" onclick="pencilDraw()">
  10. <svg>//图标
  11. </svg>
  12. </button>
  13. <button class="menu-item" onclick="lineDraw()">
  14. <svg>
  15. </svg>
  16. </button>
  17. <button class="menu-item" onclick="saveCanvas()">
  18. <svg>
  19. </svg>
  20. </button>
  21. <button class="menu-item" onclick="useEraser()">
  22. <svg>
  23. </svg>
  24. </button>
  25. <button class="menu-item" onclick="RectDraw()">
  26. <svg>
  27. </svg></button>
  28. <button class="menu-item" onclick="circleDraw()">
  29. <svg>
  30. </svg>
  31. </button>
  32. <button class="menu-item" onclick="insertText()">A</button>
  33. </div>
  34. <div>
  35. <input type="color" style="margin-top: 10px;" onchange="handleColorChange(this)">
  36. </div>
  37. </div>
  38. <div style="background-color: #fff; position: relative;" class="canvas-area">
  39. <canvas id="canvas" width="1000" height="1000"></canvas>
  40. </div>
  41. <!-- <input type="text" style="border: 1px dashed #ccc; position:absolute;top:0;left:10%;outline:none"> -->
  42. </div>

JS部分:

根据选择的画笔工具分别进行处理,实际上直线,圆,矩形的绘画代码除了使用的方法不同外,唯一的小难点可能就是没办法在画布上重复地绘画,此时需要用到两个方法来实现:

  1. ctx.putImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);
  2. ctx.getImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);

 get方法用来保存当前画布的信息,在onmouseup时,保存此次操作后的画布状态。而put方法则在每次落笔清除绘画轨迹后,将之前保存的数据进行还原,从而实现多次重复绘画的效果。

  1. var canvas = document.getElementById('canvas');
  2. var ctx = canvas.getContext('2d');
  3. var drawdown = false;
  4. var startPointX, startPointY;
  5. var toolcontrol = {
  6. pencil: false,
  7. line: false,
  8. }
  9. var convasData = null;
  10. var drawcolor = "#000";
  11. var curtool;
  12. var textvalue;
  13. function setUsingTool(tool) {
  14. for (const key in toolcontrol) {
  15. toolcontrol[key] = false;
  16. }
  17. toolcontrol[tool] = true;
  18. curtool = tool;
  19. // curtool=='line'?
  20. // ctx=canvas2.getContext('2d'):
  21. // ctx=canvas.getContext('2d');
  22. }
  23. //function clearCanvas() {
  24. // ctx.clearRect(0, 0, 1000, 1000)
  25. //}
  26. function drawToolHandler(tool) {
  27. canvas.addEventListener('mousedown', handleMouseDown);
  28. canvas.addEventListener('mousemove', handleMouseMove);
  29. canvas.addEventListener('mouseup', handleMouseUp);
  30. }
  31. var handleMouseDown = (e) => {
  32. switch (curtool) {
  33. case 'pencil':
  34. drawdown = true;
  35. ctx.beginPath();
  36. ctx.moveTo(e.offsetX, e.offsetY);
  37. break;
  38. case 'line':
  39. case 'rect':
  40. case 'ring':
  41. case 'text':
  42. drawdown = true;
  43. startPointX = e.offsetX;
  44. startPointY = e.offsetY;
  45. break;
  46. case 'eraser':
  47. drawdown = true;
  48. break;
  49. default: return;
  50. }
  51. }
  52. var handleMouseMove = (e) => {
  53. switch (curtool) {
  54. case 'pencil':
  55. if (drawdown) {
  56. ctx.lineTo(e.offsetX, e.offsetY)
  57. ctx.strokeStyle = drawcolor.toString();
  58. ctx.stroke();
  59. }
  60. break;
  61. case 'line':
  62. if (drawdown) {
  63. ctx.beginPath();
  64. ctx.clearRect(0, 0, 1000, 1000);
  65. if (convasData != null) {
  66. ctx.putImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);
  67. }
  68. ctx.moveTo(startPointX, startPointY);
  69. ctx.lineTo(e.offsetX, e.offsetY);
  70. ctx.closePath();
  71. ctx.strokeStyle = drawcolor;
  72. ctx.stroke();
  73. }
  74. break;
  75. case 'rect':
  76. if (drawdown) {
  77. ctx.beginPath();
  78. ctx.clearRect(0, 0, 1000, 1000);
  79. if (convasData != null) {
  80. ctx.putImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);
  81. }
  82. ctx.strokeStyle = drawcolor;
  83. ctx.strokeRect(startPointX, startPointY, e.offsetX - startPointX, e.offsetY - startPointY);
  84. ctx.closePath();
  85. }
  86. break;
  87. case 'ring':
  88. if (drawdown) {
  89. ctx.beginPath();
  90. ctx.clearRect(0, 0, 1000, 1000);
  91. if (convasData != null) {
  92. ctx.putImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);
  93. }
  94. ctx.strokeStyle = drawcolor;
  95. ctx.arc(startPointX, startPointY, (e.offsetY - startPointY) / 2, 0, 2 * Math.PI, false);
  96. ctx.stroke()
  97. ctx.closePath();
  98. }
  99. break;
  100. case 'text':
  101. if (drawdown) {
  102. ctx.beginPath();
  103. ctx.clearRect(0, 0, 1000, 1000);
  104. if (convasData != null) {
  105. ctx.putImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);
  106. }
  107. ctx.strokeStyle = '#000';
  108. ctx.strokeRect(startPointX, startPointY, e.offsetX - startPointX, e.offsetY - startPointY);
  109. ctx.closePath();
  110. }
  111. case 'eraser':
  112. if (drawdown) {
  113. ctx.beginPath();
  114. ctx.moveTo(startPointX, startPointY);
  115. ctx.clearRect(e.offsetX, e.offsetY, 50, 50);
  116. }
  117. break;
  118. default: return;
  119. }
  120. }
  121. var handleMouseUp = (e) => {
  122. if (curtool == 'text'&&e.offsetX - startPointX>=10&&e.offsetY - startPointY>=10) {
  123. // ctx.clearRect(0, 0, 1000, 1000);
  124. let input = document.createElement('input');
  125. let canvasArea = document.getElementsByClassName('canvas-area')[0];
  126. canvasArea.appendChild(input);
  127. input.style.position = "absolute";
  128. input.style.left = `${startPointX}px`;
  129. input.style.top = `${startPointY}px`;
  130. input.style.width = `${e.offsetX - startPointX}px`;
  131. input.style.height = `${e.offsetY - startPointY}px`;
  132. input.style.fontSize =`${parseInt(input.style.height)/2}px`;
  133. input.style.border = "2px dashed #ccc";
  134. input.style.outline = 'none'
  135. input.addEventListener('input',(e)=>{
  136. textvalue=e.target.value
  137. })
  138. input.addEventListener('blur',()=>{
  139. ctx.clearRect(0, 0, 1000, 1000);
  140. if (convasData != null) {
  141. ctx.putImageData(convasData, 0, 0, 0, 0, canvas.offsetWidth, canvas.offsetHeight);
  142. }
  143. ctx.font=`${parseInt(input.style.height)/2}px sans-serif`;
  144. ctx.fillText(textvalue,parseInt(input.style.left)+20,parseInt(input.style.top)+0.6*parseInt(input.style.height));
  145. canvasArea.removeChild(input);
  146. convasData = ctx.getImageData(0, 0, canvas.offsetWidth, canvas.offsetHeight);
  147. })
  148. drawdown = false;
  149. } else {
  150. convasData = ctx.getImageData(0, 0, canvas.offsetWidth, canvas.offsetHeight);
  151. drawdown = false;
  152. }
  153. }
  154. function restoreMouse() {
  155. canvas.removeEventListener('mousedown', handleMouseDown);
  156. canvas.removeEventListener('mousemove', handleMouseMove);
  157. canvas.removeEventListener('mouseup', handleMouseUp);
  158. }
  159. function pencilDraw() {
  160. setUsingTool('pencil');
  161. drawToolHandler('pencil');
  162. }
  163. function lineDraw() {
  164. setUsingTool('line');
  165. drawToolHandler('line');
  166. }
  167. function useEraser() {
  168. setUsingTool('eraser');
  169. drawToolHandler('eraser');
  170. }
  171. function RectDraw() {
  172. setUsingTool('rect');
  173. drawToolHandler('rect');
  174. }
  175. function circleDraw() {
  176. setUsingTool('ring');
  177. drawToolHandler('ring');
  178. }
  179. function insertText() {
  180. setUsingTool('text');
  181. drawToolHandler('text');
  182. }
  183. function handleColorChange(e) {
  184. console.log(e.value);
  185. drawcolor = e.value
  186. }
  187. function saveCanvas() {
  188. var a = document.createElement("a");
  189. a.href = canvas.toDataURL();
  190. var fileName = prompt("命名你的图画");
  191. a.download = fileName || "canvaspic"
  192. a.click();
  193. }

其中插入文本相对特殊一些,需要先在页面根据鼠标移动画出一个矩形,鼠标松开时,创建一个矩形大小的input,输入文字且失去焦点后,将input输入的值画在canvas上。

效果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/107368
推荐阅读
相关标签
  

闽ICP备14008679号