-4

I have a canvas which I am drawing from certain tiles (new Image()), lets say there are for example 10x10 tiles in my canvas.

Every tile has its own data I want to display "popup" with information about this tile everytime user hovers over the tile with mouse, it should be following the mouse until user leaves the tile.

Example of what I want to achieve would be google maps, but it should be following the mouse as I move the mouse over the tile: https://i.gyazo.com/d32cd5869ae9b2e0d9a7053729e2d2aa.mp4

Dakado
  • 11
  • 2
  • 6
  • The reason for all your downvotes is because you should include a [Minimal, Complete and Verifiable Example](https://stackoverflow.com/help/mcve) of what you've tried so far. SO isn't for building your project for you, it's for helping you out when you get stuck on a particular challenge. Take a stab at writing something to start out, and then create a new question showing what you have and exactly what you're having trouble with. – samanime Apr 06 '18 at 11:27

1 Answers1

0

You will need three things to achieve this:

  1. A way to draw the background image on your canvas
  2. A way to track mouse position over the canvas
  3. A list of "zones" and a way to determine which zone is "triggered"

Here is an implementation of the above points:

var GridOverlay = /** @class */ (function () {
    /**
     * Creates an instance of GridOverlay.
     * @param {string} imageSrc
     * @param {{
     *   position: IPoint,
     *   size: IPoint,
     *   message: string
     *  }[]} [zones=[]]
     * @memberof GridOverlay
     */
    function GridOverlay(imageSrc, zones) {
        if (zones === void 0) { zones = []; }
        var _this = this;
        this.zones = zones;
        /**
         * The last registered position of the cursor
         *
         * @type {{ x: number, y: number }}
         * @memberof GridOverlay
         */
        this.mousePosition = { x: 0, y: 0 };
        //Create an image element
        this.img = document.createElement("img");
        //Create a canvas element
        this.canvas = document.createElement("canvas");
        //When the image is loaded
        this.img.onload = function () {
            //Scale canvas to image
            _this.canvas.width = _this.img.naturalWidth;
            _this.canvas.height = _this.img.naturalHeight;
            //Draw on canvas
            _this.draw();
        };
        //Set the "src" attribute to begin loading
        this.img.src = imageSrc;
        //Listen for "mousemove" on our canvas
        this.canvas.onmousemove = this.mouseMove.bind(this);
    }
    /**
     * Registers the current position of the cursor over the canvas, saves the coordinates and calls "draw"
     *
     * @param {MouseEvent} evt
     * @memberof GridOverlay
     */
    GridOverlay.prototype.mouseMove = function (evt) {
        this.mousePosition.x = evt.offsetX;
        this.mousePosition.y = evt.offsetY;
        this.draw();
    };
    /**
     * Clears and redraws the canvas with the latest data
     *
     * @memberof GridOverlay
     */
    GridOverlay.prototype.draw = function () {
        //Get drawing context
        var ctx = this.canvas.getContext("2d");
        //Clear canvas
        ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        //Draw background
        ctx.drawImage(this.img, 0, 0);
        //Loop through zones
        for (var zoneIndex = 0; zoneIndex < this.zones.length; zoneIndex++) {
            var zone = this.zones[zoneIndex];
            //Check for cursor in zone
            if (zone.position.x <= this.mousePosition.x &&
                zone.position.x + zone.size.x >= this.mousePosition.x &&
                zone.position.y <= this.mousePosition.y &&
                zone.position.y + zone.size.y >= this.mousePosition.y) {
                //Display zone message on cursor position
                ctx.fillText(zone.message, this.mousePosition.x, this.mousePosition.y);
                //Break so that we only show a single message
                break;
            }
        }
        return this;
    };
    return GridOverlay;
}());
//TEST
var grid = new GridOverlay("https://placeholdit.imgix.net/~text?txtsize=60&txt=1&w=500&h=500", [
    { message: "Zone 1", position: { x: 10, y: 10 }, size: { x: 100, y: 100 } },
    { message: "Zone 2", position: { x: 80, y: 80 }, size: { x: 100, y: 100 } },
]);
document.body.appendChild(grid.canvas);
Emil S. Jørgensen
  • 6,216
  • 1
  • 15
  • 28