S.Zirk S.Zirk - 1 month ago 13
Ajax Question

How to load image on canvas and put markers on click

Hello there I am working on a final year project app and I don't have much experience with HTML5.

I am attempting to create a simple canvas which loads up an image on start and when the image is loaded, I want to be able to put markers on the image, like how google maps allows markers to be placed .... The marker will most probably an image but I need to calculate the X and Y position and show the coordinates of every marker that is placed on originally loaded image .....

The markers could be stored as an array in javascript, or could be ajax in as it could be updated and the map will need to be refreshed

Thanks in advance for any kind of help. Much appreciated

Answer

Zrik ok I have created a jsFiddle for you which should give you a great start :).

jsFiddle : https://jsfiddle.net/7hed6uxL/2/

Html

<p>Click on the map to place a marker</p>
<canvas id="Canvas" width="700" height="700"></canvas>

Javascript

// Target the canvas element on the page
var canvas = document.getElementById('Canvas');
var context = canvas.getContext("2d");

// Map sprite
var mapSprite = new Image();
mapSprite.src = "http://www.retrogameguide.com/images/screenshots/snes-legend-of-zelda-link-to-the-past-8.jpg";

// Create a basic class which will be used to create a marker
var Marker = function () {
    this.Sprite = new Image();
    this.Sprite.src = "http://www.clker.com/cliparts/w/O/e/P/x/i/map-marker-hi.png"
    this.Width = 12;
    this.Height = 20;
    this.XPos = 0;
    this.YPos = 0;
}

// Array of markers
var Markers = new Array();

// When the user clicks their mouse on our canvas run this code
var mouseClicked = function (mouse) {
    // Get corrent mouse coords
    var rect = canvas.getBoundingClientRect();
    var mouseXPos = (mouse.x - rect.left);
    var mouseYPos = (mouse.y - rect.top);

    // Move the marker when placed to a better location
    var marker = new Marker();
    marker.XPos = mouseXPos - (marker.Width / 2);
    marker.YPos = mouseYPos - marker.Height;

    // Push our new marker to our Markers array
    Markers.push(marker);
}

// Add mouse click event listener to canvas
canvas.addEventListener("mousedown", mouseClicked, false);

// Run this once so we setup text rendering
var firstLoad = function () {
    context.font = "15px Georgia";
    context.textAlign = "center";
}

firstLoad();

// This will be called 60 times a second, look at the code at the bottom `setInterval`
var main = function () {
    // Update our canvas
    draw();
};

var draw = function () {
    // Clear Canvas
    context.fillStyle = "#000";
    context.fillRect(0, 0, canvas.width, canvas.height);

    // Draw map
    // Sprite, X location, Y location, Image width, Image height
    // You can leave the image height and width off, if you do it will draw the image at default size
    context.drawImage(mapSprite, 0, 0, 700, 700);

    // Draw markers
    for (var i = 0; i < Markers.length; i++) {
        var tempMarker = Markers[i];
        // Draw marker
        context.drawImage(tempMarker.Sprite, tempMarker.XPos, tempMarker.YPos, tempMarker.Width, tempMarker.Height);

        // Calculate position text
        var markerText = "Postion (X:" + tempMarker.XPos + ", Y:" + tempMarker.YPos;

        // Draw a simple box so you can see the position
        var textMeasurements = context.measureText(markerText);
        context.fillStyle = "#666";
        context.globalAlpha = 0.7;
        context.fillRect(tempMarker.XPos - (textMeasurements.width / 2), tempMarker.YPos - 15, textMeasurements.width, 20);
        context.globalAlpha = 1;

        // Draw position above
        context.fillStyle = "#000";
        context.fillText(markerText, tempMarker.XPos, tempMarker.YPos);
    }
};

setInterval(main, (1000 / 60)); // Refresh 60 times a second

I have commented the code so it should explain everything to you, if you need any more help just let me know. Also just to let you know you shouldn't use hard coded numbers I.E this line context.fillRect(tempMarker.XPos - (textMeasurements.width / 2), tempMarker.YPos - 15, textMeasurements.width, 20); you should probably store 20 value in a variable because that will always be the height of the text background box. But I put it in there for you to learn what works for you.

Comments