求助 ,关于canvas画图点击事件

内拉祖睿 2014-01-07 12:51:32
是这样的,我想做一个类似于电影院选座位的效果,用canvas标签画出多个矩形模拟座位,点击可以选中,再次点击可以取消,可以多选,即点击多个图形选中。我的思路是先取得点击事件的坐标,再判断坐标是否在绘制的矩形内。问题是canvas提供的判断坐标的方法isPointInPath只可以判断当前上下文的图形是否覆盖了你的坐标。所以必须要重绘图形,每次重绘一个图形都使用判断方法,如果点击事件坐标在图形覆盖范围内则可以响应事件。但是如果我选完一个再想选第二个的话方法就会 又重新绘制,等于之前选择的又要被重绘,不能够保存。请问大神们有没有好的解决方法呢?
这里贴出源码
<!DOCTYPE html>  
<html>
<head>
<title> Canvas Demo</title>
<!--[if It IE]>
<script type="text/javascript" src="./excanvas.js"></script>
<![endif]-->
<script>
//初始化
window.onload=function() {
var canvas = document.getElementById('myCanvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');

ctx.fillStyle='blue';
// -----------------------------

ctx.beginPath();
ctx.rect(10,10,50,50);
ctx.fill();

ctx.beginPath();
ctx.rect(70,10,50,50);
ctx.fill();

ctx.beginPath();
ctx.rect(130,10,50,50);
ctx.fill();

ctx.beginPath();
ctx.rect(190,10,50,50);
ctx.fill();

ctx.beginPath();
ctx.rect(250,10,50,50);
ctx.fill();

ctx.beginPath();
ctx.rect(310,10,50,50);
ctx.fill();

//----------------------------------------




//添加事件响应
canvas.addEventListener('click', function(e){
p = getEventPosition(e);

reDraw(p,ctx);

}, false);
}
}
//得到点击的坐标
function getEventPosition(ev){
var x, y;
if (ev.layerX || ev.layerX == 0) {
x = ev.layerX;
y = ev.layerY;
}else if (ev.offsetX || ev.offsetX == 0) { // Opera
x = ev.offsetX;
y = ev.offsetY;
}
return {x: x, y: y};
}
//重绘
function reDraw(p,ctx){
arr = [

{x:10, y:10, width:50, height:50},
{x:70, y:10, width:50, height:50},
{x:130, y:10, width:50, height:50},
{x:190, y:10, width:50, height:50},
{x:250, y:10, width:50, height:50},
{x:310, y:10, width:50, height:50},




]

var whichObject = [];
for(var i=0; i < arr.length; i++){
ctx.fillStyle='blue';
ctx.beginPath();
ctx.rect(arr[i].x,arr[i].y, arr[i].width,arr[i].height);
ctx.fill();

if(p && ctx.isPointInPath(p.x, p.y)){
whichObject.push(i);
ctx.fillStyle='red';
ctx.beginPath();
ctx.rect(arr[i].x,arr[i].y, arr[i].width,arr[i].height);
ctx.fill();
}

}

//显示点击了哪个部分
// alert("click:" + whichObject[0]);
}
</script>
</head>
<body>
<div>
<canvas id="myCanvas" width="600" height="600"></canvas>
<br /><br />
</div>
</body>
</html>
...全文
1966 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
wudi久久 2016-05-24
  • 打赏
  • 举报
回复
我晕,这还用canvas? 直接div 不就可以了
叶琳 2014-05-29
  • 打赏
  • 举报
回复
对于规则的图形是可以的,如果我画了一个不规则的图形 。如:for(var i=0;i<7;i++){ ctx.moveTo(320+100*i,40);//起点 ctx.lineTo(400+100*i,40);//370-140直线 ctx.lineTo(430+100*i,20);//340-100/110-240斜线 ctx.lineTo(400+100*i,0); ctx.lineTo(320+100*i,0);//340-100直线 ctx.lineTo(350+100*i,20); ctx.lineTo(320+100*i,40);//100-140/240-110斜线 ctx.fillStyle='#FAC090'; ctx.fill();//绘制轨迹或者填满fill()'#2d89ef' ctx.fillStyle='#2d89ef'; } 似乎坐标获得的有交叉,这该怎么处理呢,谢谢 !
叶琳 2014-05-29
  • 打赏
  • 举报
回复
哦,谢谢,我会了。忘记关闭路劲了
内拉祖睿 2014-01-07
  • 打赏
  • 举报
回复
引用 1 楼 MengYouXuanLv 的回复:

<!DOCTYPE html>  
<html>  
<head>  
<title> Canvas Demo</title>  
<!--[if It IE]>  
 <script type="text/javascript" src="./excanvas.js"></script>  
<![endif]-->  
<script>  
//初始化  
window.onload=function() {   
    var canvas = document.getElementById('myCanvas');   
    if (canvas.getContext){   
        var ctx = canvas.getContext('2d');   
           
        ctx.fillStyle='blue';
    //    -----------------------------
         
        ctx.beginPath();   
        ctx.rect(10,10,50,50);   
        ctx.fill();  
         
    ctx.beginPath();   
        ctx.rect(70,10,50,50);   
        ctx.fill();  
                 
        ctx.beginPath();   
        ctx.rect(130,10,50,50);   
        ctx.fill();
         
    ctx.beginPath();   
        ctx.rect(190,10,50,50);   
        ctx.fill();
         
    ctx.beginPath();   
        ctx.rect(250,10,50,50);   
        ctx.fill();
         
    ctx.beginPath();   
        ctx.rect(310,10,50,50);   
        ctx.fill();
     
    //----------------------------------------      
  
     
           
        
        //添加事件响应   
        canvas.addEventListener('click', function(e){   
            p = getEventPosition(e);  
             
            reDraw(p,ctx);  
             
        }, false);   
    }   
}   
//得到点击的坐标   
function getEventPosition(ev){   
    var x, y;   
    if (ev.layerX || ev.layerX == 0) {   
        x = ev.layerX;   
        y = ev.layerY;   
    }else if (ev.offsetX || ev.offsetX == 0) { // Opera   
        x = ev.offsetX;   
        y = ev.offsetY;   
    }   
    return {x: x, y: y};   
}   
var arr = [             
        {x:10, y:10, width:50, height:50},   
        {x:70, y:10, width:50, height:50},
        {x:130, y:10, width:50, height:50},
		{x:190, y:10, width:50, height:50},
	    {x:250, y:10, width:50, height:50},
		{x:310, y:10, width:50, height:50}                                  
    ];
//重绘   
function reDraw(p,ctx){             
    var whichObject = [];   
    for(var i=0; i < arr.length; i++){                            
          if(p && (arr[i].x + arr[i].width) >= p.x && p.x >= arr[i].x
			&& (arr[i].y + arr[i].height) >= p.y && p.y >= arr[i].y){ 			  
                whichObject.push(i);   
				if(arr[i].selected){
					ctx.fillStyle='blue';
					arr[i].selected = false;
				} else {
					ctx.fillStyle='red';
					arr[i].selected = true;
				}
                ctx.beginPath();   
                ctx.rect(arr[i].x,arr[i].y, arr[i].width,arr[i].height);
                ctx.fill();   
				break;
            }			             
           }                
}    
</script>  
</head>  
<body>  
<div>  
<canvas id="myCanvas" width="600" height="600" style="background:#8D8D8D"></canvas>  
<br /><br />  
</div>  
</body>  
</html>
测试可行,真是太谢谢了,看来用canvas自己提供的isPointInPath方法确实不行
allali 2014-01-07
  • 打赏
  • 举报
回复

<!DOCTYPE html>  
<html>  
<head>  
<title> Canvas Demo</title>  
<!--[if It IE]>  
 <script type="text/javascript" src="./excanvas.js"></script>  
<![endif]-->  
<script>  
//初始化  
window.onload=function() {   
    var canvas = document.getElementById('myCanvas');   
    if (canvas.getContext){   
        var ctx = canvas.getContext('2d');   
           
        ctx.fillStyle='blue';
    //    -----------------------------
         
        ctx.beginPath();   
        ctx.rect(10,10,50,50);   
        ctx.fill();  
         
    ctx.beginPath();   
        ctx.rect(70,10,50,50);   
        ctx.fill();  
                 
        ctx.beginPath();   
        ctx.rect(130,10,50,50);   
        ctx.fill();
         
    ctx.beginPath();   
        ctx.rect(190,10,50,50);   
        ctx.fill();
         
    ctx.beginPath();   
        ctx.rect(250,10,50,50);   
        ctx.fill();
         
    ctx.beginPath();   
        ctx.rect(310,10,50,50);   
        ctx.fill();
     
    //----------------------------------------      
  
     
           
        
        //添加事件响应   
        canvas.addEventListener('click', function(e){   
            p = getEventPosition(e);  
             
            reDraw(p,ctx);  
             
        }, false);   
    }   
}   
//得到点击的坐标   
function getEventPosition(ev){   
    var x, y;   
    if (ev.layerX || ev.layerX == 0) {   
        x = ev.layerX;   
        y = ev.layerY;   
    }else if (ev.offsetX || ev.offsetX == 0) { // Opera   
        x = ev.offsetX;   
        y = ev.offsetY;   
    }   
    return {x: x, y: y};   
}   
var arr = [             
        {x:10, y:10, width:50, height:50},   
        {x:70, y:10, width:50, height:50},
        {x:130, y:10, width:50, height:50},
		{x:190, y:10, width:50, height:50},
	    {x:250, y:10, width:50, height:50},
		{x:310, y:10, width:50, height:50}                                  
    ];
//重绘   
function reDraw(p,ctx){             
    var whichObject = [];   
    for(var i=0; i < arr.length; i++){                            
          if(p && (arr[i].x + arr[i].width) >= p.x && p.x >= arr[i].x
			&& (arr[i].y + arr[i].height) >= p.y && p.y >= arr[i].y){ 			  
                whichObject.push(i);   
				if(arr[i].selected){
					ctx.fillStyle='blue';
					arr[i].selected = false;
				} else {
					ctx.fillStyle='red';
					arr[i].selected = true;
				}
                ctx.beginPath();   
                ctx.rect(arr[i].x,arr[i].y, arr[i].width,arr[i].height);
                ctx.fill();   
				break;
            }			             
           }                
}    
</script>  
</head>  
<body>  
<div>  
<canvas id="myCanvas" width="600" height="600" style="background:#8D8D8D"></canvas>  
<br /><br />  
</div>  
</body>  
</html>

39,087

社区成员

发帖
与我相关
我的任务
社区描述
HTML5是构建Web内容的一种语言描述方式。HTML5是互联网的下一代标准,是构建以及呈现互联网内容的一种语言方式.被认为是互联网的核心技术之一。
社区管理员
  • HTML5社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧