Joel Schmidt
Joel Schmidt

Reputation: 65

Trouble with jquery mouse events

I am currently working on making a grid of squares for a tile map. I have it set up so clicking on a tile changes its state to explored from unexplored. I am attempting to have it so that dragging with the mouse down will change the state of all underlying tiles, however I can't seem to get it to work.

I have tried using mousedown and mouseup events to set a down boolean value which I then check inside of a mouseover. I have tried going about this in several ways (i.e. the commented out code). The current code will work for clicking but I really want to be able to do a drag to change multiples feature.

var tableString;
var width = 35;
var height = 15;
var cells = [];
var localX;
var localY;


function cell(x, y, c) {
  positionX = x;
  positionY = y;
  category = c;
}

function createMap() {
  for (var i = 0; i < height; i++) {
    var row = [];
    for (var j = 0; j < width; j++) {
      let c = new cell();
      c.category = "unexplored";
      c.positionX = j;
      c.positionY = i;
      row.push(c);
    }
    cells.push(row);
  }
}

function drawMap() {
  tableString = "<table draggable='false'>";
  for (var i = 0; i < height; i++) {
    tableString += "<tr draggable='false'>";
    for (var j = 0; j < width; j++) {
      tableString += '<td draggable="false" class="' + cells[i][j].category + '" data-row="' + j + '" data-column="' + i + '"></td>';
    }
    tableString += "</tr>";
  }
  tableString += "</table>";
  $("#mainContainer").html(tableString);
  console.log("drew it");
}

function updateCellCategory(x, y, c) {
  cells[x][y].category = c;
  drawMap();
}


$(document).ready(function() {
  createMap();
  drawMap();


  // var down = false;
  // $(document,"td").mousedown(function () {
  //     down = true;
  // })
  // $(document,"td").mouseup(function () {
  //     down = false;
  // });

  // $(document,"td").on('mouseover','td',function () {
  //     if (down) {
  //         console.log("hovering and holding");
  //         localX = $(this).attr("data-row");
  //         localY = $(this).attr("data-column");
  //         updateCellCategory(localY, localX, "explored");
  //     }

  // });
});


// $(document).on('mousedown',"td, documen",(function () {
//     down = true;
//     console.log(down);
// }));
// $(document).on('mouseup',"*",(function () {
//     down = false;
//     console.log(down);
// }));

// $(document).on('mouseover','td',function () {
//     if (down) {
//         console.log("hovering and holding");
//         localX = $(this).attr("data-row");
//         localY = $(this).attr("data-column");
//         updateCellCategory(localY, localX, "explored");
//     }

// });

$("*").delegate('td', 'click', function() {
  localX = $(this).attr("data-row");
  localY = $(this).attr("data-column");
  updateCellCategory(localY, localX, "explored");
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#mainContainer {
  max-width: 100%;
  max-height: 90%;
  width: 100%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

td {
  width: 25px;
  height: 25px;
  border: .05px solid black;
}

.explored {
  background-color: lightblue;
}

.unexplored {
  background-color: lightcoral;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div id="mainContainer">

  </div>
</body>

</html>

The main issue I found when working on this is that some of the commented code works sometimes, but the second a drag event happens on a td the code breaks and the mouseup is not recognized causing the mouse cursur to continue affecting tiles even though the mouse was not held down.

Upvotes: 2

Views: 46

Answers (2)

Skylar
Skylar

Reputation: 926

You can check whether or not the mouse is down using the event parameter of the event handler. Look at the last few lines of the snippet.

var tableString;
var width = 35;
var height = 15;
var cells = [];
var localX;
var localY;


function cell(x, y, c) {
  positionX = x;
  positionY = y;
  category = c;
}

function createMap() {
  for (var i = 0; i < height; i++) {
    var row = [];
    for (var j = 0; j < width; j++) {
      let c = new cell();
      c.category = "unexplored";
      c.positionX = j;
      c.positionY = i;
      row.push(c);
    }
    cells.push(row);
  }
}

function drawMap() {
  tableString = "<table draggable='false'>";
  for (var i = 0; i < height; i++) {
    tableString += "<tr draggable='false'>";
    for (var j = 0; j < width; j++) {
      tableString += '<td draggable="false" class="' + cells[i][j].category + '" data-row="' + j + '" data-column="' + i + '"></td>';
    }
    tableString += "</tr>";
  }
  tableString += "</table>";
  $("#mainContainer").html(tableString);
  console.log("drew it");
}

function updateCellCategory(x, y, c) {
  cells[x][y].category = c;
  drawMap();
}


$(document).ready(function() {
  createMap();
  drawMap();


  // var down = false;
  // $(document,"td").mousedown(function () {
  //     down = true;
  // })
  // $(document,"td").mouseup(function () {
  //     down = false;
  // });

  // $(document,"td").on('mouseover','td',function () {
  //     if (down) {
  //         console.log("hovering and holding");
  //         localX = $(this).attr("data-row");
  //         localY = $(this).attr("data-column");
  //         updateCellCategory(localY, localX, "explored");
  //     }

  // });
});


// $(document).on('mousedown',"td, documen",(function () {
//     down = true;
//     console.log(down);
// }));
// $(document).on('mouseup',"*",(function () {
//     down = false;
//     console.log(down);
// }));

// $(document).on('mouseover','td',function () {
//     if (down) {
//         console.log("hovering and holding");
//         localX = $(this).attr("data-row");
//         localY = $(this).attr("data-column");
//         updateCellCategory(localY, localX, "explored");
//     }

// });

$("*").delegate('td', 'mousedown', function() {
  localX = $(this).attr("data-row");
  localY = $(this).attr("data-column");
  updateCellCategory(localY, localX, "explored");
});

$("*").delegate('td', 'mouseenter', function(event) {
  if (event.buttons) {
    localX = $(this).attr("data-row");
    localY = $(this).attr("data-column");
    updateCellCategory(localY, localX, "explored");
  }
  event.stopPropagation();
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#mainContainer {
  max-width: 100%;
  max-height: 90%;
  width: 100%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

td {
  width: 25px;
  height: 25px;
  border: .05px solid black;
}

.explored {
  background-color: lightblue;
}

.unexplored {
  background-color: lightcoral;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div id="mainContainer">

  </div>
</body>

</html>

Upvotes: 0

Lee Taylor
Lee Taylor

Reputation: 7984

OK. Using the click event is not what you want, since that involves pressing the mouse and releasing it.

Instead use, the mousemove, mousedown and mouseup events. Also, keep track of whether the mouse is down or not using a variable.

var tableString;
var width = 35;
var height = 15;
var cells = [];
var localX;
var localY;
var mouseDown = false;

function cell(x, y, c) {
  positionX = x;
  positionY = y;
  category = c;
}

function createMap() {
  for (var i = 0; i < height; i++) {
    var row = [];
    for (var j = 0; j < width; j++) {
      let c = new cell();
      c.category = "unexplored";
      c.positionX = j;
      c.positionY = i;
      row.push(c);
    }
    cells.push(row);
  }
}

function drawMap() {
  tableString = "<table draggable='false'>";
  for (var i = 0; i < height; i++) {
    tableString += "<tr draggable='false'>";
    for (var j = 0; j < width; j++) {
      tableString += '<td draggable="false" class="' + cells[i][j].category + '" data-row="' + j + '" data-column="' + i + '"></td>';
    }
    tableString += "</tr>";
  }
  tableString += "</table>";
  $("#mainContainer").html(tableString);
  //console.log("drew it");
}

function updateCellCategory(x, y, c) {
  cells[x][y].category = c;
  drawMap();
}

$(document).ready(function() {
  createMap();
  drawMap();
});

$("*").on("mousedown", 'td',  function() 
{
  mouseDown = true;
});

$(document).on("mouseup", function() 
{
  mouseDown = false;
});

$("*").on("mousemove", 'td',  function() 
{
  if(!mouseDown)
    return;

  localX = $(this).attr("data-row");
  localY = $(this).attr("data-column");
  updateCellCategory(localY, localX, "explored");
});
html,
body {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#mainContainer {
  max-width: 100%;
  max-height: 90%;
  width: 100%;
  height: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

td {
  width: 25px;
  height: 25px;
  border: .05px solid black;
}

.explored {
  background-color: lightblue;
}

.unexplored {
  background-color: lightcoral;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
  <div id="mainContainer">

  </div>
</body>

</html>

Upvotes: 1

Related Questions