1、首先要做的,是给Canvas元素绑定事件,比如Canvas内部某个图形要绑定点击事件,就需要通过Canvas元素代理该事件:
cvs = document.getElementById('mycanvas');
context = canvas.getContext('2d');
cvs.addEventListener('click', function(e){
p = getEventPosition(e);
reDraw(p,context); //
console.log(p); //在控制台可以打印出来点击的位置
}, false);
2、接下来需要判断事件对象发生的位置,事件对象e的layerX和layerY属性表示Canvas内部坐标系中的坐标。但是这个属性Opera不支持,Safari也打算移除,所以要做一些兼容写法:
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};
}//注:使用上面这个函数,需要给Canvas元素的position设为absolute。
现在有了事件对象的坐标位置,下面就要判断Canvas里的图形,有哪些覆盖了这个坐标。
3、重绘,为了实现循环重绘,所以就要将图形的基本参数事先保存下来:
当点击事件发生时,重绘所有图形,每绘制一个就使用isPointInPath方法,判断事件坐标是否在该图形覆盖范围内。
//重绘
var arr = [
{"x":35,"y":236,"width":64,"height":64},
{"x":175,"y":54,"width":48,"height":47},
{"x":311,"y":270,"width":76,"height":77},
{"x":35,"y":400,"width":85,"height":85},
{"x":230,"y":440,"width":100,"height":100},
// {x:150,y:220,width:98.15,height:92.65}
]
//把原区域声明为数组存起来
var hrefo= ['indexa.html','demo.html','canvas.html','https://www.baidu.com/','http://jquery.cuishifeng.cn/parent.html'] //点击对应区域跳转到相应的页面
var $my_canvas=$("#myCanvas");
var my_canvas=$my_canvas[0];
var context=my_canvas.getContext("2d");
var cvs = $my_canvas
function reDraw(p){
var who = [];
context.clearRect(0, 0, cvs.width, cvs.height);
arr.forEach(function(v, i){
context.beginPath();
context.rect(v.x, v.y, v.width, v.height);
//context.stroke();//绘制路径
//context.strokeStyle="rgba(0,0,0,0,0.5)"
if(p && context.isPointInPath(p.x, p.y)){
alert('第'+i+'个')
window.location.href = hee[i] //跳转到相应的页面根据把原区域声明为数组存起来
//如果传入了事件坐标,就用isPointInPath判断一下
//如果当前环境覆盖了该坐标,就将当前环境的index值放到数组里
who.push(i);
}else{
}
});
//根据数组中的index值,可以到arr数组中找到相应的元素。
return who;
}
点击事件发生时reDraw方法会执行一次重绘,并在重绘过程中检查每一个图形是否覆盖了事件坐标,如果判断为真,则视为点击了该图形,并将该图形的index值放入数组,最后将数组作为reDraw方法的返回值