为canvas绘制的多个图形设置点击事件 您所在的位置:网站首页 小的按钮怎么画图片 为canvas绘制的多个图形设置点击事件

为canvas绘制的多个图形设置点击事件

2024-03-12 22:52| 来源: 网络整理| 查看: 265

一、给Canvas元素绑定事件基础知识

由于事件只能达到Canvas元素这一层,所以,如果想进一步深入,识别点击发生在Canvas内部的哪一个图形上,就需要增加代码来进行处理。

基本思路是:给Canvas元素绑定事件,当事件发生时,检查事件对象的位置,然后检查哪些图形覆盖了该位置。只要鼠标点击在这个范围里,就可以视为点击了该矩形,也就可以手动触发矩形需要处理的点击事件。

第一步:封装一个获取事件对象位置的函数getEventPosition()

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添加点击事件

cvs = document.getElementById('mycanvas'); cvs.addEventListener('click', function(e){ //... }, false);

第三步:判断事件对象的坐标是否在图形内:

cvs = document.getElementById('mycanvas'); ctx = canvas.getContext('2d'); ctx.rect(10, 10, 100, 100); ctx.stroke(); ctx.isPointInPath(50, 50); //true ctx.isPointInPath(5, 5); //false

注意:canvas中绘制多个图形时,isPointInPath()只能判断事件对象的位置是否在最后一个绘制的图形上,而之前绘制的图形已经无法判断

cvs = document.getElementById('mycanvas'); ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.rect(10, 10, 100, 100); ctx.stroke(); ctx.isPointInPath(20, 20); //true ctx.beginPath(); ctx.rect(110, 110, 100, 100); ctx.stroke(); ctx.isPointInPath(150, 150); //true ctx.isPointInPath(20, 20); //false 二.当canvas绘制多个图形时的点击事件

具体思路:当点击事件发生时,重绘所有图形,每绘制一个就使用isPointInPath方法,判断事件坐标是否在该图形覆盖范围内。

第一步:为了实现重绘,需要将图形的参数保存下来

arr = [ {x:10, y:10, width:100, height:100}, {x:110, y:110, width:100, height:100} ]; cvs = document.getElementById('mycanvas'); ctx = canvas.getContext('2d');

第二步:添加点击事件

cvs.addEventListener('click', function(e){ p = getEventPosition(e); draw(p); }, false);

第三步:每次点击时重绘图形

//图形绘制 function draw(p){ var who = [];//保存点击事件包含图形的index值 ctx.clearRect(0, 0, cvs.width, cvs.height); arr.forEach(function(v, i){ ctx.beginPath(); ctx.rect(v.x, v.y, v.width, v.height); ctx.stroke(); if(p && ctx.isPointInPath(p.x, p.y)){ //如果传入了事件坐标,就用isPointInPath判断一下 //如果当前环境覆盖了该坐标,就将图形的index放到数组里 who.push(i); } }); //根据数组中的index值,可以到arr数组中找到相应的元素。 return who; }

在上面代码中,点击事件发生时draw方法会执行一次重绘,并在重绘过程中检查每一个图形是否覆盖了事件坐标,如果判断为真,则视为点击了该图形,并将该图形的index值放入数组,最后将数组作为draw方法的返回值。在这种处理机制下,如果Canvas里有N个图形,它们有一部分是重叠的,而点击事件恰巧发生在这个重叠区域上,那么draw方法的返回数组里会有N个成员。这时就有点类似事件冒泡的情况,数组的最后一个成员处于Canvas最上层,而第一个成员则在最下层,我们可以视为最上层的成员是e.target,而其他成员则是冒泡过程中传递到的节点。当然这只是最简单的一种处理方法,如果真要模拟DOM处理,还要给图形设置父子级关系。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有