由于Canvas的 ”忘记式“ 绘图机制(就是它没有维护一份绘制元素的列表)。
如果仅仅检测用户是否点击整个canvas元素,只需在canvas上注册事件就好。
如果是要分别检测canvas里绘制的不同元素的鼠标点击事件,则要用下面的做法,实现一个元素管理器。
一.原理分析
1.canvas元素能提供的一个api是,context.isPointInPath(x,y),它可以判断参数的点是否在当前路径内。
2.当前路径指的是最近一次调用context.beginPath();当前路径context.closePath();中间部分的路径代码就是当前路径。
3.元素管理器维护一个元素列表,每次用户点击时,都遍历这个列表,为列表里的元素创建路径,与当前点做检测,直到找到相应的元素。
4.元素必须自己实现相应的函数:
//1.创建自身路径:createPath(context);
//2.绘制自身:drawSelf(context);
//3.点击时的时间处理:beClick();
二.效果截图
这是一个简单播放器,点击后,canvas元素的效果(图标)会变化,激活相关事件函数。
//图片按钮
var MikuImgBtn = function(x,y,w,h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.image;
this.beClick;
this.createPath = function(context){
context.beginPath();
context.rect(this.x,this.y,this.w,this.h);
context.closePath();
};
this.drawSelf = function(context){
//图片按钮
if(this.image !== undefined){
context.drawImage(this.image,this.x,this.y,this.w,this.h);
}
};
this.addBeClick= function(beClick){
this.beClick = beClick;
}
};
//存储管理已经绘制的元素的一个类
//存储的元素必须实现
//1.创建自身路径:createPath(context);
//2.绘制自身:drawSelf(context);
//3.点击时的时间处理:beClick();
var MikuDrawedObjList = function (){
var objList = [];
this.push = function (obj){
objList.push(obj);
}
this.remove = function(obj){
for(var i = 0;i<objList.length;i++){
var temp = objList[i];
if(temp === obj){
objList.splice(i,1);
return i;
}
}
}
this.getClickObj = function (context,x,y){
for(var i = 0; i<objList.length; i++){
//obj必须实现这个方法
objList[i].createPath(context);
if(context.isPointInPath(x,y)){
return objList[i];
}
}
}
this.drawAll = function (context){
objList.forEach(function(obj){
//obj必须实现这个方法
obj.drawSelf(context);
});
}
}//页面元素列表 var activeObjList = new MikuDrawedObjList();
////按键监听//////////////////////////////////////////////////////////////////////
window.onclick = function(e){
var loc = windowToCanvas(e.clientX,e.clientY);
var clickObj = activeObjList.getClickObj(context,loc.x,loc.y);
if(clickObj!== undefined){
clickObj.beClick();
}
}Canvas---Canvas事件处理、Canvas元素的鼠标点击事件处理、实现一个元素管理器
原文地址:http://blog.csdn.net/mikuscallion/article/details/44042583