基于HTML5 Canvas的网页画板实现教程

      2020-09-14 13:22      HTML5

基于HTML5 Canvas的网页画板实现教程

HTML5的功能非常强大,尤其是Canvas的应用更加广泛,Canvas画布上面不仅可以绘制任意的图形,而且可以实现多种多样的动画,甚至是一些交互式的应用,比如网页网版。这次我们要来看的就是一款基于HTML5 Canvas的网页画板,在这里仅对一些关键性的代码进行记录,大家也可以下载全部源代码研究。



你也可以再这里查看在线演示
下面我们来简单地分析一下实现这个HTML5网页画板的原理及代码,代码由HTML以及Javascript组成,主要还是Javascript代码。
HTML代码:<div><div></div> </div>
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 locationvar 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 redrawingif(curLoadResNum < totalLoadResources){ return; }clearCanvas();var locX;var locY;if(curTool == "crayon"){// Draw the crayon tool backgroundcontext.drawImage(crayonBackgroundImage, 0, 0, canvasWidth, canvasHeight);// PurplelocX = (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);}// GreenlocX = (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);}// YellowlocX = (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);}// YellowlocX = (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 backgroundcontext.drawImage(markerBackgroundImage, 0, 0, canvasWidth, canvasHeight);// PurplelocX = (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);}// GreenlocX = (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);}// YellowlocX = (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);}// YellowlocX = (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 areacontext.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 whitecontext.strokeStyle = 'white';}else{//context.globalCompositeOperation = "source-over"; // To erase instead of draw over with whitecontext.strokeStyle = clickColor[i];}context.lineJoin = "round";context.lineWidth = radius;context.stroke();}//context.globalCompositeOperation = "source-over";// To erase instead of draw over with whitecontext.restore();// Overlay a crayon texture (if the current tool is crayon)if(curTool == "crayon"){context.globalAlpha = 0.4; // No IE supportcontext.drawImage(crayonTextureImage, 0, 0, canvasWidth, canvasHeight);}context.globalAlpha = 1; // No IE support// Draw the outline imagecontext.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);}

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

猜你在找