1、 如何根據鼠標位置獲取canvas上對應位置的x,y。
2、 canvas的圖糊了,設置寬和高的方式不對。
3、鼠標繪圖代碼
之前聽說過canvas這個元素,但是實際上並沒有深入了解過。不過日前有個項目一是使用canvas顯示dicom格式的醫療影像,一是利用canvas元素生成圖像壓縮包,將之前對canvas隱隱約約的好奇心被無限放大,那就嘗試做一個用鼠標繪制圖像的畫布吧。這不難,網上一搜都是教程,然而……很多事情好像並不像想象的美好。
要做的很簡單,mousedown的時候設置開始作畫的標簽,開始作畫后就開始捕捉mousemove的軌跡來作畫,mouseup的時候停止(后面附完整代碼)。
1、 如何根據鼠標位置獲取canvas上對應位置的x,y
然而,無論使用offsetX,offsetY還是clientX-canvas.width,clientY-canvas.height都獲取不到對應的x,y,我甚至找不到鼠標落下的點和鼠標位置的任何關系。我知道這應該跟canvas的拉伸有關,之前就有遇到過需要調整canvas大小后圖像出問題的問題,然而網上很多代碼都是直接使用這兩個值,都是大忽悠,但是我對canvas沒有一點了解,完全不知道如何轉換,幸虧后來找到合適的方法。
var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); //********嘗試獲得對應位置的x,y c.addEventListener('click',function(event){ var event = event||window.event; var bbox = c.getBoundingClientRect(); var x = event.offsetX * (c.width / bbox.width); var y = event.offsetY * (c.height / bbox.height);
ctx.beginPath(); ctx.arc(x,y,10,0,2*Math.PI); ctx.stroke(); });
2、 圖糊了,如何設置寬和高。
一開始我是把canvas當作普通元素處理,那么設置寬和高不就是,:
#myCanvas{
width:800px;
height:600px;
}
然后圖糊了,下圖不太明顯,但是在網頁中的確不能看。
然后我就知道了canvas要設置的是像素值,不是簡單的寬和高,設置方法有下面兩種:
<1>行內設置屬性
<canvas id="myCanvas" width="800" height="500"></canvas>
<2>js設置屬性
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
c.width=800;
c.height=600;
3、鼠標繪圖代碼
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"/> <script src='js/jquery-3.3.1.min.js'></script> <style> body{ background:black; text-align:center; } #myCanvas{ margin:10px auto; background:white; } </style> </head> <body> <canvas id="myCanvas"></canvas> <script type="text/javascript"> $(document).ready(function(){ var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); c.width=800; c.height=600; var tempx = -1, tempy = -1; function painting(event){ var event = event||window.event; /*獲取寬和高*/ var bbox = c.getBoundingClientRect(); var x = event.offsetX * (c.width / bbox.width); var y = event.offsetY * (c.height / bbox.height); /*畫線*/ ctx.beginPath(); ctx.moveTo(tempx, tempy); ctx.lineTo(x, y); ctx.stroke(); ctx.closePath(); /*存值*/ tempx = x; tempy = y; } c.onmousedown = function(event){ var event = event||window.event; var bbox = c.getBoundingClientRect(); /*存初值*/ tempx=event.offsetX * (c.width / bbox.width); tempy=event.offsetY * (c.height / bbox.height); /*開始作畫*/ c.onmousemove = painting; }; c.onmouseup = function(event){ c.onmousemove = null; }; }); /********* **********/ </script> </body> </html>
還可以做:
1、shift繪制圖像直線,根據shiftKey繪制,下有實現,不過不太靈敏,不夠符合理想的狀態
2、橡皮擦,和清除全部圖像,使用
context.clearRect(0, 0, canvas.width, canvas.height);
3、畫圓畫矩形,拖動會更改大小,這個涉及的細節更多了
圓形:
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();
矩形:
ctx.fillRect(0,0,150,75);
4、設置顏色選擇、更改畫筆粗細(可以使用正方形代替線,不過好像不太對勁)
ctx.fillStyle="#FF0000";
5、添加文字
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);
6、歷史畫筆,返回恢復
保存好進行過的操作
7、保存下載圖片
下文再進行討論
這些事件要考慮的細節問題太多,就懶得寫代碼調整嘗試了,下面是添加了shift操作並做了一些優化的代碼

<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"/> <script src='js/jquery-3.3.1.min.js'></script> <style> body{ background:black; text-align:center; } #myCanvas{ margin:10px auto; background:white; } </style> </head> <body> <canvas id="myCanvas"></canvas> <script type="text/javascript"> $(document).ready(function(){ var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); c.width=800; c.height=600; var tempx = -1, tempy = -1; var shiftline=-1.0,shiftx=-1,shifty=-1;/*shift畫直線,因為x,y太快捕捉不到角度,另起一個shiftx,shifty來儲存*/ //*******用鼠標畫線 function paintingLine(event){ var event = event||window.event; //*******獲取寬和高 var bbox = c.getBoundingClientRect(); var x = event.offsetX * (c.width / bbox.width); var y = event.offsetY * (c.height / bbox.height); //********shift var shiftKey = event.shiftKey; if(shiftKey==true){ if(shiftline==-1.0){ if(shiftx==-1){ shiftx = tempx; shifty = tempy; } if(timer==3){ if(x-shiftx==0){ shiftline = -2.0; } else{ shiftline = (y-shifty)*1.0/(x-shiftx); } } timer = timer+1; } else{ if(shiftline==-2.0){ x = 0; } else{ y = shifty+(x-shiftx) * shiftline; } } } else{ shiftline = -1.0; shiftx = -1; shifty = -1; timer = 0; } //**********畫線 ctx.beginPath(); ctx.moveTo(tempx, tempy); ctx.lineTo(x, y); ctx.stroke(); ctx.closePath(); //**********存值 tempx = x; tempy = y; } //******按下鼠標開始畫線 c.onmousedown = function(event){ var event = event||window.event; var bbox = c.getBoundingClientRect(); //*********存初值 tempx=event.offsetX * (c.width / bbox.width); tempy=event.offsetY * (c.height / bbox.height); //*******開始作畫 c.onmousemove = paintingLine; }; //**********松開鼠標鍵停止作畫 c.onmouseup = function(event){ c.onmousemove = null; shiftline = -1.0; shiftx = -1; shifty = -1; timer = 0; }; //**********離開界面停止作畫 c.onmouseout = function(event){ c.onmousemove = null; shiftline = -1.0; shiftx = -1; shifty = -1; timer = 0; }; }); /********* 還可以做: 1、shift繪制圖像直線,根據shiftKey繪制,上面有實現,不過不太靈敏,不夠符合理想的狀態 2、橡皮擦,和清除全部圖像,使用 context.clearRect(0, 0, canvas.width, canvas.height); 3、畫圓畫矩形,拖動會更改大小,這個涉及的細節更多了 圓形: ctx.beginPath(); ctx.arc(95,50,40,0,2*Math.PI); ctx.stroke(); 矩形: ctx.fillRect(0,0,150,75); 4、設置顏色選擇、更改畫筆粗細(可以使用正方形代替線,不過好像不太對勁) ctx.fillStyle="#FF0000"; 5、添加文字 ctx.font="30px Arial"; ctx.fillText("Hello World",10,50); 6、歷史畫筆,返回恢復 保存好進行過的操作 7、保存下載圖片 下文再進行討論 這些事件要考慮的細節問題太多,就懶得寫代碼調整嘗試了 **********/ </script> </body> </html>
參考:
獲取鼠標位置和canvas的對應xy:https://blog.csdn.net/u010513756/article/details/47363743