1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > html5 (canvas) +css+js 实现画图工具

html5 (canvas) +css+js 实现画图工具

时间:2020-03-12 07:31:17

相关推荐

html5 (canvas) +css+js 实现画图工具

效果图:

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=1if(mouseout == 1)mousedown=1;}

// 鼠标移出了画布,mouseout=1function 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记录当前的lineWidthfor( 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].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(){//清空localstoragelocalStorage.clear();//把当前对象保存到localstoragefor (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").οnchange=function(){cxt.strokeStyle=this.value};var x = document.getElementsByName("shape");// 用shape_click记录当前被选中的按钮,默认为直线,直线的背景设为pinkvar shape_click=0;x[0].style.background = "pink";for(var j=0;j<x.length;j++){var select_shape = j;//当鼠标移到图形选项上时,背景色变成蓝色x[j].οnmοuseοver=(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" οnchange="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;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。