由于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