canvas怎么只选中png图片中有内容的地方,而不选中透明部分?

如题,canvas 绘制完一张png图片后(注意是图片),只想在有图形的地方上响应mousemove事件改变鼠标样式,而不是透明的地方。

就是在下面这个canvas中,画了一张透明底的图片,只想在透明底图片中的黄色部分响应鼠标事件,而不想一移动到上透明底图片的透明部分就响应鼠标事件。

33.PNG

想知道有没有什么方法可以完成这个操作?因为在某个地方看到了这个操作,但不知道该怎么实现,是需要SVG转canvas嘛?有没有什么canvas库可以推荐一下呢?

感谢大佬们!

阅读 4.7k
3 个回答

canvas没办法直接知道某一个点下面是什么,但我们可以使用空间分析去粗略的计算,对于简单图形这个计算也会比较简单,但这是有前提的。

比如你这里就需要预先知道黄色部分在canvas中的中心点位置和半径(可通过相对图片大小,图片位置,图片大小等计算),如果这个不知道,也就把下面的路堵死了。知道这个后可以通过判断鼠标是否落在圆形区域来判断。

//rx 圆心x   ry 圆心y   r半径
myCanvas.onmousemove = function(e){
    var x = e.offsetX; //offsetX不一定是准确的
    var y = e.offsetY;
    if((x-rx)*(x-rx)+(y-ry)*(y-ry) <= r*r*Math.PI){
        //console.log("在圆内");
    }else{
        //console.log("在圆外");
    }
}

再说个不大适用的,如果你的canvas中需要判断的地方颜色是仅有的,那么还可以通过获取canvas在该地方的颜色值进行判断,这个颜色值应该是一个区间,而不是一个固定值

var w = canvas.width
var h = canvas.height
var ctx = canvas.getContext('2d');
var imgData = ctx.getImageData(0,0,w,h)
imgData = imgData.data

myCanvas.onmousemove = function(e){
    var x = e.offsetX;
    var y = e.offsetY;
    var i = w * (y - 1) + x //色值位置
    var r = imgData[i];
    var g = imgData[i+1];
    var b = imgData[i+2];
    var a = imgData[i+3];
    if(testColor(r, g, b, colors)){
        //不是对应的颜色          
    }else{
        //是对应的颜色
    }
}

//图中两种颜色
var myColors = [[247, 193, 0], [205, 159, 16]
function testColor(r, g, b){
    //阈值,与目标颜色的相似度
    var limit = 10;
    return myColors.some(function(item, index){
        return (Math.abs(item[0] - r) <= limit) 
            && (Math.abs(item[1] - g) <= limit) 
            && (Math.abs(item[2] - b) <= limit)
    })
}

憋死我了!为什么自己的问题要一个小时之后才能回答。上面的兄弟,回答错了,说了是图片不是图形啦~

stackoverflow上有人回答我了
是用getImageDate()先获取图片数据
const pixel = canvas.getImageData(x, y, 1, 1).data;
然后判断鼠标下方的像素点的RGBA值中的A值为0还是为1。就可以判断是不是在图片的透明区域了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题