Canvas居中时如何判断鼠标是否点击到画布内的图形?
解决Canvas图形点击检测问题

我的Canvas处于屏幕中央,添加点击事件后调用console.log(e.clientX, e.clientY)得到的是例如530,483这样的屏幕坐标,但我的图形相对于Canvas的坐标是50,50。我该如何判断自己点击的是图形而非Canvas背景区域?
用户提供的代码:
let shapes:any = []; shapes.push({ x:50, y:50, width: this.qrSize, height: this.qrSize, color:'lightgreen' }) let is_mouse_in_shape = function(x:any, y:any, shape:any){ let shape_left = shape.x; let shape_right = shape.x + shape.width; let shape_top = shape.y; let shape_bottom = shape.y + shape.height; console.log(x,y) // x = 415, y = 467 console.log(shape_left, shape_top) // x = 50, y = 50 if( x > shape_left && x < shape_right && y > shape_top && y > shape_bottom ){ return true; } return false; // 此处始终返回false } let mouse_down = function(event:any){ event.preventDefault(); startX = parseInt(event.clientX); startY = parseInt(event.clientY); console.log(event) let index = 0; for(let shape of shapes){ if(is_mouse_in_shape(startX, startY, shape)){ console.log('yes'); current_shape_index = index; } else { console.log('no') } index++; } } let draw_shapes = function(){ context.clearRect(0,0, canvas_width, canvas_height); for (let shape of shapes){ context.fillStyle = shape.color; context.fillRect(shape.x, shape.y, shape.width, shape.height); } } draw_shapes(); canvas.onmousedown = mouse_down;
问题分析与修正方案
你的代码存在两处关键问题,直接导致点击检测失效:
- 未转换屏幕坐标为Canvas相对坐标:
clientX/clientY是相对于浏览器视口的坐标,需要转换成Canvas自身坐标系的坐标才能和图形的本地坐标对比。 - y轴判断条件错误:
is_mouse_in_shape函数中y > shape_bottom应该改为y < shape_bottom,否则逻辑完全颠倒。
修正后的完整代码
let shapes:any = []; shapes.push({ x:50, y:50, width: this.qrSize, height: this.qrSize, color:'lightgreen' }) let is_mouse_in_shape = function(x:number, y:number, shape:any){ const shapeLeft = shape.x; const shapeRight = shape.x + shape.width; const shapeTop = shape.y; const shapeBottom = shape.y + shape.height; // 修正y轴判断条件 return x > shapeLeft && x < shapeRight && y > shapeTop && y < shapeBottom; } let mouse_down = function(event:MouseEvent){ event.preventDefault(); // 获取Canvas在视口中的位置信息 const rect = canvas.getBoundingClientRect(); // 转换为Canvas相对坐标 const canvasX = event.clientX - rect.left; const canvasY = event.clientY - rect.top; let index = 0; for(let shape of shapes){ if(is_mouse_in_shape(canvasX, canvasY, shape)){ console.log('yes'); current_shape_index = index; } else { console.log('no') } index++; } } let draw_shapes = function(){ context.clearRect(0,0, canvas_width, canvas_height); for (let shape of shapes){ context.fillStyle = shape.color; context.fillRect(shape.x, shape.y, shape.width, shape.height); } } draw_shapes(); canvas.onmousedown = mouse_down;
关键说明
- 使用
canvas.getBoundingClientRect()获取Canvas元素在浏览器视口中的位置(left、top等属性),用鼠标的视口坐标减去这些值,就能得到相对于Canvas左上角的坐标。 - 修正
is_mouse_in_shape中的y轴判断逻辑,确保只有当鼠标y坐标在图形的top和bottom之间时才返回true。
内容的提问来源于stack exchange,提问作者Nawapol R.
相关产品推荐
相关产品推荐

