canvas 中的圖形事件判斷
阿新 • • 發佈:2018-11-15
瞭解canvas這個標籤後,會發現在一個canvas類似一個img圖片,在canvas中繪製的圖形都是一個整體,所有的事件也都是發生在這一個標籤上,沒有辦法直接判斷事件是發生在canvas中的某個圖形上。但是通過canvas中的路徑的概念可以解決這個問題。
關鍵:通過路徑來繪製圖形,用每一個圖形是一個路徑,事件繫結在canvas標籤上,獲得事件的發生的x,y座標。再通過 isPointInPath(),來判斷點(x,y)是否在路徑內,需要注意的是isPointInPath()只對當前路徑(currentPath)有效,並且經測試發現,只對當前路徑的第一個子路徑有效(subPath,一個currentPath可以有多個subPath)。關於路徑的詳細解釋可以看看canvas的api文件。
具體的判斷就是,當事件觸發時,對canvas中的內容進行重繪,每重回一個路徑中的圖形,用 isPointInPath()判斷一次,如果在路徑內,執行相應的操作。
如下面的例子,可以拖動一個canvas標籤中繪製的多個圓中的任一個。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <script type="text/javascript"> var list=[]; var currentC; var _e={}; var cricle = function(x,y,r){ this.x=x; this.y=y; this.r=r; this.isCurrent=false; this.drawC=function(ctx,x,y){ ctx.save(); ctx.beginPath(); ctx.moveTo(this.x,this.y-this.r); ctx.arc(this.x,this.y,this.r,2*Math.PI,0,true); if ((x && y && ctx.isPointInPath(x, y) && !currentC )||this.isCurrent) { ctx.fillStyle = '#ff0000'; currentC=this; this.isCurrent=true; }else{ ctx.fillStyle = '#999999'; } ctx.fill(); } } function draw(){ var canvas = document.getElementById('tutorial'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); for(var i=0;i<10;i++){ var c=new cricle(20*i,20*i,5*i); c.drawC(ctx); list.push(c); } } } function reDraw(e){ e=e||event; var canvas = document.getElementById('tutorial'); var x = e.clientX - canvas.offsetLeft; var y = e.clientY - canvas.offsetTop; canvas.width = canvas.width; if (canvas.getContext){ var ctx = canvas.getContext('2d'); for(var i=0;i<list.length;i++){ var c=list[i]; c.drawC(ctx,x,y); } } } function show(e){ e=e||event; var canvas = document.getElementById('tutorial'); var ctx = canvas.getContext('2d'); var x = e.clientX - canvas.offsetLeft; var y = e.clientY - canvas.offsetTop; if(currentC){ currentC.x=parseInt(x+(x-currentC.x)/5); currentC.y=parseInt(y+(y-currentC.y)/5); } _e=e; } window.onload=function(){ var canvas = document.getElementById('tutorial'); draw(); canvas.onmousedown=function(e){ e=e||event; var x = e.clientX - canvas.offsetLeft; var y = e.clientY - canvas.offsetTop; if(currentC) currentC.isCurrent=false; currentC=null; reDraw(e); _e=e; var showTimer=setInterval(function(e){ reDraw(e); },10,_e); canvas.onmousemove=show; document.onmouseup=function(){ if(currentC) currentC.isCurrent=false; currentC=null; canvas.onmousemove=null; clearInterval(showTimer); } } } </script> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body style="background:#eeeeee;"> <div style="background:#0f0;width:100px;height:100px;position:absolute;left:100px;top:100px;z-index:1;" onclick="alert(1);"></div> <canvas id="tutorial" width="1000" height="550" style="z-index:100;display:block;position:absolute;"></canvas> </body> <script> </script> </html>