超酷的html5 canvas网络画板教程-mile米乐体育
web技术
2020年03月31日 23:11
1
本文由码农网 – 小峰原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!
在今天的html教程里,我们要学习一下如何使用html5 canvas实现一个超酷而又简单的网络画板功能。在这个教程中,我们可以选择笔刷的类型、笔刷的大小以及笔刷的颜色,当然作为画板还需要很多功能,这里只是最基本的绘制功能,大家可以自己实现类似矩形、椭圆等复杂元素的绘制。
你也可以再这里查看demo演示
下面我们来简单地分析一下实现这个html5网页画板的原理及代码,代码由html以及javascript组成,主要还是javascript代码。
html代码:
html代码非常简单,仅仅是构造了一个canvas容器,我们的画板就在这个地方生成。
javascript代码:
首先我们通过一组变量来定义画板的样式,以及一些数据的初始化:
var canvas; var context; var canvaswidth = 490; var canvasheight = 220; var padding = 25; var linewidth = 8; var colorpurple = "#cb3594"; var colorgreen = "#659b41"; var coloryellow = "#ffcf33"; var colorbrown = "#986928"; var outlineimage = new image(); var crayonimage = new image(); var markerimage = new image(); var eraserimage = new image(); var crayonbackgroundimage = new image(); var markerbackgroundimage = new image(); var eraserbackgroundimage = new image(); var crayontextureimage = new image(); var clickx = new array(); var clicky = new array(); var clickcolor = new array(); var clicktool = new array(); var clicksize = new array(); var clickdrag = new array(); var paint = false; var curcolor = colorpurple; var curtool = "crayon"; var cursize = "normal"; var mediumstartx = 18; var mediumstarty = 19; var mediumimagewidth = 93; var mediumimageheight = 46; var drawingareax = 111; var drawingareay = 11; var drawingareawidth = 267; var drawingareaheight = 200; var toolhotspotstarty = 23; var toolhotspotheight = 38; var sizehotspotstarty = 157; var sizehotspotheight = 36; var sizehotspotwidthobject = new object(); sizehotspotwidthobject.huge = 39; sizehotspotwidthobject.large = 25; sizehotspotwidthobject.normal = 18; sizehotspotwidthobject.small = 16; var totalloadresources = 8; var curloadresnum = 0;
接下来开始准备画布,也就是初始化canvas对象:
function preparecanvas() { // create the canvas (neccessary for ie because it doesn't know what a canvas element is) var canvasdiv = document.getelementbyid('canvasdiv'); canvas = document.createelement('canvas'); canvas.setattribute('width', canvaswidth); canvas.setattribute('height', canvasheight); canvas.setattribute('id', 'canvas'); canvasdiv.appendchild(canvas); if(typeof g_vmlcanvasmanager != 'undefined') { canvas = g_vmlcanvasmanager.initelement(canvas); } context = canvas.getcontext("2d"); // grab the 2d canvas context // note: the above code is a workaround for ie 8 and lower. otherwise we could have used: // context = document.getelementbyid('canvas').getcontext("2d"); // load images // ----------- crayonimage.onload = function() { resourceloaded(); }; crayonimage.src = "images/crayon-outline.png"; //context.drawimage(crayonimage, 0, 0, 100, 100); markerimage.onload = function() { resourceloaded(); }; markerimage.src = "images/marker-outline.png"; eraserimage.onload = function() { resourceloaded(); }; eraserimage.src = "images/eraser-outline.png"; crayonbackgroundimage.onload = function() { resourceloaded(); }; crayonbackgroundimage.src = "images/crayon-background.png"; markerbackgroundimage.onload = function() { resourceloaded(); }; markerbackgroundimage.src = "images/marker-background.png"; eraserbackgroundimage.onload = function() { resourceloaded(); }; eraserbackgroundimage.src = "images/eraser-background.png"; crayontextureimage.onload = function() { resourceloaded(); }; crayontextureimage.src = "images/crayon-texture.png"; outlineimage.onload = function() { resourceloaded(); }; outlineimage.src = "images/watermelon-duck-outline.png"; // add mouse events // ---------------- $('#canvas').mousedown(function(e) { // mouse down location var mousex = e.pagex - this.offsetleft; var mousey = e.pagey - this.offsettop; if(mousex < drawingareax) // left of the drawing area { if(mousex > mediumstartx) { if(mousey > mediumstarty && mousey < mediumstarty mediumimageheight){ curcolor = colorpurple; }else if(mousey > mediumstarty mediumimageheight && mousey < mediumstarty mediumimageheight * 2){ curcolor = colorgreen; }else if(mousey > mediumstarty mediumimageheight * 2 && mousey < mediumstarty mediumimageheight * 3){ curcolor = coloryellow; }else if(mousey > mediumstarty mediumimageheight * 3 && mousey < mediumstarty mediumimageheight * 4){ curcolor = colorbrown; } } } else if(mousex > drawingareax drawingareawidth) // right of the drawing area { if(mousey > toolhotspotstarty) { if(mousey > sizehotspotstarty) { var sizehotspotstartx = drawingareax drawingareawidth; if(mousey < sizehotspotstarty sizehotspotheight && mousex > sizehotspotstartx) { if(mousex < sizehotspotstartx sizehotspotwidthobject.huge){ cursize = "huge"; }else if(mousex < sizehotspotstartx sizehotspotwidthobject.large sizehotspotwidthobject.huge){ cursize = "large"; }else if(mousex < sizehotspotstartx sizehotspotwidthobject.normal sizehotspotwidthobject.large sizehotspotwidthobject.huge){ cursize = "normal"; }else if(mousex < sizehotspotstartx sizehotspotwidthobject.small sizehotspotwidthobject.normal sizehotspotwidthobject.large sizehotspotwidthobject.huge){ cursize = "small"; } } } else { if(mousey < toolhotspotstarty toolhotspotheight){ curtool = "crayon"; }else if(mousey < toolhotspotstarty toolhotspotheight * 2){ curtool = "marker"; }else if(mousey < toolhotspotstarty toolhotspotheight * 3){ curtool = "eraser"; } } } } else if(mousey > drawingareay && mousey < drawingareay drawingareaheight) { // mouse click location on drawing area } paint = true; addclick(mousex, mousey, false); redraw(); }); $('#canvas').mousemove(function(e){ if(paint==true){ addclick(e.pagex - this.offsetleft, e.pagey - this.offsettop, true); redraw(); } }); $('#canvas').mouseup(function(e){ paint = false; redraw(); }); $('#canvas').mouseleave(function(e){ paint = false; }); }
看起来很复杂,前面主要是初始化canvas的背景图片,后面主要是初始化画笔事件,像click、mouseup、mouseleave等鼠标事件。
下面是draw的主要方法:
function redraw() { // make sure required resources are loaded before redrawing if(curloadresnum < totalloadresources){ return; } clearcanvas(); var locx; var locy; if(curtool == "crayon") { // draw the crayon tool background context.drawimage(crayonbackgroundimage, 0, 0, canvaswidth, canvasheight); // purple locx = (curcolor == colorpurple) ? 18 : 52; locy = 19; context.beginpath(); context.moveto(locx 41, locy 11); context.lineto(locx 41, locy 35); context.lineto(locx 29, locy 35); context.lineto(locx 29, locy 33); context.lineto(locx 11, locy 27); context.lineto(locx 11, locy 19); context.lineto(locx 29, locy 13); context.lineto(locx 29, locy 11); context.lineto(locx 41, locy 11); context.closepath(); context.fillstyle = colorpurple; context.fill(); if(curcolor == colorpurple){ context.drawimage(crayonimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(crayonimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } // green locx = (curcolor == colorgreen) ? 18 : 52; locy = 46; context.beginpath(); context.moveto(locx 41, locy 11); context.lineto(locx 41, locy 35); context.lineto(locx 29, locy 35); context.lineto(locx 29, locy 33); context.lineto(locx 11, locy 27); context.lineto(locx 11, locy 19); context.lineto(locx 29, locy 13); context.lineto(locx 29, locy 11); context.lineto(locx 41, locy 11); context.closepath(); context.fillstyle = colorgreen; context.fill(); if(curcolor == colorgreen){ context.drawimage(crayonimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(crayonimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } // yellow locx = (curcolor == coloryellow) ? 18 : 52; locy = 46; context.beginpath(); context.moveto(locx 41, locy 11); context.lineto(locx 41, locy 35); context.lineto(locx 29, locy 35); context.lineto(locx 29, locy 33); context.lineto(locx 11, locy 27); context.lineto(locx 11, locy 19); context.lineto(locx 29, locy 13); context.lineto(locx 29, locy 11); context.lineto(locx 41, locy 11); context.closepath(); context.fillstyle = coloryellow; context.fill(); if(curcolor == coloryellow){ context.drawimage(crayonimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(crayonimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } // yellow locx = (curcolor == colorbrown) ? 18 : 52; locy = 46; context.beginpath(); context.moveto(locx 41, locy 11); context.lineto(locx 41, locy 35); context.lineto(locx 29, locy 35); context.lineto(locx 29, locy 33); context.lineto(locx 11, locy 27); context.lineto(locx 11, locy 19); context.lineto(locx 29, locy 13); context.lineto(locx 29, locy 11); context.lineto(locx 41, locy 11); context.closepath(); context.fillstyle = colorbrown; context.fill(); if(curcolor == colorbrown){ context.drawimage(crayonimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(crayonimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } } else if(curtool == "marker") { // draw the marker tool background context.drawimage(markerbackgroundimage, 0, 0, canvaswidth, canvasheight); // purple locx = (curcolor == colorpurple) ? 18 : 52; locy = 19; context.beginpath(); context.moveto(locx 10, locy 24); context.lineto(locx 10, locy 24); context.lineto(locx 22, locy 16); context.lineto(locx 22, locy 31); context.closepath(); context.fillstyle = colorpurple; context.fill(); if(curcolor == colorpurple){ context.drawimage(markerimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(markerimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } // green locx = (curcolor == colorgreen) ? 18 : 52; locy = 46; context.beginpath(); context.moveto(locx 10, locy 24); context.lineto(locx 10, locy 24); context.lineto(locx 22, locy 16); context.lineto(locx 22, locy 31); context.closepath(); context.fillstyle = colorgreen; context.fill(); if(curcolor == colorgreen){ context.drawimage(markerimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(markerimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } // yellow locx = (curcolor == coloryellow) ? 18 : 52; locy = 46; context.beginpath(); context.moveto(locx 10, locy 24); context.lineto(locx 10, locy 24); context.lineto(locx 22, locy 16); context.lineto(locx 22, locy 31); context.closepath(); context.fillstyle = coloryellow; context.fill(); if(curcolor == coloryellow){ context.drawimage(markerimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(markerimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } // yellow locx = (curcolor == colorbrown) ? 18 : 52; locy = 46; context.beginpath(); context.moveto(locx 10, locy 24); context.lineto(locx 10, locy 24); context.lineto(locx 22, locy 16); context.lineto(locx 22, locy 31); context.closepath(); context.fillstyle = colorbrown; context.fill(); if(curcolor == colorbrown){ context.drawimage(markerimage, locx, locy, mediumimagewidth, mediumimageheight); }else{ context.drawimage(markerimage, 0, 0, 59, mediumimageheight, locx, locy, 59, mediumimageheight); } } else if(curtool == "eraser") { context.drawimage(eraserbackgroundimage, 0, 0, canvaswidth, canvasheight); context.drawimage(eraserimage, 18, 19, mediumimagewidth, mediumimageheight); }else{ alert("error: current tool is undefined"); } if(cursize == "small"){ locx = 467; }else if(cursize == "normal"){ locx = 450; }else if(cursize == "large"){ locx = 428; }else if(cursize == "huge"){ locx = 399; } locy = 189; context.beginpath(); context.rect(locx, locy, 2, 12); context.closepath(); context.fillstyle = '#333333'; context.fill(); // keep the drawing in the drawing area context.save(); context.beginpath(); context.rect(drawingareax, drawingareay, drawingareawidth, drawingareaheight); context.clip(); var radius; var i = 0; for(; i < clickx.length; i ) { if(clicksize[i] == "small"){ radius = 2; }else if(clicksize[i] == "normal"){ radius = 5; }else if(clicksize[i] == "large"){ radius = 10; }else if(clicksize[i] == "huge"){ radius = 20; }else{ alert("error: radius is zero for click " i); radius = 0; } context.beginpath(); if(clickdrag[i] && i){ context.moveto(clickx[i-1], clicky[i-1]); }else{ context.moveto(clickx[i], clicky[i]); } context.lineto(clickx[i], clicky[i]); context.closepath(); if(clicktool[i] == "eraser"){ //context.globalcompositeoperation = "destination-out"; // to erase instead of draw over with white context.strokestyle = 'white'; }else{ //context.globalcompositeoperation = "source-over"; // to erase instead of draw over with white context.strokestyle = clickcolor[i]; } context.linejoin = "round"; context.linewidth = radius; context.stroke(); } //context.globalcompositeoperation = "source-over";// to erase instead of draw over with white context.restore(); // overlay a crayon texture (if the current tool is crayon) if(curtool == "crayon"){ context.globalalpha = 0.4; // no ie support context.drawimage(crayontextureimage, 0, 0, canvaswidth, canvasheight); } context.globalalpha = 1; // no ie support // draw the outline image context.drawimage(outlineimage, drawingareax, drawingareay, drawingareawidth, drawingareaheight); }
其实html5说白了还是需要很多javascript支持,不过canvas非常不错,可以让你在上面自由地绘制图形和动画。这款基于html5 canvas的网页画板就是一个很好的例子。源代码下载>>
本文链接:http://www.codeceo.com/article/cool-html5-canvas-drawing.html
本文作者:码农网 – 小峰
[ 原创作品,转载必须在正文中标注并保留原文链接和作者等信息。]
展开全文