前言
本篇的內容主要包括:
- 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 { width: 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{ width: 1.5em; height: 1.5em; transition: all 0.3s; margin: 4px; } .colors{ position: fixed; top: 70px; left: 10px; } .colors ol li{ width: 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; width: 16px; height: 0; } .sizes ol li#thin2{ border-top: 4px solid black; width: 16px; height: 0; } .sizes ol li#thick{ border-top: 6px solid black; width: 16px; height: 0; } .sizes ol li#thick2{ border-top: 8px solid black; width: 16px; height: 0; }