如何 'highlight' 绘制矩形区域?

How do I 'highlight' the drawn rectangle areas?

当你移动单位(蓝色div)时;我希望突出显示单元悬停的矩形,如果它悬停在某个矩形上,则以该单元的中点作为指示符。 突出显示我的意思是,f.e。:更改该特定矩形的颜色。

const board = document.getElementById("board");
const ctxB = board.getContext("2d");
var Grid = false;
const boxsize = 64;

const amountOfrows = 8;
const amountOfHorBoxes = 7;
const totalAmountOfBoxes = amountOfrows * amountOfHorBoxes;
board.width = boxsize * 7.5;
board.height = boxsize * 8;
var addHorBox = 0;
var addVertBox = 0;

function drawGrid(){
    Grid=true;
    // for the amout of rows
    for (let rowcount = 0; rowcount < amountOfrows; rowcount++) {
        ctxB.lineWidth = 1;
        ctxB.strokeStyle = "black";
        ctxB.fillStyle = "white";

        // filling the rows
        for (let boxcount = 0; boxcount < amountOfHorBoxes; boxcount++) {
            ctxB.beginPath();
            ctxB.rect(addHorBox, addVertBox, boxsize, boxsize);
            ctxB.fill();
            ctxB.closePath();
            ctxB.stroke();
            addHorBox+=boxsize;
        }
        addHorBox=0;
        addVertBox+=boxsize;
    }
}
function loop(timestamp){    
    
    //var winw = window.innerWidth; 
    //var winh = window.innerHeight;
    
    // draw once
    if(Grid==false) drawGrid();
   
    requestAnimationFrame(loop);
}
loop();

// Make the UNIT draggable:
dragElement(document.getElementById("unit"));

function dragElement(unit) {
    var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    unit.onmousedown = dragMouseDown;
  
    function dragMouseDown(e) {
        e = e || window.event;
        e.preventDefault();
        // get the mouse cursor position at startup:
        pos3 = e.clientX;
        pos4 = e.clientY;
        document.onmouseup = closeDragElement;
        // call a function whenever the cursor moves:
        document.onmousemove = elementDrag;
    }
    function elementDrag(e) {
        e = e || window.event;
        e.preventDefault();
        // calculate the new cursor position:
        pos1 = pos3 - e.clientX;
        pos2 = pos4 - e.clientY;
        pos3 = e.clientX;
        pos4 = e.clientY;
        // set the element's new position:
        unit.style.top = (unit.offsetTop - pos2) + "px";
        unit.style.left = (unit.offsetLeft - pos1) + "px";
    }
    function closeDragElement() {
        // stop moving when mouse button is released:
        document.onmouseup = null;
        document.onmousemove = null;
    }
}
#board{
    background-color: #999;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
#unit{
    background-color: rgb(134, 162, 224);
    position: absolute;
    cursor: pointer;
    z-index: 1;
    width: 50px;
    height: 50px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="gridbattler.css"/>
    <title>Gridding</title>
</head>
<body>
    <div id="unit"></div>
    <canvas id="board"></canvas></div>
    <script src="gridbattler.js"></script>
</body>
</html>

我怎样才能最好地做到这一点?

我可以做很多 if 循环来检查单元的 x/y 点是否大于或小于矩形的位置(我首先需要创建)来检查是否单元中间悬停是否满足高亮条件。但这似乎有很多假设,我相信有更好、更简单的方法来做到这一点。

这是一种可行的方法:

  1. 使用 new Path2D() 对象绘制矩形并将它们存储在专用数组中以便稍后使用该对象
  2. 在拖动框的事件侦听器处理程序中,使用 isPointInPath() 搜索所有位于所述坐标上的框。
  3. 对于找到的框(es?),将所有其他项目的背景颜色更改为“突出显示”,恢复原始“正常”背景颜色。

我还认为必须迭代所有项目似乎在性能方面很糟糕,但似乎是我发现的唯一方法。

归功于这个对我有帮助的答案:

const board = document.getElementById('board')
const ctxB = board.getContext('2d')
let Grid = false
const boxsize = 64

const amountOfrows = 8
const amountOfHorBoxes = 7
const totalAmountOfBoxes = amountOfrows * amountOfHorBoxes
board.width = boxsize * 7.5
board.height = boxsize * 8
let addHorBox = 0
let addVertBox = 0
let boxes = []

function drawGrid () {
    Grid = true
    // for the amout of rows
    for (let rowcount = 0; rowcount < amountOfrows; rowcount++) {
        for (let boxcount = 0; boxcount < amountOfHorBoxes; boxcount++) {
            let box = new Path2D()
            box.rect(addHorBox, addVertBox, boxsize, boxsize)
            ctxB.stroke(box)
            boxes.push(box)
            addHorBox += boxsize
        }
        addHorBox = 0
        addVertBox += boxsize
    }
}

function loop (timestamp) {

    // draw once
    if (Grid == false) drawGrid()

    requestAnimationFrame(loop)
}

loop()

// Make the UNIT draggable:
dragElement(document.getElementById('unit'))

function dragElement (unit) {
    let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0
    unit.onmousedown = dragMouseDown

    function dragMouseDown (e) {
        e = e || window.event
        e.preventDefault()
        // get the mouse cursor position at startup:
        pos3 = e.clientX
        pos4 = e.clientY
        document.onmouseup = closeDragElement
        // call a function whenever the cursor moves:
        document.onmousemove = elementDrag
    }

    function elementDrag (evt) {
    
        const rect = board.getBoundingClientRect()
        const x = evt.clientX - rect.left
        const y = evt.clientY - rect.top
  
        // set the element's new position:
        unit.style.top = (y) + 'px'
        unit.style.left = (x) + 'px'

        for (let box of boxes) {
            if (ctxB.isPointInPath(box, x, y)) {
                ctxB.fillStyle = 'green'
                ctxB.fill(box)
                ctxB.stroke(box)
            } else {
                ctxB.fillStyle = '#999'
                ctxB.fill(box)
                ctxB.stroke(box)
            }
        }
    }

    function closeDragElement () {
        // stop moving when mouse button is released:
        document.onmouseup = null
        document.onmousemove = null
    }
}
#board {
  background-color: #999;
}

#unit {
  background-color: rgb(134, 162, 224);
  position: absolute;
  cursor: pointer;
  z-index: 1;
  width: 50px;
  height: 50px;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="gridbattler.css" />
  <title>Gridding</title>
</head>

<body>
  <div id="unit"></div>
  <canvas id="board"></canvas></div>
  <script src="gridbattler.js"></script>
</body>

</html>