前言
本篇的内容主要包括:
- canvas标签简介
- 画板的功能简介
- 画板的JS部分
(包括:1、获取画布 2、使画板全屏幕显示且自适应 3、如何绘制直线 4、绘画时的三种状态(鼠标点击、移动、离开)5、画笔功能(画笔颜色、画笔粗细) 6、橡皮擦功能 7、一键清除功能 8、一键下载功能) - 画板的HTML部分
- 画板的CSS部分
正文
1 canvas标签简介
<canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。 <canvas> 看起来和 <img> 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。实际上,<canvas> 标签只有两个属性—— width和height。这些都是可选的,并且同样利用 DOM properties 来设置。当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。该元素可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果CSS的尺寸与初始画布的比例不一致,它会出现扭曲。 //注意:canvas不能使用CSS来设置宽高
2 画板的功能简介
- 画板的主要功能有:1 画笔功能(多种画笔颜色、画笔粗细),2 橡皮擦功能 ,3 一键清除功能 , 4 一键保存功能。
- 画板效果如下图所示,
3 画板的JS部分
-
获取画布
//1 获取画布 var canvasname=document.getElementById("canvas"); if(canvasname.getContext){ var context=canvasname.getContext('2d'); }
-
使画板全屏幕显示且自适应
//2 全屏幕画布,ps:最好不要用css,会出bug setCanvasSize(); window.onresize=function(){ setCanvasSize(); }; //这句的用处是在用户拖动屏幕的时候,宽度会重新全屏幕。但是会有刚刚画的东西丢失的bug
-
绘画时的三种状态(鼠标点击、移动、离开)
//3 特性检测,检测设备是否可触碰。 lisenToUser(canvas) function lisenToUser(canvas){ //使用document.body.ontouchstart!==undefined或者in方法ontouchstart in document.body都行。 if(document.body.ontouchstart!==undefined){ lisenToTouch(canvas); }else{ lisenToMouse(canvas); } } //监听触摸事件的函数 function lisenToTouch(canvas){ var lastPoint={x:undefined,y:undefined}; var usingBrush=false; canvas.ontouchstart=function(aaa){ console.log(aaa) //打印出touchevent var x=aaa.touches[0].clientX; //因为clientX/clientY的在Touch event的touchs下面的0数组中,所以。。。 var y=aaa.touches[0].clientY; console.log(x,y) //打印出坐标 if(usingEraser){ context.clearRect(x-10,y-10,20,20) //橡皮擦功能 }else{ usingBrush=true; lastPoint={"x":x,"y":y}; //drawCircle(x,y,3); } }; canvas.ontouchmove=function(aaa){ var x=aaa.touches[0].clientX; var y=aaa.touches[0].clientY; if(usingEraser){ context.clearRect(x-10,y-10,20,20) }else{ if (usingBrush){ var newPoint={"x":x,"y":y}; //drawCircle(x,y,3); drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y); lastPoint=newPoint; } } }; canvas.ontouchup=function(){ usingBrush=false; usingEraser=false; }; } //监听鼠标事件的函数 function lisenToMouse(canvas){ var lastPoint={x:undefined,y:undefined}; var usingBrush=false; canvas.onmousedown=function(aaa){ var x=aaa.clientX; var y=aaa.clientY; if(usingEraser){ context.clearRect(x-10,y-10,20,20) }else{ usingBrush=true; lastPoint={"x":x,"y":y}; //drawCircle(x,y,3); } }; canvas.onmousemove=function(aaa){ var x=aaa.clientX; var y=aaa.clientY; if(usingEraser){ context.clearRect(x-10,y-10,20,20) }else{ if (usingBrush){ var newPoint={"x":x,"y":y}; //drawCircle(x,y,3); drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y); lastPoint=newPoint; } } }; canvas.onmouseup=function(){ usingBrush=false; usingEraser=false; }; }
-
如何绘制直线
//画一个直线 function drawLine(x1,y1,x2,y2){ context.beginPath(); context.moveTo(x1,y1); context.lineTo(x2,y2); context.stroke(); //画直线不能用fill() context.closePath(); context.lineWidth=lineWidth; //此处将线宽赋值给一个变量时为了使为了方便设置画笔宽度 }
一条直线的作用是生成画笔的功能。配合鼠标/触摸的点击和移动的坐标,每次鼠标移动时保存上次的坐标并将上次的坐标和移动到的新的坐标相连接,用户在使用鼠标/手机触摸在页面上移动时会随着用户的移动形成线条。 -
画笔功能(画笔颜色、画笔粗细)
//4 画笔功能 brush.onclick=function(){ usingEraser=false; //如果用户在使用画笔,则关闭橡皮擦功能 }
//有颜色的画笔,添加几个有颜色的按钮 red.onclick=function(){ context.strokeStyle="red"; context.fillStyle="red"; } yellow.onclick=function(){ context.strokeStyle="yellow"; context.fillStyle="yellow"; } green.onclick=function(){ context.strokeStyle="green"; context.fillStyle="green"; } blue.onclick=function(){ context.strokeStyle="blue"; context.fillStyle="blue"; } //画笔的粗细 var lineWidth; thin.onclick=function(){ lineWidth=2; } thin2.onclick=function(){ lineWidth=4; } thick.onclick=function(){ lineWidth=6; } thick2.onclick=function(){ lineWidth=8; } -
橡皮擦功能
//5 橡皮擦功能
eraser.onclick=function(){ usingEraser=true; }
实现橡皮擦的功能:在鼠标/触摸点击和移动的时候检测用户是否在使用eraser按钮,如果在使用,使用如下语句擦除所画内容:context.clearRect(x-10,y-10,20,20),如用户未使用橡皮擦,则执行画笔功能。 -
一键清除功能
//6 一键清除 clear.onclick=function(){ context.clearRect(0,0,canvas.width,canvas.height); //清除整个画布的内容即可实现一键清除 }
-
一键下载功能
//7 一键下载 download.onclick = function(){ var url = canvas.toDataURL('image/png'); var a = document.createElement('a'); document.body.appendChild(a); a.href = url; a.download = 'my pic'; a.target="_blank" a.click(); eraser.classList.remove("activesvg") brush.classList.remove("activesvg") clear.classList.remove("activesvg") download.classList.add("activesvg") }
4 画板的HTML部分
<!DOCTYPE html> <html lang="zh-Hans"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <!--加上"user-scalable=no/"会使手机真正自适应,使页面到手机上时字体不会自动缩放。"device-width"设备宽度--> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>myCanvas</title> <link rel="stylesheet" href="./style.css"> <script src="//at.alicdn.com/t/font_650559_geuacjzbo98p8pvi.js"></script> </head> <body> <canvas id="canvas" width="300px" height="300px"></canvas> <!--不要用css添加宽度高度样式,不要用css添加宽度高度样式,不要用css添加宽度高度样式重要的事情说三遍--> <div class="actions" id="actions"> <svg class="icon" aria-hidden="true" id="brush"> <use xlink:href="#icon-pen"></use> </svg> <svg class="icon" aria-hidden="true" id="eraser"> <use xlink:href="#icon-eraser"></use> </svg> <svg class="icon" aria-hidden="true" id="clear"> <use xlink:href="#icon-clear"></use> </svg> <svg class="icon" aria-hidden="true" id="download"> <use xlink:href="#icon-download"></use> </svg> </div> <div class="colors"> <ol> <li id="red"></li> <li id="yellow"></li> <li id="green"></li> <li id="blue"></li> </ol> </div> <div class="sizes"> <ol> <li id="thin"></li> <li id="thin2"></li> <li id="thick"></li> <li id="thick2"></li> </ol> </div> <script src="./main.js"></script> </body> </html>
5 画板的CSS部分
.icon { 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } ol,li{ list-style: none; /*清除无序列表前面的点点*/ } *{ margin: 0; padding: 0; /*kill掉元素的外边距和内边距*/ } body{ overflow: hidden; /*解决在手机上页面会滚动的bug*/ position: fixed; top: 0; left: 0; } #canvas{ background:rgb(255, 255, 255); display:block; } .actions{ position: fixed; /*使元素脱离文档流,自己重新定位*/ top:0; left:0; padding:20px; } .actions svg{ 1.5em; height: 1.5em; transition: all 0.3s; margin: 4px; } .colors{ position: fixed; top: 70px; left: 10px; } .colors ol li{ 20px; height: 20px; margin: 8px 6px; border-radius: 50%; /*是元素变成一个圆*/ } .colors ol li#red{ background: red; } .colors ol li#yellow{ background: yellow; } .colors ol li#green{ background: green; } .colors ol li#blue{ background: blue; } .sizes{ position: fixed; top: 70px; right: 10px; } .sizes ol li{ margin: 20px 6px; } .sizes ol li#thin{ border-top: 2px solid black; 16px; height: 0; } .sizes ol li#thin2{ border-top: 4px solid black; 16px; height: 0; } .sizes ol li#thick{ border-top: 6px solid black; 16px; height: 0; } .sizes ol li#thick2{ border-top: 8px solid black; 16px; height: 0; }