canvas {
border: 1px solid red;
height: 600px;
width: 600px;
}
const WIDTH = 600
const HEIGHT = 600
const NODE_LIST = [
{
x: 10,
y: 20,
width: 30,
height: 30,
text: 'rect1'
},
{
x: 50,
y: 100,
height: 300,
width: 300,
text: 'rect2',
children: [
{
x: 100,
y: 150,
height: 200,
width: 200,
text: 'rect2-1',
children: [
{
x: 140,
y: 200,
height: 50,
width: 40,
text: 'rect2-1-1',
},
{
x: 220,
y: 200,
height: 50,
width: 40,
text: 'rect2-1-2',
}
]
}
]
}
]
function _drawRect (nodeList, ctx) {
nodeList.forEach(node => {
ctx.strokeRect(node.x, node.y, node.width, node.height)
node.children && _drawRect(node.children, ctx)
})
}
function drawRect () {
let canvas = document.querySelector('canvas')
canvas.width = WIDTH
canvas.height = HEIGHT
let ctx = canvas.getContext('2d')
_drawRect(NODE_LIST, ctx)
}
function calcClickPosition (event) {
let canvas = document.querySelector('canvas')
let rect = canvas.getBoundingClientRect()
let x = (event.clientX - rect.left) / rect.width * WIDTH
let y = (event.clientY - rect.top) / rect.height * HEIGHT
return { x, y }
}
function isInRect(pos, node) {
let { x, y, width: w, height: h } = node
console.log(pos, x, y, pos.x >= x)
return pos.x >= x && pos.x <= x + w && pos.y >= y && pos.y <= y + h
}
// 递归查找
function findClickNode (pos, nodeList) {
for (let node of nodeList) {
if (isInRect(pos, node)) {
let childTarget = findClickNode(pos, node.children || [])
return childTarget || node
}
}
return null
}
function click (event) {
let pos = calcClickPosition(event)
let text = '点击区域不在画布'
if (isInRect(pos, {x:0, y: 0, width: WIDTH, height: HEIGHT})) {
let node = findClickNode(pos, NODE_LIST)
text = node ? `点击了${node.text}` : '点击了画布'
}
let el = document.querySelector('.show-click')
el.innerText = text
}
drawRect()
document.addEventListener('click', click)