How to fix this "mouse hover" function in a canvas

Viewed 81

I made a Canvas with 32x32 tiles. I wanted to stroke the tile the mouse is on, this is what I made (Thanks to some tutorials and adjustments)

First, I create cPush and cUndo. cPush is called when I draw something, to memorize it. For cUndo, you'll see later. I also call my ctx var and I call my canvas var.

var canvas = document.getElementById('canvas');
var cPushArray = new Array();
var cStep = -1;
var ctx = canvas.getContext('2d');

function cPush() {
    cStep++;
    if (cStep < cPushArray.length) { cPushArray.length = cStep; }
    cPushArray.push(document.getElementById('canvas').toDataURL());
}
function cUndo() {
    if (cStep > 0) {
        cStep--;
        var canvasPic = new Image();
        canvasPic.src = cPushArray[cStep];
        canvasPic.onload = function () { ctx.drawImage(canvasPic, 0, 0); }
    }
}

I will skip some parts because they are not necessary. Here, I'm calling the onmousemove function :

     canvas.onmousemove = function(e) {

    let rects = [], i = 0, r;
    let jk = 0;
    for(var nb = 0, l = map.terrain.length ; nb < l ; nb++) {
         var ligne = map.terrain[nb];
         var y2 = nb * 32;
         for(var j = 0, k = ligne.length ; j < k ; j++, jk++) {
             rects[jk] = {lignej: ligne[j], x: j * 32, y: y2, w: 32, h: 32};
         }
    }

This first part is made to get every tiles of the map and store it into rects[x] This will be useful for me later, when I will need specific tiles.

Now, I call a function :

     map.test = function(linewidth) {
         this.tileset.dessinerTile(r.lignej, context, r.x, r.y);
         ctx.lineWidth = linewidth;
         ctx.strokeRect(r.x, r.y, 32, 32);
     }

This is made to redraw the Tile i'm on with a stroke. (r. = rects var, you'll see later)

Here's the rest :

         var rect = this.getBoundingClientRect(),
             x = e.clientX - rect.left,
             y = e.clientY - rect.top;

     while (r = rects[i++]) {
             ctx.beginPath();
             ctx.rect(r.x, r.y, 32, 32);

             if (ctx.isPointInPath(x, y) == true) {
                 cPush();
                 map.test(2);
             } else {
                 cUndo();
             }
     }
};

The var Rect is made to check the mouse's position.

Now, there's a while. For each tiles we'll check if isPointinPath is true. (x and y are the mouse's positions).

So, if that's true, the function map.test will draw the tile with a 2 lineWidth stroke as mentioned.

If not, it will Undo the last stroke.

What I wanted to do here :

If the mouse is on a tile, it stroke the tile. If the mouse move, it undo the last stroke and stroke the new one.

What it does :

If the mouse is on a tile, it stroke the tile before doing an undo of the stroke because it check the other ones. So the stroke only last 0.5s instead of being permanent until I move the mouse. I think the problem is that I'm using a "onmousemove" function ? Do I need to change to a "onmousehover" or something like that ? I'm quite lost...

Thanks for the help !

RECORD OF THE PROBLEM (Sorry for the low FPS it's a gif)

http://recordit.co/GokcSAoMv6

0 Answers
Related