Search code examples
javascripthtml5-canvasonclicklistener

Generating buttons in a grid


I'm working on a drum machine and I am not sure how to approach making the squares clickable. How can I alter the color of a specific square to crimson upon being clicked?

const drums = ["Crash", "CHiHat", "OHiHat", "Tom3", "Tom2", "Tom1", "Snare", "Kick"];

for (let i = 0; i < 8; i++) {
    for (let v = 0; v < 16; v++) {
      var block = document.getElementById('canvas');
      var context = block.getContext('2d');
      context.strokeRect(100 + (55 * v), (55 * i), 50, 50);
      context.fillStyle = 'crimson';
      context.fillRect(100 + (55 * v), (55 * i), 50, 50);
    }
}
<canvas id="canvas" width="1920" height="1080"></canvas>

I tried addEventListener, but that returned an error.


Solution

  • A canvas is just a grid of pixels. You can't assign a click handler to a canvas shape, because that shape is just some pixels. If you aren't restricted to using canvas, try using regular elements, like this:

    var drumMachine = document.getElementById("drumMachine");
    var nRows = 8;
    var nCols = 16;
    
    for (let i = 0; i < nRows; i++) {
      var row = document.createElement("tr");
      for (let j = 0; j < nCols; j++) {
        let cell = document.createElement("td");
        cell.className = "clickable";
        cell.addEventListener("click", function () {
          this.classList.toggle("activated");
        });
        row.appendChild(cell);
      }
      drumMachine.appendChild(row);
    }
    #drumMachine {
      margin-left: 100px;
    }
    
    .clickable {
      width: 50px;
      height: 50px;
      background-color: black;
      cursor: pointer;
      margin-right: 5px;
      margin-bottom: 5px;
      display: inline-block;
    }
    
    .clickable.activated {
      background-color: crimson;
    }
    <table id="drumMachine"></table>

    This does a few things.

    1. First, it defines the grid dimensions and then creates the elements in a two-dimensional loop.

    2. It then adds an click event listener to each element (here is where HTML elements shine against HTML canvas!)

    3. After which, the elements are assembled into a regular table setup. CSS is used to mimic your canvas setup.

    If you have any questions don't hesitate to ask in the comments.