javascript结合html5 canvas实现(可调画笔颜色/粗细/橡皮)的涂鸦板


Posted in Javascript onApril 27, 2013

js+html5 canvas实现的涂鸦画板特效,可调画笔颜色|粗细|橡皮,可以保存涂鸦效果为图片编码,非常适合学习html5的canvas,必须支持html5的浏览器才能看到效果。

<!doctype html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>javascript结合html5 canvas实现的涂鸦板 - 分享JavaScript-sharejs.com</title> 
<meta name="Copyright" content="JavaScript分享网 http://www.sharejs.com/" /> 
<meta name="description" content="javascript结合html5 canvas实现的涂鸦板,JavaScript分享网,js脚本,网页特效,网页模板,png图标,矢量图下载" /> 
<meta content="JavaScript,分享,JavaScript代码,Ajax,jQuery,网页模板,PNG图标,矢量图" name="keywords" /> 
</head> 
<body> 
<style> 
*{margin:0;padding:0;} 
.fa{width:740px;margin:0 auto;} 
.top{margin:20px 0;} 
.top input{width:25px;height:25px;border:1px solid #fff;border-radius:4px;background:#ddd;} 
.top .i1{background:#000000;} 
.top .i2{background:#FF0000;} 
.top .i3{background:#80FF00;} 
.top .i4{background:#00FFFF;} 
.top .i5{background:#808080;} 
.top .i6{background:#FF8000;} 
.top .i7{background:#408080;} 
.top .i8{background:#8000FF;} 
.top .i9{background:#CCCC00;} 
#canvas{background:#eee;cursor:default;} 
.font input{font-size:14px;} 
.top .grea{background:#aaa;} 
</style> 
</head> 
<body> 
<div class="fa"> 
<div class="top"> 
<div id="color"> 
请选择画笔颜色: 
<input class="i1" type="button" value="" /> 
<input class="i2" type="button" value="" /> 
<input class="i3" type="button" value="" /> 
<input class="i4" type="button" value="" /> 
<input class="i5" type="button" value="" /> 
<input class="i6" type="button" value="" /> 
<input class="i7" type="button" value="" /> 
<input class="i8" type="button" value="" /> 
<input class="i9" type="button" value="" /> 
</div> 
<div class="font" id="font"> 
请选择画笔的宽度: 
<input type="button" value="细" /> 
<input type="button" value="中" class="grea"/> 
<input type="button" value="粗" /> 
</div> 
<div> 
<span id="error">如果有错误,请使用橡皮擦:</span> 
<input id="eraser" style="width:60px;font-size:14px;"type="button" value="橡皮擦" /> 
</div> 
<input id="clear" type="button" value="清除画布" style="width:80px;"/> 
<input id="revocation" type="button" value="撤销" style="width:80px;"/> 
<input id="imgurl" type="button" value="导出图片路径" style="width:80px;"/> 
</div> 
<canvas id="canvas" width="740" height="420">您的浏览器不支持 canvas 标签</canvas> 
<div id="div1"></div> 
</div> 
<div id="html"> 
</div> 
<script> 
(function(){ 
var paint={ 
init:function() 
{ 
this.load(); 
}, 
load:function() 
{ 
this.x=[];//记录鼠标移动是的X坐标 
this.y=[];//记录鼠标移动是的Y坐标 
this.clickDrag=[]; 
this.lock=false;//鼠标移动前,判断鼠标是否按下 
this.isEraser=false; 
//this.Timer=null;//橡皮擦启动计时器 
//this.radius=5; 
this.storageColor="#000000"; 
this.eraserRadius=15;//擦除半径值 
this.color=["#000000","#FF0000","#80FF00","#00FFFF","#808080","#FF8000","#408080","#8000FF","#CCCC00"];//画笔颜色值 
this.fontWeight=[2,5,8]; 
this.$=function(id){return typeof id=="string"?document.getElementById(id):id;}; 
this.canvas=this.$("canvas"); 
if (this.canvas.getContext) { 
} else { 
alert("您的浏览器不支持 canvas 标签"); 
return; 
} 
this.cxt=this.canvas.getContext('2d'); 
this.cxt.lineJoin = "round";//context.lineJoin - 指定两条线段的连接方式 
this.cxt.lineWidth = 5;//线条的宽度 
this.iptClear=this.$("clear"); 
this.revocation=this.$("revocation"); 
this.imgurl=this.$("imgurl");//图片路径按钮 
this.w=this.canvas.width;//取画布的宽 
this.h=this.canvas.height;//取画布的高 
this.touch =("createTouch" in document);//判定是否为手持设备 
this.StartEvent = this.touch ? "touchstart" : "mousedown";//支持触摸式使用相应的事件替代 
this.MoveEvent = this.touch ? "touchmove" : "mousemove"; 
this.EndEvent = this.touch ? "touchend" : "mouseup"; 
this.bind(); 
}, 
bind:function() 
{ 
var t=this; 
/*清除画布*/ 
this.iptClear.onclick=function() 
{ 
t.clear(); 
}; 
/*鼠标按下事件,记录鼠标位置,并绘制,解锁lock,打开mousemove事件*/ 
this.canvas['on'+t.StartEvent]=function(e) 
{ 
var touch=t.touch ? e.touches[0] : e; 
var _x=touch.clientX - touch.target.offsetLeft;//鼠标在画布上的x坐标,以画布左上角为起点 
var _y=touch.clientY - touch.target.offsetTop;//鼠标在画布上的y坐标,以画布左上角为起点 
if(t.isEraser) 
{ 
/* 
t.cxt.globalCompositeOperation = "destination-out"; 
t.cxt.beginPath(); 
t.cxt.arc(_x, _y,t.eraserRadius, 0, Math.PI * 2); 
t.cxt.strokeStyle = "rgba(250,250,250,0)"; 
t.cxt.fill(); 
t.cxt.globalCompositeOperation = "source-over"; 
*/ 
t.resetEraser(_x,_y,touch); 
}else 
{ 
t.movePoint(_x,_y);//记录鼠标位置 
t.drawPoint();//绘制路线 
} 
t.lock=true; 
}; 
/*鼠标移动事件*/ 
this.canvas['on'+t.MoveEvent]=function(e) 
{ 
var touch=t.touch ? e.touches[0] : e; 
if(t.lock)//t.lock为true则执行 
{ 
var _x=touch.clientX - touch.target.offsetLeft;//鼠标在画布上的x坐标,以画布左上角为起点 
var _y=touch.clientY - touch.target.offsetTop;//鼠标在画布上的y坐标,以画布左上角为起点 
if(t.isEraser) 
{ 
//if(t.Timer)clearInterval(t.Timer); 
//t.Timer=setInterval(function(){ 
t.resetEraser(_x,_y,touch); 
//},10); 
} 
else 
{ 
t.movePoint(_x,_y,true);//记录鼠标位置 
t.drawPoint();//绘制路线 
} 
} 
}; 
this.canvas['on'+t.EndEvent]=function(e) 
{ 
/*重置数据*/ 
t.lock=false; 
t.x=[]; 
t.y=[]; 
t.clickDrag=[]; 
clearInterval(t.Timer); 
t.Timer=null; 
}; 
this.revocation.onclick=function() 
{ 
t.redraw(); 
}; 
this.changeColor(); 
this.imgurl.onclick=function() 
{ 
t.getUrl(); 
}; 
/*橡皮擦*/ 
this.$("eraser").onclick=function(e) 
{ 
t.isEraser=true; 
t.$("error").style.color="red"; 
t.$("error").innerHTML="您已使用橡皮擦!"; 
}; 
}, 
movePoint:function(x,y,dragging) 
{ 
/*将鼠标坐标添加到各自对应的数组里*/ 
this.x.push(x); 
this.y.push(y); 
this.clickDrag.push(y); 
}, 
drawPoint:function(x,y,radius) 
{ 
for(var i=0; i < this.x.length; i++)//循环数组 
{ 
this.cxt.beginPath();//context.beginPath() , 准备绘制一条路径 
if(this.clickDrag[i] && i){//当是拖动而且i!=0时,从上一个点开始画线。 
this.cxt.moveTo(this.x[i-1], this.y[i-1]);//context.moveTo(x, y) , 新开一个路径,并指定路径的起点 
}else{ 
this.cxt.moveTo(this.x[i]-1, this.y[i]); 
} 
this.cxt.lineTo(this.x[i], this.y[i]);//context.lineTo(x, y) , 将当前点与指定的点用一条笔直的路径连接起来 
this.cxt.closePath();//context.closePath() , 如果当前路径是打开的则关闭它 
this.cxt.stroke();//context.stroke() , 绘制当前路径 
} 
}, 
clear:function() 
{ 
this.cxt.clearRect(0, 0, this.w, this.h);//清除画布,左上角为起点 
}, 
redraw:function() 
{ 
/*撤销*/ 
this.cxt.restore(); 
}, 
preventDefault:function(e){ 
/*阻止默认*/ 
var touch=this.touch ? e.touches[0] : e; 
if(this.touch)touch.preventDefault(); 
else window.event.returnValue = false; 
}, 
changeColor:function() 
{ 
/*为按钮添加事件*/ 
var t=this,iptNum=this.$("color").getElementsByTagName("input"),fontIptNum=this.$("font").getElementsByTagName("input"); 
for(var i=0,l=iptNum.length;i<l;i++) 
{ 
iptNum[i].index=i; 
iptNum[i].onclick=function() 
{ 
t.cxt.save(); 
t.cxt.strokeStyle = t.color[this.index]; 
t.storageColor=t.color[this.index]; 
t.$("error").style.color="#000"; 
t.$("error").innerHTML="如果有错误,请使用橡皮擦:"; 
t.cxt.strokeStyle = t.storageColor; 
t.isEraser=false; 
} 
} 
for(var i=0,l=fontIptNum.length;i<l;i++) 
{ 
t.cxt.save(); 
fontIptNum[i].index=i; 
fontIptNum[i].onclick=function() 
{ 
t.changeBackground(this.index); 
t.cxt.lineWidth = t.fontWeight[this.index]; 
t.$("error").style.color="#000"; 
t.$("error").innerHTML="如果有错误,请使用橡皮擦:"; 
t.isEraser=false; 
t.cxt.strokeStyle = t.storageColor; 
} 
} 
}, 
changeBackground:function(num) 
{ 
/*添加画笔粗细的提示背景颜色切换,灰色为当前*/ 
var fontIptNum=this.$("font").getElementsByTagName("input"); 
for(var j=0,m=fontIptNum.length;j<m;j++) 
{ 
fontIptNum[j].className=""; 
if(j==num) fontIptNum[j].className="grea"; 
} 
}, 
getUrl:function() 
{ 
this.$("html").innerHTML=this.canvas.toDataURL(); 
}, 
resetEraser:function(_x,_y,touch) 
{ 
/*使用橡皮擦-提醒*/ 
var t=this; 
//this.cxt.lineWidth = 30; 
/*source-over 默认,相交部分由后绘制图形的填充(颜色,渐变,纹理)覆盖,全部浏览器通过*/ 
t.cxt.globalCompositeOperation = "destination-out"; 
t.cxt.beginPath(); 
t.cxt.arc(_x, _y, t.eraserRadius, 0, Math.PI * 2); 
t.cxt.strokeStyle = "rgba(250,250,250,0)"; 
t.cxt.fill(); 
t.cxt.globalCompositeOperation = "source-over" 
} 
}; 
paint.init(); 
})(); 
</script> 
<div style="clear:both"></div> 
</body> 
</html>
Javascript 相关文章推荐
javascript document.execCommand() 常用解析
Dec 14 Javascript
Javascript常考语句107条收集
Mar 09 Javascript
你必须知道的JavaScript 变量命名规则详解
May 07 Javascript
javascript事件冒泡详解和捕获、阻止方法
Apr 12 Javascript
jQuery实现不断闪烁文字的方法
May 15 Javascript
如何实现移动端浏览器不显示 pc 端的广告
Oct 15 Javascript
Node.js的MongoDB驱动Mongoose基本使用教程
Mar 01 Javascript
mui上拉加载功能实例详解
Apr 13 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
May 17 Javascript
Vue隐藏显示、只读实例代码
Jul 18 Javascript
浅谈Angular7 项目开发总结
Dec 19 Javascript
JS删除对象中某一属性案例详解
Sep 08 Javascript
jQuery语法高亮插件支持各种程序源代码语法着色加亮
Apr 27 #Javascript
JQuery onload、ready概念介绍及使用方法
Apr 27 #Javascript
用jquery实现输入框获取焦点消失文字
Apr 27 #Javascript
javascript中强制执行toString()具体实现
Apr 27 #Javascript
用客户端js实现带省略号的分页
Apr 27 #Javascript
jquery ajax同步异步的执行最终解决方案
Apr 26 #Javascript
html中使用javascript调用本地程序(exe、doc等)实现代码
Apr 26 #Javascript
You might like
php数据库配置文件一般做法分享
2012/07/07 PHP
php 购物车完整实现代码
2014/06/05 PHP
php返回字符串中所有单词的方法
2015/03/09 PHP
php实现的mongodb操作类实例
2015/04/03 PHP
图文详解PHP环境搭建教程
2016/07/16 PHP
JavaScript去掉空格的方法集合
2010/12/28 Javascript
EasyUI实现二级页面的内容勾选的方法
2015/03/01 Javascript
jQuery使用hide方法隐藏页面上指定元素的方法
2015/03/30 Javascript
jquery.map()方法的使用详解
2015/07/09 Javascript
Nodejs如何搭建Web服务器
2016/03/28 NodeJs
js判断数组key是否存在(不用循环)的简单实例
2016/08/03 Javascript
前端js实现文件的断点续传 后端PHP文件接收
2016/10/14 Javascript
Bootstrap框架的学习教程详解(二)
2016/10/18 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
设置cookie指定时间失效(实例代码)
2017/05/28 Javascript
jQuery实现选中行变色效果(实例讲解)
2017/07/06 jQuery
纯js实现页面返回顶部的动画(超简单)
2017/08/10 Javascript
微信小程序chooseImage的用法(从本地相册选择图片或使用相机拍照)
2018/08/22 Javascript
element中的$confirm的使用
2020/04/26 Javascript
[57:12]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第一场 10.31
2020/11/02 DOTA
Python 12306抢火车票脚本 Python京东抢手机脚本
2018/02/06 Python
python3+mysql查询数据并通过邮件群发excel附件
2018/02/24 Python
对python中GUI,Label和Button的实例详解
2019/06/27 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
Apache部署Django项目图文详解
2019/07/30 Python
Python实现PyPDF2处理PDF文件的方法示例
2019/09/25 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
TensorFlow保存TensorBoard图像操作
2020/06/23 Python
Python中常用的os操作汇总
2020/11/05 Python
python 发送邮件的示例代码(Python2/3都可以直接使用)
2020/12/03 Python
Waterford英国官方网站:世界上最受欢迎的优质水晶品牌
2019/08/17 全球购物
介绍一下gcc特性
2012/01/20 面试题
公司离职证明范本(5篇)
2014/09/17 职场文书
2015年村级财务管理制度
2015/08/04 职场文书
使用numpy实现矩阵的翻转(flip)与旋转
2021/06/03 Python
Flink 侧流输出源码示例解析
2022/09/23 Servers