0

I want an HTML canvas that displays mouse position on its JS grid on mouse move, but I can't seem to clear my canvas, I tried using ctx.clearRect(0,0 canvas.width, canvas.height) and clearing with a click, but it somehow remembers the previous draw it had. I want only one black square to be displayed on canvas at a time depending on the mouse position. Heres demo on code pen and some code

<canvas id="myMap" style="width: 300px;height: 300px;background-color: beige;"></canvas>
<script>
  var findDivisible = (x, scale) => {
    while (x % scale !== 0 && x > 0) {
      x = x - 1;
    };
    return x
  };

  var map = document.getElementById("myMap");
  map.width = 300;
  map.height = 300;
  var mapContext = document.getElementById("myMap").getContext("2d");
  map.addEventListener("mousemove", function(e) {
    mapContext.clearRect(0, 0, map.width, map.height);
    mapContext.rect(findDivisible(e.clientX - map.offsetLeft, 50), findDivisible(e.pageY - map.offsetTop, 50), 50, 50);
    mapContext.stroke();

  });
  map.addEventListener("click", function() {
    mapContext.clearRect(0, 0, 500, 500);
  })
</script>

0

2 Answers 2

2

You're not starting a new stroke for each rectangle, but "piling them up" so they get re-re-redrawn with .stroke().

Use .beginPath():

function findDivisible(x, scale) {
  while (x % scale !== 0 && x > 0) {
    x = x - 1;
  }
  return x;
}

var map = document.getElementById("myMap");
map.width = 300;
map.height = 300;
var mapContext = map.getContext("2d");
map.addEventListener("mousemove", function(e) {
  mapContext.clearRect(0, 0, map.width, map.height);
  mapContext.beginPath();
  mapContext.rect(
    findDivisible(e.clientX - map.offsetLeft, 50),
    findDivisible(e.pageY - map.offsetTop, 50),
    50,
    50,
  );
  mapContext.stroke();
});
map.addEventListener("click", function() {
  mapContext.clearRect(0, 0, 500, 500);
});
<canvas id="myMap" style="width: 300px;height: 300px;background-color: beige;"></canvas>

Sign up to request clarification or add additional context in comments.

Comments

1

You can try this:

map.addEventListener("mousemove", function(e){              
  map.width = map.width;
  mapContext.rect(findDivisible(e.clientX-map.offsetLeft,50) , findDivisible(e.pageY - map.offsetTop,50), 50, 50);
  mapContext.stroke();              
});

map.addEventListener("click", function(){
  map.width = map.width;
});

One of the ways that is implicitly endorsed in the spec and often used in people’s apps to clear a canvas https://dzone.com/articles/how-you-clear-your-html5

2 Comments

If ctx.clearRect doesn't work, it's unlikely an old method of doing the same thing (re-setting the width) will make any difference.
@DBS and still, that would. This does reset the whole context, including the current sub-path declaration along with all the context's settable options, and its underlying ImageData (i.e a lot of garbage to collect). That's why one should never use this hack.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.