html5在线画图工具,HTML5 Canvas画板画图工具 可定义笔刷和画布
本文作者html5tricks,转载请注明出处
下面我们来简单地分析一下实现这个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的网页画板就是一个很好的例子。
html5在线画图工具,HTML5 Canvas画板画图工具 可定义笔刷和画布相关推荐
- 移动端canvas画板绘图工具
移动端canvas画板绘图工具 原生js canvas画板可在移动端使用,使用鼠标或者手指触屏绘画各种图形效果. 演示地址 下载地址
- html5在线制作教程,HTML5 Canvas 制作动画
HTML5 Canvas 制作动画 在HTML5 canvas中绘制图像动画效果,你需要绘制出每一帧的图像,然后在一个极短的时间内从一帧过渡到下一帧,形成动画效果. 在线示例 要在HTML5画布上绘制 ...
- html5在线考试倒计时,html5 canvas 实现倒计时 功能
function showTime(a) { var b = { id: "showtime", //canvasid x: 60, //中心点坐标 X轴; y: 60, //中心 ...
- 几何画板自定义工具_可能是全网最详细:12 款 iPad 绘画工具横评,总有一款适合你...
自从上次写完 Procreate 的两篇教程后,我收到了许多读者的反馈,很开心.然后我注意到有部分读者提到自己不太能适应 Procreate 的一些功能和画笔效果. 也难免,虽然 Procreate ...
- html5 电子白板 直播,HTML5 canvas 做画板画图 可以做电子白板
HTML5 canvas 做画板画图 可以做电子白板 HTML5 canvas 做画板画图 可以做电子白板 var canvas; var context; var tool; /** * calle ...
- HTML5 canvas 做画板画图 可以做电子白板
HTML5 canvas 做画板画图 可以做电子白板 <html><head><meta charset="utf-8"><title&g ...
- html5 在线白板,Html5 canvas画图白板踩坑
最近接手了一个小型的H5,最主要的功能大概就是拍照上传和canvas画板了. 主要是记录一下自己菜到像傻子一样的技术. 1.canvas画板隔空打牛!画布越往上部分错位距离越小,越往下距离越大. 2. ...
- html canvas php,HTML5 canvas实现画图程序(附代码)
这篇文章给大家介绍的内容是关于HTML5 canvas实现画图程序(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 项目简介 整个项目分为两大部分场景 场景负责canvas控 ...
- html5 canvas 自定义画图裁剪图片
html5 给我们带来了极大惊喜的canvas标签,有了它我们可以在浏览器客户端处理图片,不需要经过服务器周转.可以实现: 1.照片本地处理,ps有的一些基本功能都有 2.结合js可以实现一些很炫的动 ...
- HTML5 canvas画板的制作
canvas画板的制作 今天看了一些canvas视频的教程,有制作画板的过程,但是我有给出他们的简洁版和使用版本,能让用户看出画直线的路径,也就是当你拉一条直线的时候就和绘图工具一样,都能很好使用 ...
最新文章
- rollback 最后判断成功_面试自我介绍随便说说就行?注意3忌2套路帮你提升50%成功率...
- pandas重置dataframe的索引(reset_index)、如果索引不匹配dataframe操作时候的问题、重置索引(不设置drop=true)远索引生成新的数据列
- 国内第一本micropython的书出版《机器人Python极客编程入门与实战》
- 斐波那契查找+思路分析
- java初始化数据报_java – 如何在Docker中初始化数据库后启动flyway
- C++中lib和dll解析
- 程序员的进阶课-架构师之路(13)-B-树
- java存储数据_Java 数据存储
- python工资这么高为什么不学-为什么我不建议你学Python?
- sql语言的一大类 DML 数据的操纵语言
- 通过binlog恢复mysql数据库
- 生信技能树 电脑配置linux,生信技能树----Linux练习题答案
- VB 注册ocx控件的方法
- python读书心得体会_终于领会学习python的心得体会
- mp3格式转换软件哪个好?
- 数学建模--正态分布均值的假设检验
- 问题解决:VScode在使用中文输入法时出现vim insert模式变成vim normal的奇怪现象( jj 映射成esc)
- oracle中有没有distance,oracle_关于extended distance cluster rac的介绍
- 【数据存储】signed,unsigned到底怎么区分?如何计算?
- inet_addr,inet_pton,inet_aton 用法