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:
- Use
new Path2D()
objects for drawing the rectangles and store them in a dedicated array to use the object later on - While in the event listener handler for dragging the box, search for all boxes that are on said coordinates using
isPointInPath()
. - 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>