超级炫酷的HTML5 Canvas网络画板代码示例详解
超级炫酷的HTML5 Canvas网络画板代码示例详解
在今天的HTML教程里,我们要学习一下如何使用HTML5 Canvas实现一个超酷而又简单的网络画板功能。在这个教程中,我们可以选择笔刷的类型、笔刷的大小以及笔刷的颜色,当然作为画板还需要很多功能,这里只是最基本的绘制功能,大家可以自己实现类似矩形、椭圆等复杂元素的绘制。
你也可以再这里查看DEMO演示
下面我们来简单地分析一下实现这个HTML5网页画板的原理及代码,代码由HTML以及Javascript组成,主要还是Javascript代码。
HTML代码:
<p style="width:530px;margin:10px auto"> <p id="canvasp"></p> </p>
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 canvasp = document.getElementById('canvasp'); canvas = document.createElement('canvas'); canvas.setAttribute('width', canvasWidth); canvas.setAttribute('height', canvasHeight); canvas.setAttribute('id', 'canvas'); canvasp.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的网页画板就是一个很好的例子。源代码下载>>
Atas ialah kandungan terperinci 超级炫酷的HTML5 Canvas网络画板代码示例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan untuk Sempadan Jadual dalam HTML. Di sini kita membincangkan pelbagai cara untuk menentukan sempadan jadual dengan contoh Sempadan Jadual dalam HTML.

Panduan untuk HTML margin-kiri. Di sini kita membincangkan gambaran keseluruhan ringkas tentang HTML margin-left dan Contoh-contohnya bersama-sama dengan Pelaksanaan Kodnya.

Ini ialah panduan untuk Nested Table dalam HTML. Di sini kita membincangkan cara membuat jadual dalam jadual bersama-sama dengan contoh masing-masing.

Panduan untuk Susun Atur Jadual HTML. Di sini kita membincangkan Nilai Susun Atur Jadual HTML bersama-sama dengan contoh dan output n perincian.

Panduan untuk Pemegang Tempat Input HTML. Di sini kita membincangkan Contoh Pemegang Tempat Input HTML bersama-sama dengan kod dan output.

Panduan kepada Senarai Tertib HTML. Di sini kami juga membincangkan pengenalan senarai dan jenis Tertib HTML bersama-sama dengan contoh mereka masing-masing

Panduan untuk Memindahkan Teks dalam HTML. Di sini kita membincangkan pengenalan, cara teg marquee berfungsi dengan sintaks dan contoh untuk dilaksanakan.

Panduan untuk Butang onclick HTML. Di sini kita membincangkan pengenalan, kerja, contoh dan onclick Event masing-masing dalam pelbagai acara.
