html5 (canvas) +css+js 实现画图工具
2018-01-30 16:12
756 查看
效果图:
js:var canvas= document.getElementById("cans");
var cxt=canvas.getContext("2d");
var startX,startY,endX,endY;
var data;
var shapes = new Array();
var mousedown,mouseout;
var shape=1;
html:
<body>
<div id="myCans" class="mycans" >
<br><br>
<form name="form1">
<center>
<div class="black" >
<center>
<span name="shape" id="Line" > Line</span><!--
--><span name="shape" id="Circle" >Circle</span><!--
--><span name="shape" id="Rectangle">Rectangle</span><!--
--><span name="shape" id="Pencil">Pencil</span><!--
--><span name="shape" id="Rubber">Rubber</span>
</center>
</div>
<br>
<center>
<input type="button" value="open" id="Open">
<input type="button" value="Save" id="Reserve">
<input type="color" id="color" >
<select id="linewidth" name="line_width" onchange="line_Width(form1.line_width.options[selectedIndex].value)">
<option value="1" slected="slected">1px</option>
<option value="3" >3px</option>
<option value="5" >5px</option>
<option value="10" >10px</option>
<option value="15" >15px</option>
<option value="20" >20px</option>
</select>
<input type="button" value="clear" id="Clear" >
</center>
</center>
</form>
<br><br>
<center>
<canvas id="cans" width="1300" height="500"></canvas>
</center>
</div>
</body>
css:
.black{
background:black;
padding:8px;
width:500px;
color:white;
}
canvas{
background: white;
}
.mycans{
height:758px;
background: black;
}
body{
margin:0;
background: black;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
span{
display:inline-block;
width:80px;
cursor:pointer;
}
js:var canvas= document.getElementById("cans");
var cxt=canvas.getContext("2d");
var startX,startY,endX,endY;
var data;
var shapes = new Array();
var mousedown,mouseout;
var shape=1;
// 创建图形对象,保存该图形的开始、结束坐标以及相关属性 function create_shape(Shape,startx,starty,endx,endy){ var color = cxt.strokeStyle.toString(); var size = cxt.lineWidth; shapes[shapes.length]={ "Shape":Shape, "startx":startx, "endx":endx, "starty":starty, "endy":endy, "color":color, "size":size, "x":[], "y":[], }; }
//点击画布,获取起始坐标,由于加了标题栏,坐标存在一个偏移量 function StartPos(e){ mousedown =0; mouseout = 0; var rect = canvas.getBoundingClientRect(); startX=e.clientX - rect.left * (canvas.width / rect.width); startY=e.clientY - rect.top * (canvas.height / rect.height) ; //如果是任意线,创建该对象 if(shape==4){ create_shape(4,startX,startY,endX,endY); shapes[shapes.length-1].x.push(startX); shapes[shapes.length-1].y.push(startY); } //如果是橡皮擦,调用擦除功能函数 if(shape==5){ delete_picture(); } //保存当前画面 data=cxt.getImageData(0, 0, canvas.width, canvas.height); }
// 获取终点坐标 function EndPos(e){ if(startX!=null){ var rect = canvas.getBoundingClientRect(); endX=e.clientX - rect.left * (canvas.width / rect.width); endY=e.clientY - rect.top * (canvas.height / rect.height) ; } }
// 松开鼠标 function Mouseup(){ if(startX!=null&&endX!=null&&shape!=5&&shape!=4&&!(mousedown==1&&mouseout==1)){ //创建该图形对象,并保存相关属性 create_shape(shape,startX,startY,endX,endY); endX=null; } startX=null; }
// 按下鼠标 function Mousedown(){ //如果鼠标是在画布外按下的,mousedown=1 if(mouseout == 1) mousedown=1; }
// 鼠标移出了画布,mouseout=1 function MouseOut(){ mouseout=1; }
// 选择画直线 function line(){ shape=1; } // 选择画圆 function circle(){ shape=2 } // 选择画矩形 function rectangle(){ shape=3; } // 选择画自由线 function pencil(){ shape=4; } // 选择橡皮擦 function rubber(){ shape = 5; }
// 鼠标移动过程中画画 function draw(){ // 如果起始坐标不为空而且不是橡皮擦状态 if(startX!=null&&shape!=5){ //如果不是任意线状态,清空当前画布,展示上一个画布状态 if(shape!=4){ cxt.clearRect(0,0,canvas.width,canvas.height); cxt.putImageData(data,0,0); } //调用画图函数画图 draw_picture(shape,startX,startY,endX,endY); } }
// 画图 function draw_picture(Shape,startx,starty,endx,endy){ switch(Shape){ case 1://直线 cxt.beginPath(); cxt.moveTo(startx,starty); cxt.lineTo(endx,endy); cxt.stroke(); cxt.closePath(); break; case 2://圆 var temp=Math.sqrt(Math.pow((endx-startx),2)+Math.pow((endy-starty),2)); cxt.beginPath(); cxt.arc(startx,starty,temp,0,Math.PI*2,true); cxt.stroke(); cxt.closePath(); break; case 3://矩形 cxt.beginPath(); cxt.rect(startx,starty,endx-startx,endy-starty); cxt.stroke(); cxt.closePath(); break; case 4://任意线 draw_pencil(); } }
//画任意线 function draw_pencil(){ //如果不是橡皮擦状态,记录走过的位置坐标 if(shape!=5){ shapes[shapes.length-1].x.push(endX); shapes[shapes.length-1].y.push(endY); } //画任意线 cxt.beginPath(); cxt.lineJoin="round"; cxt.moveTo(startX,startY); cxt.lineTo(endX,endY); cxt.stroke(); cxt.closePath(); startX=endX; startY=endY; }
//橡皮擦功能函数,这里橡皮惨的功能是删除点击位置所存在的图形对象 function delete_picture(){ cxt.clearRect(0,0,canvas.width,canvas.height); // 清除画布 var list =new Array();// 用list记录需要删除的对象的下标 var current_size = cxt.lineWidth;// 用current_size记录当前的lineWidth for( var j=0 in shapes){ var isPointIn = -1;// 标志该点是否存在当前对象中 var Error = judgeError(shapes[j].size); switch(shapes[j].Shape){ case 1: // 直线 //判断点到直线的距离 var a=shapes[j].endy-shapes[j].starty; var b=shapes[j].startx-shapes[j].endx; var c=-shapes[j].endy*shapes[j].startx+shapes[j].endx*shapes[j].starty; var distance=Math.pow((a*startX+b*startY+c),2)/(Math.pow(a,2)+Math.pow(b,2)); //如果该距离小于2,则视为该点在直线上,删除该对象,否则画出该直线 if(distance<(Error*Error)){ isPointIn = 1; break; } isPointIn = 0; break; case 2:// 圆 var x1=shapes[j].startx,y1=shapes[j].starty,x2=shapes[j].endx,y2=shapes[j].endy; var radius=Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)); cxt.arc(shapes[j].startx,shapes[j].starty,radius,0,Math.PI*2,true); // 判断该点到圆心的距离,与半径进行比较 var distance = Math.sqrt(Math.pow((x1-startX),2)+Math.pow((y1-startY),2)); if(distance<=radius+Error && distance>=radius-Error){ isPointIn = 1; break; } isPointIn = 0; break; case 3://矩形 // 判断该点是否在矩形边上,在则删除该对象,记录下标,否则画出该矩形 var y1 = Math.max(shapes[j].endy,shapes[j].starty); var y2 = Math.min(shapes[j].endy,shapes[j].starty); var x1 = Math.max(shapes[j].startx,shapes[j].endx); var x2 = Math.min(shapes[j].endx,shapes[j].startx); if((x1<=startX+Error && x1>=startX-Error)||(x2<=startX+Error && x2>=startX-Error)){ if(startY>=y2-Error&&startY<=y1+Error){ isPointIn = 1; break; } } if((y1<=startY+Error&&y1>=startY-Error)||(y2<=startY+Error&&y2>=startY-Error)){ if(startX>=x2-Error&&startX<=x1+Error){ isPointIn = 1; break; } } isPointIn = 0; break; case 4: cxt.beginPath(); var k; //依次取出任意线轨迹中的相邻两点,并且以这两点为对角顶点,做矩形 for(k=0;k<shapes[j].x.length-1;k++){ var y1 = Math.max(shapes[j].y[k],shapes[j].y[k+1]); var y2 = Math.min(shapes[j].y[k],shapes[j].y[k+1]); var x1 = Math.max(shapes[j].x[k],shapes[j].x[k+1]); var x2 = Math.min(shapes[j].x[k],shapes[j].x[k+1]); cxt.rect(shapes[j].x[k],shapes[j].y[k],shapes[j].x[k+1] -shapes[j].x[k],shapes[j].y[k+1]-shapes[j].y[k]); //如果该点在这个矩形中,则视为该点在这个对象上,删除对象 if(startX<=x1&&startX>=x2&&startY<=y1&&startY>=y2){ k=-1; break; } if(startX-Error<x1&&startX+Error>x2&&startY-Error<y1&&startY+Error>y2){ k=-1; break; } } if(k==-1){ cxt.closePath(); list.push(j); break; } //该点不在对象上,设置当前画布属性与该对象一致,画出该任意线 else{ cxt.lineWidth = shapes[j].size; cxt.strokeStyle = shapes[j].color; for(k=0;k<shapes[j].x.length-1;k++){ cxt.beginPath(); cxt.moveTo(shapes[j].x[k],shapes[j].y[k]); cxt.lineTo(shapes[j].x[k+1],shapes[j].y[k+1]); cxt.stroke(); cxt.closePath(); } } } //如果该图形不是任意线,且该点不在对象上,设置当前画布属性与该对象一致,画出该图形 if(isPointIn==0&&shapes[j].Shape!=4){ cxt.lineWidth = shapes[j].size; cxt.strokeStyle = shapes[j].color; draw_picture(shapes[j].Shape,shapes[j].startx,shapes[j]. ae8e starty,shapes[j].endx,shapes[j].endy); } if(isPointIn ==1){ list.push(j); } } //删除该点所经过的对象 for(var k=0;k<list.length;k++){ var a= list[k]-k; shapes.splice(a,1); } //恢复当前画布属性到使用橡皮擦之前 cxt.strokeStyle = document.getElementById("color").value; cxt.lineWidth = current_size; }
//判断当前画笔粗细,来决定橡皮擦的误差 function judgeError(num){ switch(num){ case 1: return 2; case 3: return 2; case 5: return 3; case 10: return 4; case 15: return 8; case 20: return 11; } }
//清除画布 function clear(){ // 提示该操作不可逆 var reminder=confirm("The operation is irreversible!"); // 如果确认要清除,初始化界面 if(reminder==true){ cxt.clearRect(0,0,canvas.width,canvas.height); endX=null; shapes =[]; } }
//设置笔画粗细 function line_Width(new_width){ cxt.lineWidth = new_width; }
//保存当前画布 function reserve(){ //清空localstorage localStorage.clear(); //把当前对象保存到localstorage for (var j=0 in shapes){ var json = JSON.stringify(shapes[j]); localStorage.setItem(j.toString(),json); } }
//打开之前保存的画布 function open(){ //清空画布,清空对象 cxt.clearRect(0,0,canvas.width,canvas.height); shapes=[]; //把locastorag的对象添加到当前的对象组 for(var j=0;j<localStorage.length;j++){ var json = localStorage.getItem(j.toString()); shapes[j] = JSON.parse(json); } // 在画布上输出这些对象 for( var j=0 in localStorage){ cxt.strokeStyle = shapes[j].color; cxt.lineWidth = shapes[j].size; draw_picture(shapes[j].Shape,shapes[j].startx,shapes[j].starty,shapes[j].endx,shapes[j].endy); } }
//菜单栏的响应式设计 document.getElementById("color").onchange=function(){cxt.strokeStyle=this.value}; var x = document.getElementsByName("shape"); // 用shape_click记录当前被选中的按钮,默认为直线,直线的背景设为pink var shape_click=0; x[0].style.background = "pink"; for(var j=0;j<x.length;j++){ var select_shape = j; //当鼠标移到图形选项上时,背景色变成蓝色 x[j].onmouseover=(function(select_shape){ return function(){ var Select = select_shape; if(shape_click!= Select) this.style.background="skyblue"; } })(select_shape); //当鼠标离开时,恢复原来的背景色 x[j].onmouseout = (function(select_shape){ var Select = select_shape; return function(){ if(shape_click!=Select) this.style.background = "black"; } })(select_shape); //当选中该图形选项时,背景色变为粉色 x[j].onclick = (function(select_shape){ var Select = select_shape; return function(){ recover(shape_click); shape_click = Select; this.style.background = "pink"; } })(select_shape); }
//当图形选项改变时,恢复上一个被选中选项的背景色 function recover(shape_num){ document.getElementsByName("shape")[shape_num].style.background ="black"; } Line.addEventListener("click",line,false); Circle.addEventListener("click",circle,false); Rectangle.addEventListener("click",rectangle,false); Pencil.addEventListener("click",pencil,false); Rubber.addEventListener("click",rubber,false); Clear.addEventListener("click",clear,false); Reserve.addEventListener("click",reserve,false); Open.addEventListener("click",open,false); canvas.addEventListener("mousedown",StartPos,false); myCans.addEventListener("mousedown",Mousedown,false); canvas.addEventListener("mouseout",MouseOut,false); myCans.addEventListener("mouseup",Mouseup,false); myCans.addEventListener("mousemove",EndPos,false); myCans.addEventListener("mousemove",draw,false);
html:
<body>
<div id="myCans" class="mycans" >
<br><br>
<form name="form1">
<center>
<div class="black" >
<center>
<span name="shape" id="Line" > Line</span><!--
--><span name="shape" id="Circle" >Circle</span><!--
--><span name="shape" id="Rectangle">Rectangle</span><!--
--><span name="shape" id="Pencil">Pencil</span><!--
--><span name="shape" id="Rubber">Rubber</span>
</center>
</div>
<br>
<center>
<input type="button" value="open" id="Open">
<input type="button" value="Save" id="Reserve">
<input type="color" id="color" >
<select id="linewidth" name="line_width" onchange="line_Width(form1.line_width.options[selectedIndex].value)">
<option value="1" slected="slected">1px</option>
<option value="3" >3px</option>
<option value="5" >5px</option>
<option value="10" >10px</option>
<option value="15" >15px</option>
<option value="20" >20px</option>
</select>
<input type="button" value="clear" id="Clear" >
</center>
</center>
</form>
<br><br>
<center>
<canvas id="cans" width="1300" height="500"></canvas>
</center>
</div>
</body>
css:
.black{
background:black;
padding:8px;
width:500px;
color:white;
}
canvas{
background: white;
}
.mycans{
height:758px;
background: black;
}
body{
margin:0;
background: black;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
span{
display:inline-block;
width:80px;
cursor:pointer;
}
相关文章推荐
- 基于HTML5 Canvas和jQuery 的画图工具的实现
- 基于HTML5 Canvas和jQuery 的画图工具的实现
- 基于HTML5 Canvas和jQuery 的画图工具的实现
- 基于HTML5 Canvas和jQuery的画图工具的实现
- 基于html5 canvas和js实现的水果忍者网页版
- [js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具)
- js+html5实现canvas绘制椭圆形图案的方法
- HTML5 Canvas实现web画图之自由绘制矩形
- html5 canvas结合js实现的非常酷的ascii animation动画特效
- 玩转HTML5移动页面_非常实用的css\js\图片优化等工具
- JS实现简单的Canvas画图实例
- html5 canvas结合js实现的非常酷的ascii animation动画特效
- Html5 Canvas+Javascript实现一个简单画图程序(三)
- node.js 和 HTML5-Canvas 结合实现截图上传交互
- JS实现简单的Canvas画图实例
- html5 canvas 实现简单的画图
- Html5系列(十二)canvas-js贝塞尔曲线代码在线生成工具
- Html5 Canvas+Javascript实现一个简单画图程序(二)
- Canvas实现画图工具
- 数据可视化的实现技术和工具比较(HTML5 canvas(Echart)、SVG、webGL等等)