JSFiddle - React, Tailwind, and code Playground

HTML

<p id="verb1">xindex: #, yindex: #</p>
<p id="verb2">gridx: #, gridy: #</p>
<div id="canvas" onselectstart="return false;" ondragstart="return false;">
</div>
<p id="verb4">#, #</p>
<p id="verb5">number of tiles: #</p>
<p id="verb6">#, #</p>

CSS

body {
    background-color: #666;
    text-align: center;
}
#canvas {
    margin: 10px auto;
    background-color: #999;
    position: relative;
    
}
div.tile {
    position: absolute;
}
form {
    margin: 10px auto;
    width: 180px;
}

JavaScript

var tileColour = 'pink';
var tileBorderPxWidth = 0;
var tilePxWidth = 30;
var tilePxHeight = 30;
var columns =4;
var rows =4;

var totalTilePxWidth = tilePxWidth + 2*tileBorderPxWidth;
var totalTilePxHeight = tilePxHeight + 2*tileBorderPxWidth;

var spacing = -tileBorderPxWidth;

var gridSpacing = totalTilePxWidth + spacing;

var canvasPxWidth = (columns*totalTilePxWidth) + (columns - 1)*spacing;
var canvasPxHeight = (rows*totalTilePxHeight) + (rows - 1)*spacing;

var tileStyle = 'div.tile { background-color:' + tileColour + '; border:' + tileBorderPxWidth + 'px solid; width:' + tilePxWidth + 'px; height:' + tilePxHeight + 'px; }';
var canvasStyle = '#canvas { width:' + canvasPxWidth + 'px; height:' + canvasPxHeight + 'px; }';

$('head').append($(document.createElement('style')).text(tileStyle + '\n' + canvasStyle));



$('document').ready(function() {

    var canvasOffset = $("#canvas").offset();
    $(document.createElement('p')).attr('id', 'offset').text('offsetx: '+canvasOffset.left+' offsety: '+canvasOffset.top).appendTo('body');
    

    $(window).resize(function() {
        canvasOffset = $("#canvas").offset();
        $('#offset').text('offsetx: '+canvasOffset.left+' offsety: '+canvasOffset.top);
    });
    

    $('#canvas').mousemove(function(event) {
        event = event || window.event;
        var x = mouseAxisX(event) - canvasOffset.left;
        var y = mouseAxisY(event) - canvasOffset.top;
        $('#verb4').text(x+', '+y);
    });
    

    $('body').mousemove(function(event) {
        event = event || window.event;
        var x = mouseAxisX(event);
        var y = mouseAxisY(event);
        $('#verb6').text(x+', '+y);
    });
    

     $('#canvas').mousedown(function(event) {
        event = event || window.event;
        

        if (event.which != 1) return;
        

        var x = mouseAxisX(event) - canvasOffset.left;
        var y = mouseAxisY(event) - canvasOffset.top;
        

        var x = x-(0.5*gridSpacing);
        var y...