Home > Enterprise >  How do I 'highlight' the drawn rectangle areas?
How do I 'highlight' the drawn rectangle areas?

Time:06-02

When you move the unit (blue div) around; I want the rectangle over which the unit hovers to be highlighted, with the middle point of that unit as the indicator if it's hovering over a certain rectangle or not. With highlighted I mean, f.e.: Change the color of that specific rectangle.

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>

How can I best do this?

I can make a lot of if-loops to check if the x/y points of the unit are greater and or lesser than the position of a rectangle (which I first would need to create) to check if the middle of the unit hovers over it or not to satisfy the condition of being highlighted. But this seems like a lot of ifs and I'm sure there is a better, simpler way to do this.

CodePudding user response:

Here is one potential way of doing it:

  1. Use new Path2D() objects for drawing the rectangles and store them in a dedicated array to use the object later on
  2. While in the event listener handler for dragging the box, search for all boxes that are on said coordinates using isPointInPath().
  3. For the found box(es?) change the background color to "highlight" for all other items restore the original "normal" background color.

I also think having to iterate all items seems bad performance wise but seem to be the only way for what I found.

Credit to this answer, which helped me:

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>

  • Related