Search code examples
javascriptcanvashexagonal-tiles

Update canvas on mouse events


I've created a hexagonal grid using this JS library. The grid does get properly painted onto the Canvas. My issue is with trying to introduce events on mouse events. For instance, when I hover over a certain hexagon I want it's background color to change.

At the moment, only the last created hexagon will change on mouseover regardless of which hexagon the cursor is hovering over. How can I make the event listener update the specific hexagon over which the cursor exists?

If this is not possible due to painted objects becoming "rasterized" into the canvas, what alternate approach would be recommended?

The code is below:

<canvas id="stage"></canvas>
<script>
  var element        = document.getElementById("stage");
      element.height = window.innerHeight;
      element.width  = window.innerWidth;

  var stage   = new createjs.Stage("stage");
      stage.x = window.innerWidth/2;
      stage.y = window.innerHeight/2;
      stage.enableMouseOver();

  var grid             = new Grid();
      grid.tileSize    = 55;

  var stageTransformer = new StageTransformer().initialize({ element: element, stage: stage });
  stageTransformer.addEventListeners();

  var tick = function (event) { stage.update(); };
  var colorHexagon = function(hexagon, fill) {
    hexagon.graphics
      .beginFill(fill)
      .beginStroke("rgba(50,50,50,1)")
      .drawPolyStar(0, 0, grid.tileSize, 6, 0, 0);
  };

  var coordinates = grid.hexagon(0, 0, 3, true)
  for (var i = 0; i < coordinates.length; i++) {
    var q = coordinates[i].q,
        r = coordinates[i].r,
        center = grid.getCenterXY(q, r),
        hexagon = new createjs.Shape();
        hexagon.cursor = "pointer";

    hexagon.addEventListener("mouseover", function() {
      colorHexagon(hexagon, "rgba(50,150,0,1)")
    });

    hexagon.addEventListener("mouseout", function() {
      colorHexagon(hexagon, "rgba(150,150,150,1)")
    });

    hexagon.q = q;
    hexagon.r = r;
    hexagon.x = center.x;
    hexagon.y = center.y;

    colorHexagon(hexagon, "rgba(150,150,150,1)");

    stage.addChild(hexagon);
    stage.update();
  }

  tick();
  createjs.Ticker.setFPS(30);
  createjs.Ticker.addEventListener("tick", tick);
</script>

Solution

  • This should work.

    stage.addEventListener("mouseover", function(evt) {
      colorHexagon(evt.target, "rgba(50,150,0,1)")
    });
    
    stage.addEventListener("mouseout", function(evt) {
      colorHexagon(evt.target, "rgba(150,150,150,1)")
    });
    

    you can put them at the very bottom of your script. They don't have to be in a loop.