在今天的HTML教程里,我们要学习一下如何使用HTML5 Canvas实现一个超酷而又简单的网络画板功能。在这个教程中,我们可以选择笔刷的类型、笔刷的大小以及笔刷的颜色,当然作为画板还需要很多功能,这里只是最基本的绘制功能,大家可以自己实现类似矩形、椭圆等复杂元素的绘制。

demo演示

下面我们来简单地分析一下实现这个HTML5网页画板的原理及代码,代码由HTML以及Javascript组成,主要还是Javascript代码。

HTML代码:

  1. <div style="width:530px;margin:10px auto">
  2. <div id="canvasDiv"></div>
  3. </div>

复制代码

HTML代码非常简单,仅仅是构造了一个canvas容器,我们的画板就在这个地方生成。

Javascript代码:

首先我们通过一组变量来定义画板的样式,以及一些数据的初始化:

  1. var canvas;
  2. var context;
  3. var canvasWidth = 490;
  4. var canvasHeight = 220;
  5. var padding = 25;
  6. var lineWidth = 8;
  7. var colorPurple = "#cb3594";
  8. var colorGreen = "#659b41";
  9. var colorYellow = "#ffcf33";
  10. var colorBrown = "#986928";
  11. var outlineImage = new Image();
  12. var crayonImage = new Image();
  13. var markerImage = new Image();
  14. var eraserImage = new Image();
  15. var crayonBackgroundImage = new Image();
  16. var markerBackgroundImage = new Image();
  17. var eraserBackgroundImage = new Image();
  18. var crayonTextureImage = new Image();
  19. var clickX = new Array();
  20. var clickY = new Array();
  21. var clickColor = new Array();
  22. var clickTool = new Array();
  23. var clickSize = new Array();
  24. var clickDrag = new Array();
  25. var paint = false;
  26. var curColor = colorPurple;
  27. var curTool = "crayon";
  28. var curSize = "normal";
  29. var mediumStartX = 18;
  30. var mediumStartY = 19;
  31. var mediumImageWidth = 93;
  32. var mediumImageHeight = 46;
  33. var drawingAreaX = 111;
  34. var drawingAreaY = 11;
  35. var drawingAreaWidth = 267;
  36. var drawingAreaHeight = 200;
  37. var toolHotspotStartY = 23;
  38. var toolHotspotHeight = 38;
  39. var sizeHotspotStartY = 157;
  40. var sizeHotspotHeight = 36;
  41. var sizeHotspotWidthObject = new Object();
  42. sizeHotspotWidthObject.huge = 39;
  43. sizeHotspotWidthObject.large = 25;
  44. sizeHotspotWidthObject.normal = 18;
  45. sizeHotspotWidthObject.small = 16;
  46. var totalLoadResources = 8;
  47. var curLoadResNum = 0;

复制代码

接下来开始准备画布,也就是初始化Canvas对象:

  1. function prepareCanvas()
  2. {
  3. // Create the canvas (Neccessary for IE because it doesn't know what a canvas element is)
  4. var canvasDiv = document.getElementById('canvasDiv');
  5. canvas = document.createElement('canvas');
  6. canvas.setAttribute('width', canvasWidth);
  7. canvas.setAttribute('height', canvasHeight);
  8. canvas.setAttribute('id', 'canvas');
  9. canvasDiv.appendChild(canvas);
  10. if(typeof G_vmlCanvasManager != 'undefined') {
  11. canvas = G_vmlCanvasManager.initElement(canvas);
  12. }
  13. context = canvas.getContext("2d"); // Grab the 2d canvas context
  14. // Note: The above code is a workaround for IE 8 and lower. Otherwise we could have used:
  15. //     context = document.getElementById('canvas').getContext("2d");
  16. // Load images
  17. // -----------
  18. crayonImage.onload = function() { resourceLoaded();
  19. };
  20. crayonImage.src = "images/crayon-outline.png";
  21. //context.drawImage(crayonImage, 0, 0, 100, 100);
  22. markerImage.onload = function() { resourceLoaded();
  23. };
  24. markerImage.src = "images/marker-outline.png";
  25. eraserImage.onload = function() { resourceLoaded();
  26. };
  27. eraserImage.src = "images/eraser-outline.png";
  28. crayonBackgroundImage.onload = function() { resourceLoaded();
  29. };
  30. crayonBackgroundImage.src = "images/crayon-background.png";
  31. markerBackgroundImage.onload = function() { resourceLoaded();
  32. };
  33. markerBackgroundImage.src = "images/marker-background.png";
  34. eraserBackgroundImage.onload = function() { resourceLoaded();
  35. };
  36. eraserBackgroundImage.src = "images/eraser-background.png";
  37. crayonTextureImage.onload = function() { resourceLoaded();
  38. };
  39. crayonTextureImage.src = "images/crayon-texture.png";
  40. outlineImage.onload = function() { resourceLoaded();
  41. };
  42. outlineImage.src = "images/watermelon-duck-outline.png";
  43. // Add mouse events
  44. // ----------------
  45. $('#canvas').mousedown(function(e)
  46. {
  47. // Mouse down location
  48. var mou** = e.pageX - this.offsetLeft;
  49. var mouseY = e.pageY - this.offsetTop;
  50. if(mou** < drawingAreaX) // Left of the drawing area
  51. {
  52. if(mou** > mediumStartX)
  53. {
  54. if(mouseY > mediumStartY && mouseY < mediumStartY + mediumImageHeight){
  55. curColor = colorPurple;
  56. }else if(mouseY > mediumStartY + mediumImageHeight && mouseY < mediumStartY + mediumImageHeight * 2){
  57. curColor = colorGreen;
  58. }else if(mouseY > mediumStartY + mediumImageHeight * 2 && mouseY < mediumStartY + mediumImageHeight * 3){
  59. curColor = colorYellow;
  60. }else if(mouseY > mediumStartY + mediumImageHeight * 3 && mouseY < mediumStartY + mediumImageHeight * 4){
  61. curColor = colorBrown;
  62. }
  63. }
  64. }
  65. else if(mou** > drawingAreaX + drawingAreaWidth) // Right of the drawing area
  66. {
  67. if(mouseY > toolHotspotStartY)
  68. {
  69. if(mouseY > sizeHotspotStartY)
  70. {
  71. var sizeHotspotStartX = drawingAreaX + drawingAreaWidth;
  72. if(mouseY < sizeHotspotStartY + sizeHotspotHeight && mou** > sizeHotspotStartX)
  73. {
  74. if(mou** < sizeHotspotStartX + sizeHotspotWidthObject.huge){
  75. curSize = "huge";
  76. }else if(mou** < sizeHotspotStartX + sizeHotspotWidthObject.large + sizeHotspotWidthObject.huge){
  77. curSize = "large";
  78. }else if(mou** < sizeHotspotStartX + sizeHotspotWidthObject.normal + sizeHotspotWidthObject.large + sizeHotspotWidthObject.huge){
  79. curSize = "normal";
  80. }else if(mou** < sizeHotspotStartX + sizeHotspotWidthObject.small + sizeHotspotWidthObject.normal + sizeHotspotWidthObject.large + sizeHotspotWidthObject.huge){
  81. curSize = "small";
  82. }
  83. }
  84. }
  85. else
  86. {
  87. if(mouseY < toolHotspotStartY + toolHotspotHeight){
  88. curTool = "crayon";
  89. }else if(mouseY < toolHotspotStartY + toolHotspotHeight * 2){
  90. curTool = "marker";
  91. }else if(mouseY < toolHotspotStartY + toolHotspotHeight * 3){
  92. curTool = "eraser";
  93. }
  94. }
  95. }
  96. }
  97. else if(mouseY > drawingAreaY && mouseY < drawingAreaY + drawingAreaHeight)
  98. {
  99. // Mouse click location on drawing area
  100. }
  101. paint = true;
  102. addClick(mou**, mouseY, false);
  103. redraw();
  104. });
  105. $('#canvas').mousemove(function(e){
  106. if(paint==true){
  107. addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
  108. redraw();
  109. }
  110. });
  111. $('#canvas').mouseup(function(e){
  112. paint = false;
  113. redraw();
  114. });
  115. $('#canvas').mouseleave(function(e){
  116. paint = false;
  117. });
  118. }

复制代码

看起来很复杂,前面主要是初始化canvas的背景图片,后面主要是初始化画笔事件,像click、mouseup、mouseleave等鼠标事件。

下面是draw的主要方法:

  1. function redraw()
  2. {
  3. // Make sure required resources are loaded before redrawing
  4. if(curLoadResNum < totalLoadResources){ return; }
  5. clearCanvas();
  6. var locX;
  7. var locY;
  8. if(curTool == "crayon")
  9. {
  10. // Draw the crayon tool background
  11. context.drawImage(crayonBackgroundImage, 0, 0, canvasWidth, canvasHeight);
  12. // Purple
  13. locX = (curColor == colorPurple) ? 18 : 52;
  14. locY = 19;
  15. context.beginPath();
  16. context.moveTo(locX + 41, locY + 11);
  17. context.lineTo(locX + 41, locY + 35);
  18. context.lineTo(locX + 29, locY + 35);
  19. context.lineTo(locX + 29, locY + 33);
  20. context.lineTo(locX + 11, locY + 27);
  21. context.lineTo(locX + 11, locY + 19);
  22. context.lineTo(locX + 29, locY + 13);
  23. context.lineTo(locX + 29, locY + 11);
  24. context.lineTo(locX + 41, locY + 11);
  25. context.closePath();
  26. context.fillStyle = colorPurple;
  27. context.fill();
  28. if(curColor == colorPurple){
  29. context.drawImage(crayonImage, locX, locY, mediumImageWidth, mediumImageHeight);
  30. }else{
  31. context.drawImage(crayonImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  32. }
  33. // Green
  34. locX = (curColor == colorGreen) ? 18 : 52;
  35. locY += 46;
  36. context.beginPath();
  37. context.moveTo(locX + 41, locY + 11);
  38. context.lineTo(locX + 41, locY + 35);
  39. context.lineTo(locX + 29, locY + 35);
  40. context.lineTo(locX + 29, locY + 33);
  41. context.lineTo(locX + 11, locY + 27);
  42. context.lineTo(locX + 11, locY + 19);
  43. context.lineTo(locX + 29, locY + 13);
  44. context.lineTo(locX + 29, locY + 11);
  45. context.lineTo(locX + 41, locY + 11);
  46. context.closePath();
  47. context.fillStyle = colorGreen;
  48. context.fill();
  49. if(curColor == colorGreen){
  50. context.drawImage(crayonImage, locX, locY, mediumImageWidth, mediumImageHeight);
  51. }else{
  52. context.drawImage(crayonImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  53. }
  54. // Yellow
  55. locX = (curColor == colorYellow) ? 18 : 52;
  56. locY += 46;
  57. context.beginPath();
  58. context.moveTo(locX + 41, locY + 11);
  59. context.lineTo(locX + 41, locY + 35);
  60. context.lineTo(locX + 29, locY + 35);
  61. context.lineTo(locX + 29, locY + 33);
  62. context.lineTo(locX + 11, locY + 27);
  63. context.lineTo(locX + 11, locY + 19);
  64. context.lineTo(locX + 29, locY + 13);
  65. context.lineTo(locX + 29, locY + 11);
  66. context.lineTo(locX + 41, locY + 11);
  67. context.closePath();
  68. context.fillStyle = colorYellow;
  69. context.fill();
  70. if(curColor == colorYellow){
  71. context.drawImage(crayonImage, locX, locY, mediumImageWidth, mediumImageHeight);
  72. }else{
  73. context.drawImage(crayonImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  74. }
  75. // Yellow
  76. locX = (curColor == colorBrown) ? 18 : 52;
  77. locY += 46;
  78. context.beginPath();
  79. context.moveTo(locX + 41, locY + 11);
  80. context.lineTo(locX + 41, locY + 35);
  81. context.lineTo(locX + 29, locY + 35);
  82. context.lineTo(locX + 29, locY + 33);
  83. context.lineTo(locX + 11, locY + 27);
  84. context.lineTo(locX + 11, locY + 19);
  85. context.lineTo(locX + 29, locY + 13);
  86. context.lineTo(locX + 29, locY + 11);
  87. context.lineTo(locX + 41, locY + 11);
  88. context.closePath();
  89. context.fillStyle = colorBrown;
  90. context.fill();
  91. if(curColor == colorBrown){
  92. context.drawImage(crayonImage, locX, locY, mediumImageWidth, mediumImageHeight);
  93. }else{
  94. context.drawImage(crayonImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  95. }
  96. }
  97. else if(curTool == "marker")
  98. {
  99. // Draw the marker tool background
  100. context.drawImage(markerBackgroundImage, 0, 0, canvasWidth, canvasHeight);
  101. // Purple
  102. locX = (curColor == colorPurple) ? 18 : 52;
  103. locY = 19;
  104. context.beginPath();
  105. context.moveTo(locX + 10, locY + 24);
  106. context.lineTo(locX + 10, locY + 24);
  107. context.lineTo(locX + 22, locY + 16);
  108. context.lineTo(locX + 22, locY + 31);
  109. context.closePath();
  110. context.fillStyle = colorPurple;
  111. context.fill();
  112. if(curColor == colorPurple){
  113. context.drawImage(markerImage, locX, locY, mediumImageWidth, mediumImageHeight);
  114. }else{
  115. context.drawImage(markerImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  116. }
  117. // Green
  118. locX = (curColor == colorGreen) ? 18 : 52;
  119. locY += 46;
  120. context.beginPath();
  121. context.moveTo(locX + 10, locY + 24);
  122. context.lineTo(locX + 10, locY + 24);
  123. context.lineTo(locX + 22, locY + 16);
  124. context.lineTo(locX + 22, locY + 31);
  125. context.closePath();
  126. context.fillStyle = colorGreen;
  127. context.fill();
  128. if(curColor == colorGreen){
  129. context.drawImage(markerImage, locX, locY, mediumImageWidth, mediumImageHeight);
  130. }else{
  131. context.drawImage(markerImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  132. }
  133. // Yellow
  134. locX = (curColor == colorYellow) ? 18 : 52;
  135. locY += 46;
  136. context.beginPath();
  137. context.moveTo(locX + 10, locY + 24);
  138. context.lineTo(locX + 10, locY + 24);
  139. context.lineTo(locX + 22, locY + 16);
  140. context.lineTo(locX + 22, locY + 31);
  141. context.closePath();
  142. context.fillStyle = colorYellow;
  143. context.fill();
  144. if(curColor == colorYellow){
  145. context.drawImage(markerImage, locX, locY, mediumImageWidth, mediumImageHeight);
  146. }else{
  147. context.drawImage(markerImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  148. }
  149. // Yellow
  150. locX = (curColor == colorBrown) ? 18 : 52;
  151. locY += 46;
  152. context.beginPath();
  153. context.moveTo(locX + 10, locY + 24);
  154. context.lineTo(locX + 10, locY + 24);
  155. context.lineTo(locX + 22, locY + 16);
  156. context.lineTo(locX + 22, locY + 31);
  157. context.closePath();
  158. context.fillStyle = colorBrown;
  159. context.fill();
  160. if(curColor == colorBrown){
  161. context.drawImage(markerImage, locX, locY, mediumImageWidth, mediumImageHeight);
  162. }else{
  163. context.drawImage(markerImage, 0, 0, 59, mediumImageHeight, locX, locY, 59, mediumImageHeight);
  164. }
  165. }
  166. else if(curTool == "eraser")
  167. {
  168. context.drawImage(eraserBackgroundImage, 0, 0, canvasWidth, canvasHeight);
  169. context.drawImage(eraserImage, 18, 19, mediumImageWidth, mediumImageHeight);
  170. }else{
  171. alert("Error: Current Tool is undefined");
  172. }
  173. if(curSize == "small"){
  174. locX = 467;
  175. }else if(curSize == "normal"){
  176. locX = 450;
  177. }else if(curSize == "large"){
  178. locX = 428;
  179. }else if(curSize == "huge"){
  180. locX = 399;
  181. }
  182. locY = 189;
  183. context.beginPath();
  184. context.rect(locX, locY, 2, 12);
  185. context.closePath();
  186. context.fillStyle = '#333333';
  187. context.fill();
  188. // Keep the drawing in the drawing area
  189. context.save();
  190. context.beginPath();
  191. context.rect(drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);
  192. context.clip();
  193. var radius;
  194. var i = 0;
  195. for(; i < clickX.length; i++)
  196. {
  197. if(clickSize[i] == "small"){
  198. radius = 2;
  199. }else if(clickSize[i] == "normal"){
  200. radius = 5;
  201. }else if(clickSize[i] == "large"){
  202. radius = 10;
  203. }else if(clickSize[i] == "huge"){
  204. radius = 20;
  205. }else{
  206. alert("Error: Radius is zero for click " + i);
  207. radius = 0;
  208. }
  209. context.beginPath();
  210. if(clickDrag[i] && i){
  211. context.moveTo(clickX[i-1], clickY[i-1]);
  212. }else{
  213. context.moveTo(clickX[i], clickY[i]);
  214. }
  215. context.lineTo(clickX[i], clickY[i]);
  216. context.closePath();
  217. if(clickTool[i] == "eraser"){
  218. //context.globalCompositeOperation = "destination-out"; // To erase instead of draw over with white
  219. context.strokeStyle = 'white';
  220. }else{
  221. //context.globalCompositeOperation = "source-over";    // To erase instead of draw over with white
  222. context.strokeStyle = clickColor[i];
  223. }
  224. context.lineJoin = "round";
  225. context.lineWidth = radius;
  226. context.stroke();
  227. }
  228. //context.globalCompositeOperation = "source-over";// To erase instead of draw over with white
  229. context.restore();
  230. // Overlay a crayon texture (if the current tool is crayon)
  231. if(curTool == "crayon"){
  232. context.globalAlpha = 0.4; // No IE support
  233. context.drawImage(crayonTextureImage, 0, 0, canvasWidth, canvasHeight);
  234. }
  235. context.globalAlpha = 1; // No IE support
  236. // Draw the outline image
  237. context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);
  238. }

复制代码

其实HTML5说白了还是需要很多Javascript支持,不过Canvas非常不错,可以让你在上面自由地绘制图形和动画。这款基于HTML5 Canvas的网页画板就是一个很好的例子。

代码下载

超酷的HTML5 Canvas网络画板教程相关推荐

  1. canvas动画科技园_8个经典炫酷的HTML5 Canvas动画欣赏

    HTML5非常强大,尤其是Canvas技术的应用,让HTML5几乎可以完成所有Flash能完成的效果.本文精选了8个经典炫酷的HTML5 Canvas动画欣赏,每一个都提供全部的源代码,希望对你有所帮 ...

  2. html5字体动画效果,7款超华丽的HTML5 Canvas文字动画特效

    原标题:7款超华丽的HTML5 Canvas文字动画特效 文字是网页中最为常见的元素之一,当然我们使用最多的就是调整文字的颜色.大小等基本属性.有时候我们在一些活动页面上需要展示特别样式的文字效果,这 ...

  3. 好看的html导航栏作品,精选10款超酷的HTML5/CSS3菜单

    本文作者html5tricks,转载请注明出处 今天向大家精选了10款超酷的 1.CSS3手风琴菜单 下拉展开带弹性动画 利用CSS3技术可以实现各种各样的网页菜单,我们之前也在CSS3菜单栏目中分享 ...

  4. 精选10款超酷的HTML5/CSS3菜单

    今天向大家精选了10款超酷的HTML5/CSS3菜单,给你的网页添加不一样的精彩,一起来围观一下吧. 1.CSS3手风琴菜单 下拉展开带弹性动画 利用CSS3技术可以实现各种各样的网页菜单,我们之前也 ...

  5. html5 电子白板 直播,HTML5 canvas 做画板画图 可以做电子白板

    HTML5 canvas 做画板画图 可以做电子白板 HTML5 canvas 做画板画图 可以做电子白板 var canvas; var context; var tool; /** * calle ...

  6. HTML5 canvas 做画板画图 可以做电子白板

    HTML5 canvas 做画板画图 可以做电子白板 <html><head><meta charset="utf-8"><title&g ...

  7. html5超酷单页面,精选10款超酷的HTML5/CSS3菜单

    原标题:精选10款超酷的HTML5/CSS3菜单 今天向大家精选了10款超酷的HTML5/CSS3菜单,给你的网页添加不一样的精彩,一起来围观一下吧. 1.CSS3手风琴菜单 下拉展开带弹性动画 利用 ...

  8. ae制h5文字动画_7款超华丽的HTML5 Canvas文字动画特效

    本文作者html5tricks,转载请注明出处 文字是网页中最为常见的元素之一,当然我们使用最多的就是调整文字的颜色.大小等基本属性.有时候我们在一些活动页面上需要展示特别样式的文字效果,这时候我们就 ...

  9. 超酷震撼 HTML5/CSS3动画应用及源码

    HTML5可以制作非常华丽的动画效果,这点通过之前的分享学习我们已经有深刻的了解了,今天我们主要来分享一些HTML5结合CSS3形成的超炫震撼的动画应用以及它们的源代码,真的非常不错. 1.纯CSS3 ...

最新文章

  1. poj3686(最小权值完美匹配)
  2. Logback 配置文件这么写,日志 TPS 提高 10 倍
  3. msql查询指定日期
  4. oracle hyperion招聘,Hyperion Planning功能顾问
  5. progress与meter的区别
  6. 常见的一些 Hash 函数
  7. linux 获取CPU NUMA内存节点信息
  8. RealNetworks CTO:我们追求低复杂度的软解码
  9. P3033 [USACO11NOV]牛的障碍Cow Steeplechase
  10. 用openbabel将pdbqt文件转成pdb
  11. 猛龙出击•东莞赛区新闻发布会隆重举行,粤港澳大湾区将迎来首场搏击盛宴...
  12. VMware虚拟机CentOS7 - VMnet8网络配置及常见问题解决
  13. 计算机“复制粘贴”之父去世
  14. 手把手学ROR三——Rails的代码方式
  15. mysql 联合主键的作用
  16. 索爱SA-K37拉杆音箱,随时随地帮你撑起一个大舞台
  17. c语言atm程序个人总结,自己写的ATM模拟程序
  18. 逆向最大匹配分词RMM
  19. Banner信息收集和美杜莎使用(9.26 第十二天)
  20. 技术贴(1):将移动硬盘名从F盘改为E盘

热门文章

  1. PyTorch随机生成一个布尔型张量
  2. 交换机短路_交换机端口短路 导致上网不正常
  3. Atmel Studio 6.0 重新安装
  4. 每周全球科技十大新闻(2021.6.21-6.27)
  5. 如何查询一个 app 的 Android 和 iOS 下载量?
  6. 时间管理类入门书籍分享
  7. AI 上当,“苹果”变 “iPod”
  8. 云原生 | 混沌工程工具 ChaosBlade Operator Pod 篇(文末赠书)
  9. 又找到一款微信机器人!(附源码)
  10. Java 某天的开始时间与结束时间