一、实现的功能
1、基于oop思想构建,支持坐标点、线条(由坐标点组成,包含方向)、多边形(由多个坐标点组成)、圆形(包含圆心坐标点和半径)等实体
2、原生JavaScript实现,不依赖任何第三方js库和插件
3、多图形绘制(支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多边形和圆形绘制)
4、拖拽式绘制(鼠标移动过程中不断进行canvas重绘)
5、图片绘制(作为背景图片时重绘会发生闪烁现象,暂时有点问题,后面继续完善)
5、清空绘制功能
6、新版本优化绘制性能(使用共享坐标变量数组,减少了大量的对象创建操作)
7、新版本支持箭头绘制功能
二、完整实现代码
DrawingTools =(function(){
//公共方法
var getDom=function(id){return document.getElementById(id)};
var isNull=function(s){return s==undefined||typeof(s)=='undefined'||s==null||s=='null'||s==''||s.length<1};
var hideDefRM=function(){document.oncontextmenu=function(){return false}};//屏蔽浏览器默认鼠标事件
/**绘图容器*/
var cbtCanvas;
/**绘图对象*/
var cxt;
/**绘制的图形列表*/
var shapes=new Array();
var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};
//背景图片绘制配置
var bgPictureConfig={
pic:null,//背景图片地址或路径
repaint:true,//是否作为永久背景图,每次清除时会进行重绘
};
//加载并绘制图片(src:图片路径或地址),默认重绘背景图
var loadPicture=function(src){
if(isNull(bgPictureConfig.repaint)||bgPictureConfig.repaint){bgPictureConfig.pic=src}
var img = new Image();
img.onload = function(){cxt.drawImage(img,0,0)}
img.src =src;
}
//绘图基础配置
var paintConfig={lineWidth:1,//线条宽度,默认1
strokeStyle:'red',//画笔颜色,默认红色
fillStyle:'red',//填充色
lineJoin:"round",//线条交角样式,默认圆角
lineCap:"round",//线条结束样式,默认圆角
};
//重新载入绘制样式
var resetStyle=function(){
cxt.strokeStyle=paintConfig.strokeStyle;
cxt.lineWidth=paintConfig.lineWidth;
cxt.lineJoin=paintConfig.lineJoin;
cxt.lineCap=paintConfig.lineCap;
cxt.fillStyle=paintConfig.fillStyle;
}
//鼠标图形
var cursors=['crosshair','pointer'];
/** 切换鼠标样式*/
var switchCorser=function(b){
cbtCanvas.style.cursor=((isNull(b)"选择:"+ctrlConfig.kind);
//设置起始点
switch(ctrlConfig.kind){
case graphkind.pen://画笔(不松开鼠标按键一直画)
beginDrawing();//开始绘制
cxt.beginPath();
cxt.moveTo(e.offsetX,e.offsetY);
break;
case graphkind.poly://多边形
var p=new Point(e.offsetX,e.offsetY);
if(isDrawing()){
getCuGraph().add(p);//添加到
}else{//第一次确定开始坐标
beginDrawing();//开始绘制
setStartPoint(p);
var poly=new Poly();
poly.add(p);
setCuGraph(poly);//设置当前绘制图形
}
break;
case graphkind.line://线条
case graphkind.arrow://方向
case graphkind.trian://三角形
case graphkind.rect://矩形
case graphkind.parallel://平行四边形
case graphkind.trapezoid://梯形
beginDrawing();//开始绘制
var p=new Point(e.offsetX,e.offsetY);
setStartPoint(p);
var poly=new Poly();
poly.add(p);
setCuGraph(poly);//设置当前绘制图形
break;
case graphkind.circle://圆
console.log("确定图形绘制开始坐标点:"+e.offsetX+","+e.offsetY);//点击确定图形的开始坐标点
beginDrawing();//开始绘制
var p=new Point(e.offsetX,e.offsetY);
setStartPoint(p);
var circle= new Circle({'start':p});
setCuGraph(circle);
break;
case ctrlConfig.cursor: //手型鼠标
default://默认是手型鼠标,不允许绘制
}
}else if(btnNum==2){
console.log("右键由于结束多边形绘制");
if(isDrawing()){
if(ctrlConfig.kind==graphkind.poly){
repaint();
getCuGraph().draw();
stopDrawing();//结束绘制
}
}
}
hideDefRM();//屏蔽浏览器默认事件
}
//鼠标移动(拖动,根据鼠标移动的位置不断重绘图形)
var mouseMove = function(e){
if(isDrawing()&&hasStartPoint()){//检查是否开始绘制,检查是否有开始坐标点
//画笔不需要重绘
if(ctrlConfig.kind>1){
repaint();//重绘
}
var p=setCuPointXY(e.offsetX,e.offsetY,0);//设置共享的临时坐标点,用于防止重复创建对象
switch(ctrlConfig.kind){
case graphkind.pen://画笔(一直画)
cxt.lineTo(e.offsetX,e.offsetY);
cxt.stroke();
break;
case graphkind.poly://多边形
var poly=getCuGraph(poly);
var size=poly.getSize();
poly.setPoint(p,(size-1));
poly.draw();
break;
case graphkind.line://线条
var line=new Line(getStartPoint(),p,false);
ctrlConfig.cuGraph=line;
line.draw();
break;
case graphkind.arrow://方向
var line=new Line(getStartPoint(),p,true);
ctrlConfig.cuGraph=line;
line.draw();
break;
case graphkind.trian://三角形
var lu=getStartPoint();
var x2=p.getX();
var x1=lu.getX();
//三角形左边的点坐标计算方法:(x1-(x2-x1),y2)
var x3=x1-(x2-x1);
var l=setCuPointXY(x3,p.getY(),1);//设置共享的临时坐标点,用于防止重复创建对象
var poly=getCuGraph();//获取当前图形
poly.set([lu,p,l]);
poly.draw();//即时绘制
break;
case graphkind.parallel://平行四边形
var lu=getStartPoint();
var x3=p.getX();
var x1=lu.getX();
//平行四边形两个未知坐标点计算方法:(x1-(x3-x1),y3),(x1+(x3-x1),y1)
var x2=x3+(x3-x1);
var x4=x1-(x3-x1);
var ld=setCuPointXY(x2,lu.getY(),1);//设置共享的临时坐标点,用于防止重复创建对象
var ru=setCuPointXY(x4,p.getY(),2);//设置共享的临时坐标点,用于防止重复创建对象
var poly=getCuGraph();//获取当前图形
poly.set([lu,ru,p,ld]);
poly.draw();//即时绘制
break;
case graphkind.trapezoid://梯形
var lu=getStartPoint();
var x3=p.getX();
var x1=lu.getX();
//梯形两个未知坐标点计算方法:(x3-(x3-x1)/2,y1),(x1-(x3-x1)/2,y3)
var x2=x3-(x3-x1)/2;
var x4=x1-(x3-x1)/2;
var ld=setCuPointXY(x2,lu.getY(),1);
var ru=setCuPointXY(x4,p.getY(),2);
var poly=getCuGraph();
poly.set([lu,ru,p,ld]);
poly.draw();
break;
case graphkind.rect://矩形
var lu=getStartPoint();
//矩形右上角和左上角坐标计算方法
var ld=setCuPointXY(lu.getX(),p.getY(),1);
var ru=setCuPointXY(p.getX(),lu.getY(),2);
var poly=getCuGraph();
poly.set([lu,ru,p,ld]);
poly.draw();
break;
case graphkind.circle://圆
var circle=getCuGraph();//获取当前图形
circle.set({'start':getStartPoint(),'end':p});
circle.draw();//即时绘制
break;
}
}
}
//鼠标按键松开
var mouseUp = function(e){
if(isDrawing()){
//console.log("松开鼠标按键:"+e.offsetX+","+e.offsetY);
//画笔不需要重绘
if(ctrlConfig.kind>1){
repaint();
getCuGraph().draw();
}
if(ctrlConfig.kind!=graphkind.poly){//多边形绘制鼠标按键松开不结束绘制,多边形只有右键点击才能结束绘制
stopDrawing();//结束绘制
}
}
}
//鼠标移出
var mouseOut = function(e){
console.log("鼠标移出绘制区域"+e.offsetX+","+e.offsetY);
if(isDrawing()){
console.log("停止绘制");
if(ctrlConfig.kind>1){
repaint();
getCuGraph().draw();
}
stopDrawing();//停止绘制
}
}
return{
isNull:isNull,
getDom:getDom,
clear:function(){
stopDrawing();//停止绘制
repaint();
},
/**初始化*/
init:function(params){
cbtCanvas=getDom(params.id);
//浏览器是否支持Canvas
if (cbtCanvas.getContext){
/**绘图对象*/
cxt=cbtCanvas.getContext("2d");
cbtCanvas.onmousedown = mouseDown;
cbtCanvas.onmouseup = mouseUp;
cbtCanvas.onmousemove = mouseMove;
cbtCanvas.onmouseout = mouseOut;
resetStyle();//载入样式
return true;
}else{
return false;
}
},
/**设置背景图片*/
setBgPic:loadPicture,
/**选择图形类型*/
begin:function(k){
console.log("选择绘制图形:"+k);
if(isNaN(k)){//如果不是数字,先转换为对应字符
ctrlConfig.kind=kind[k];
}else{
ctrlConfig.kind=k;
}
switchCorser(true);//切换鼠标样式
},
/*手型,并停止绘图*/
hand:function(){
ctrlConfig.kind=0;
stopDrawing();//停止绘制
switchCorser(false);//切换鼠标样式
}
}
})
三、使用方式
1、图形类型
0:鼠标,1:画笔,2:线条,3:三角形,4:矩形,5:多边形,6:圆形,21:箭头,41:平行四边形,42:梯形
var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};
2、初始化以及使用背景图片和画笔选择
var drawUtil=new DrawingTools();
//初始化,(如果浏览器不支持H5,会初始化失败,返回false)
if(drawUtil.init({'id':'calibrationCanvas'})){
//加载图片
var imgsrc='图片地址';
if(!drawUtil.isNull(imgsrc)){
drawUtil.setBgPic(imgsrc,true);//设置背景图片(异步加载图片)
}
}
drawUtil.begin(1);//选择画笔
2、绘制箭头
drawUtil.begin(21);
总结
以上所述是小编给大家介绍的原生JS使用Canvas实现拖拽式绘图功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
暂无“原生JS使用Canvas实现拖拽式绘图功能”评论...
更新动态
2025年10月29日
2025年10月29日
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]