0

I have a map (background image) on a Canvas, and "markers" in some cities (images duplicated from an Array of Objects and included in Canvas by drawImage ()).

Now I have to include href and title attributes in these markers. The data is also in the same Array of Objects.

The code so far:

var mkr = [
        {markerX: 222, markerY: 9, mkrTitle: "t1", mkrAction: "http://www.google.com"},
        {markerX: 210, markerY: 93, mkrTitle: "t2", mkrAction: "http://www.google.com"},
        {markerX: 122, markerY: 82, mkrTitle: "t3", mkrAction: "http://www.google.com"},
        {markerX: 103, markerY: 190, mkrTitle: "t4", mkrAction: "http://www.google.com"},
        {markerX: 96, markerY: 209, mkrTitle: "t5", mkrAction: "http://www.google.com"},
        {markerX: 122, markerY: 762, mkrTitle: "t6", mkrAction: "http://www.google.com"}
    ]

    var x = [];
    var y = [];
    var title = [];
    var action = [];

    Object.keys(mkr).forEach(function(key) {

      var valX = mkr[key]["markerX"];
      var valY = mkr[key]["markerY"];
      var valT = mkr[key]["mkrTitle"];
      var valA = mkr[key]["mkrAction"];

      x.push(valX);
      y.push(valY);
      title.push(valT);
      action.push(valA);

      var c = document.getElementById("mCanvas");
      //EDIT:
      var cLeft = c.offsetLeft;
      var cTop = c.offsetTop;
      //
      var ctx = c.getContext("2d");
      var img = document.getElementById("marker");
      ctx.drawImage(img, val, val2);

      //EDIT:
    c.addEventListener('click', function(event) {
                valX = event.pageX - cLeft,
                valY = event.pageY - cTop;
                console.log(x, y);
                mkr.forEach(function(img) {
                    if (valY > img.top && valY < img.top + img.height && valX > img.left && valX < img.left + img.width) {
                        ctx.fillText = mkr.valA;
                        window.location.href = mkr.valA;
                    }
                });

            }, false);

    });

And the HTML:

<img src="img/marker.png" id="marker" style="display: none;" />
<canvas id="mCanvas" width="295" height="809"></canvas> <!-- where are the markers -->
<canvas id="mapCanvas" width="600" height="600"></canvas> <!-- where is the background image -->

I can retrieve the data from the Array, but I can not include them as image attributes. My intent is to add click event on each image (markers) that I have over the map, using the data from the "mkrAction" item.

EDIT: As suggested, I have included the addEventListener code to try it, but simply it didn't work. Nothing happens, neither error on console... Where am I doing wrong?

Atoyansk
  • 233
  • 5
  • 20
  • 1
    Why use `Object.keys()` on an array? `mkr.forEach` will suffice – haim770 Feb 20 '17 at 08:47
  • haim770's suggestion is a good one, just note that the object passed to the function will be the object at the index itself instead of a key. You can also obtain canvas context once outside the loop. For text you can use fillText(). Though, there is not really a question in the question... –  Feb 20 '17 at 08:55
  • What do you mean by "include them as image attributes" ? You're not creating HTML `img` elements, you're drawing the images on the canvas. If you want to respond to click and hover events on those markers (the images drawn on the canvas) you'll have to set events listeners to the canvas and check the pointer position to see if it is over one of the markers. – Titus Feb 20 '17 at 08:56
  • haim770 yes, I can change using forEach, but would it change the way to solve the problem? If so, I could edit the code above... – Atoyansk Feb 20 '17 at 09:02
  • For the href just add a click listener to your image/canvas or where you want to be triggered (not really clear from the question) – rakwaht Feb 20 '17 at 09:03
  • Titus, Can I use the data of positions that I already have to find the point to call the event? May you give me some example of it? – Atoyansk Feb 20 '17 at 09:26
  • Yes you can use the position data because you're using it when you draw the images, beside the position you also need the images' size. Here is an example of responding to clicks on shapes drawn on a canvas http://stackoverflow.com/a/9880302/1552587 – Titus Feb 20 '17 at 09:32
  • Beside the click implementation in that example you'll also need to do something similar for hover events to draw the markers' title. – Titus Feb 20 '17 at 09:34
  • If you're dealing with maps and markers you should take a look at the [Google Maps JavaScript API](https://developers.google.com/maps/documentation/javascript/) – Titus Feb 20 '17 at 09:37
  • Titus, it's not a real map, just an image with some effects. But I think that your example above will be what I need. – Atoyansk Feb 20 '17 at 09:52

1 Answers1

0

Probably you need something like this...

NOTE: I used two different markers so you can notice that is working.

Edited: I modified the code to make every element clickable. You will get an alert with the name of the element.

window.onload = function() {
  mkr = [
        {markerX: 10, markerY: 80, mkrTitle: "t1", mkrAction: "http://www.google.com"},
        {markerX: 210, markerY: 93, mkrTitle: "t2", mkrAction: "http://www.google.com"},
        {markerX: 122, markerY: 82, mkrTitle: "t3", mkrAction: "http://www.google.com"},
        {markerX: 190, markerY: 190, mkrTitle: "t4", mkrAction: "http://www.google.com"},
        {markerX: 96, markerY: 209, mkrTitle: "t5", mkrAction: "http://www.google.com"},
        {markerX: 23, markerY: 262, mkrTitle: "t6", mkrAction: "http://www.google.com"}
  ]


  var x = [];
  var y = [];
  var title = [];
  var action = [];

  var c = document.getElementById("mCanvas");
  var elemLeft = c.offsetLeft;
  var elemTop = c.offsetTop;
  var ctx = c.getContext("2d");
  var img = document.getElementById("marker");

  mkr.forEach(function(key) {
    var valX = key["markerX"];
    var valY = key["markerY"];
    var valTitle = key["mkrTitle"];
    var valAction = key["mkrAction"];

    x.push(valX);
    y.push(valY);
    title.push(valTitle);
    action.push(valAction);

    var c = document.getElementById("mCanvas");
    var ctx = c.getContext("2d");
    var img = document.getElementById("marker");
    ctx.drawImage(img, valX, valY);
  });


  // Add event listener for `click` events.
  c.addEventListener('click', function(event) {
    var x = event.pageX - elemLeft,
      y = event.pageY - elemTop;

    // Collision detection between clicked offset and element.
    mkr.forEach(function(element) {
      if (y > element["markerY"] && y < element["markerY"] + 100 &&
        x > element["markerX"] && x < element["markerX"] + 100) {
        alert('clicked on element: ' + element["mkrTitle"]);
      }
    });

  }, false);
};
<img src="http://tsurumimexico.com/wp-content/uploads/2016/10/redmap-1.png" id="marker" style="display: none;" />
<img src="http://longboard-masterclass.com/wp-content/uploads/2016/10/Location_Icon_black_Longboard-Masterclass.png" id="marker2" style="display: none;" />
<!-- where are the markers -->
<canvas id="mCanvas" width="400" height="400"></canvas>
<!-- where is the background image -->
<canvas id="mapCanvas" width="600" height="600"></canvas>
Teocci
  • 7,189
  • 1
  • 50
  • 48
  • Teocci, sorry I didn't understand... My issue is to include event click, using the data inside the "mkrAction" as link for each image on the Canvas. All of the images must be the same. – Atoyansk Feb 20 '17 at 09:45
  • All these 6 elements are clickable now – Teocci Feb 21 '17 at 07:51