【题目】【8天】canvas画板
canvas
画板,比较简易,目前还有很多bug
1、手机端上下会晃动
2、下载按钮微信上没法用
3、下载后背景色是透明
4、切换成橡皮擦后,需要先点铅笔才能绘画,不能直接点颜色
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <style> ul,ol{list-style:none;} *{margin: 0;padding: 0;} body{overflow: hidden;} .icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } .canvas{ background: white; display: block; position:fixed; top:0; left:0; } #actions{ position: fixed; top: 0; left:5px; } #actions svg{ width: 1.5em; height: 2em; transition: all 0.3s; margin: 10px; } #actions .action{ fill:red; transform: scale(1.2); } .colors{ position: fixed; top:41px; left:12px; } .color{ transform: scale(1.2); } .colors > li{ width:20px; height:20px; margin:10px 0; border-radius: 50%; } .colors > li.black{ background: black; } .colors > li.red{ background: red; } .colors > li.green{ background: green; } .colors > li.blue{ background: blue; } </style> </head> <body> <canvas id="xxx" class="canvas"></canvas> <div id="actions"> <svg id="pen" class="icon action" aria-hidden="true"> <use xlink:href="#icon-pen"></use> </svg> <svg id="eraser" class="icon" aria-hidden="true"> <use xlink:href="#icon-eraser"></use> </svg> <svg id="clear" class="icon" aria-hidden="true"> <use xlink:href="#icon-custom-clear"></use> </svg> <svg id="download" class="icon" aria-hidden="true"> <use xlink:href="#icon-download1"></use> </svg> <!--<button id="eraser">橡皮擦</button>--> <!--<button id="brush">画笔</button>--> </div> <ol class="colors"> <li id="black" class="black color"></li> <li id="red" class="red"></li> <li id="green" class="green"></li> <li id="blue" class="blue"></li> </ol> <!--<div id="canvas"></div>--> <script src="//at.alicdn.com/t/font_663139_nbdaue5y67gmn29.js"></script> <script src="js/canvas3.js"></script> </body> </html>
JS代码
<script> var yyy = document.getElementById('xxx'); var ctx = yyy.getContext("2d"); autoCanvasSize(yyy); listenToUser(yyy); //是否使用橡皮擦 var eraserEnable = false; eraser.onclick = function () { eraserEnable = true; eraser.classList.add('action'); pen.classList.remove('action'); }; pen.onclick = function () { eraserEnable = false; pen.classList.add('action'); eraser.classList.remove('action'); }; red.onclick = function () { ctx.fillStyle = "red"; ctx.strokeStyle = "red"; red.classList.add('color'); green.classList.remove('color'); blue.classList.remove('color'); black.classList.remove('color'); }; green.onclick = function () { ctx.fillStyle = "green"; ctx.strokeStyle = "green"; green.classList.add('color'); red.classList.remove('color'); blue.classList.remove('color'); black.classList.remove('color'); }; blue.onclick = function () { ctx.fillStyle = "blue"; ctx.strokeStyle = "blue"; blue.classList.add('color'); red.classList.remove('color'); green.classList.remove('color'); black.classList.remove('color'); }; black.onclick = function () { ctx.fillStyle = "black"; ctx.strokeStyle = "black"; black.classList.add('color'); red.classList.remove('color'); blue.classList.remove('color'); green.classList.remove('color'); }; clear.onclick = function () { ctx.clearRect(0,0,yyy.width,yyy.height); }; download.onclick = function () { var url = yyy.toDataURL("image/png"); var a = document.createElement('a'); document.body.appendChild(a); a.href = url; a.download = "我的画"; a.target = "_blank"; a.click(); }; //设置画板 function autoCanvasSize(canvas) { function setCanvasSize(){ var pageWidth = document.documentElement.clientWidth; // 获取屏幕宽度 var pageHeight = document.documentElement.clientHeight; //获取屏幕高度 canvas.width = pageWidth; //画板宽等于屏幕宽度 canvas.height = pageHeight; //画板高等于屏幕高度 } setCanvasSize(); window.onresize = function ( ){ //改变窗口大小 setCanvasSize(); }; } //监听用户鼠标事件 function listenToUser(canvas) { var painting = false; var lastPoint = {}; if(document.body.ontouchstart !== undefined){ canvas.ontouchstart = function (aaa) { console.log(aaa); var x = aaa.touches[0].clientX; //console.log打印出aaa,找到里面的touches(多点触控),第一个用touches[0] var y = aaa.touches[0].clientY; painting = true; if(eraserEnable){ ctx.clearRect(x-5,y-5,10,10); }else{ lastPoint = {"x":x,"y":y}; //在每次动的时候把当前点和动的点连成一条线 drawCircle(x,y,4); } }; canvas.ontouchmove = function (aaa) { var x = aaa.touches[0].clientX; var y = aaa.touches[0].clientY; var newPoint = {x:x,y:y}; if(!painting){return;} if(eraserEnable){ ctx.clearRect(x-5,y-5,10,10); }else{ drawCircle(x,y,4); drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y,10); lastPoint = newPoint; //实时更新上一个点的坐标,不然都和第一个点连接了 } }; canvas.ontouchend = function () { painting = false; } }else{ //鼠标按下 canvas.onmousedown = function (aaa) { var x = aaa.clientX; var y = aaa.clientY; painting = true; if(eraserEnable){ ctx.clearRect(x-5,y-5,10,10); }else{ lastPoint = {"x":x,"y":y}; //在每次动的时候把当前点和动的点连成一条线 drawCircle(x,y,4); } }; //鼠标移动 canvas.onmousemove = function (aaa) { var x = aaa.clientX; var y = aaa.clientY; var newPoint = {x:x,y:y}; if(!painting){return;} if(eraserEnable){ ctx.clearRect(x-5,y-5,10,10); }else{ drawCircle(x,y,4); drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y,10); lastPoint = newPoint; //实时更新上一个点的坐标,不然都和第一个点连接了 } }; //松开鼠标 canvas.onmouseup = function () { painting = false; }; } } //画圆 function drawCircle(x,y,radius){ ctx.beginPath(); ctx.arc(x,y,radius,0,Math.PI*2); ctx.fill() } //连线 function drawLine(x1,y1,x2,y2,lineWidth){ ctx.beginPath(); ctx.moveTo(x1,y1); ctx.lineWidth = lineWidth; ctx.lineTo(x2,y2); ctx.stroke(); ctx.closePath(); } </script>
总结:
1、按下鼠标和移动鼠标后它们中间会有空隙,解决方法:用线连接鼠标移动前后的两点。lasePoint
和newPoint
2、painting = false
监听用户是否在绘画。true
再绘画false
不在绘画。
3、eraserEnable = false;
监测用户是在使用橡皮檫,true
是在使用橡皮擦,停止使用铅笔。
4、判断用户是使用pc还是手机,需要监测是否有touch
事件,如果有,首先使用touch
事件;在pc端document.body.ontouchstart === undefined
,在移动端是null
,只要不等于undefined
就可以确定是移动端。
5、状态切换,不直接修改css里面内容,通过js切换class来实现状态切换。比如:上面橡皮擦和铅笔的切换。
6、使用x.className = 'active'
,class
会变为active
;使用x.classList.add('active')
,class
后面会增加一个属性值active
。
7、document.documentElement.clientWidth
的作用是获取document
宽度(也就是viewport
宽度)
8、移动端支持多点触控,所以要获取clientX
需要加上touches[0]
,表示touch
第一个值
相关推荐
大地飞鸿 2020-11-12
星星有所不知 2020-10-12
jinxiutong 2020-07-26
MIKUScallion 2020-07-05
songfens 2020-07-05
songfens 2020-06-11
songfens 2020-06-08
northwindx 2020-05-31
northwindx 2020-05-31
northwindx 2020-05-27
northwindx 2020-05-25
MIKUScallion 2020-05-25
jinxiutong 2020-05-10
xdyangxiaoromg 2020-05-10
大地飞鸿 2020-05-06
northwindx 2020-04-25