Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jQuery to change image map coord values

I have a pretty complex image map that I would like to shrink by half. To do so would require dividing all the coord values by 2. Since there are thousands of coord values, I was thinking that I could use jQuery to traverse the DOM to find the coord values, and divide them by two. I'm pretty amateur when it comes to JavaScript and jQuery and I wrote the following code that doesn't work to accomplish my task:

$(function(){
    $('area').each(function(){
        coord_vals= $('area'[coords]).split(',');
        new_vals= coord_vals/2;
        $('area'[coords]).val(new_vals + ',');
    });
});

Here's the first few lines of HTML I'm trying to traverse:

<div id="map">
    <img class="map" src="images/us_map.jpg" width="960" height="593" usemap="#usa">
    <map name="usa">
    <area href="#" title="SC" shape="poly" coords="735,418, 734,419, 731,418, 731,416, 729,413, 727,411, 725,410, 723,405, 720,399, 716,398, 714,396, 713,393, 711,391, 709,390, 707,387, 704,385, 699,383, 699,382, 697,379, 696,378, 693,373, 690,373, 686,371, 684,369, 684,368, 685,366, 687,365, 687,363, 693,360, 701,356, 708,355, 724,355, 727,356, 728,360, 732,359, 745,358, 747,358, 760,366, 769,374, 764,379, 762,385, 761,391, 759,392, 758,394, 756,395, 754,398, 751,401, 749,404, 748,405, 744,408, 741,409, 742,412, 737,417, 735,418"></area>
    <area href="#" title="HI" shape="poly" coords="225,521, 227,518, 229,517, 229,518, 227,521, 225,521"></area>
    <area href="#" title="HI" shape="poly" coords="235,518, 241,520, 243,520, 244,516, 244,513, 240,512, 236,514, 235,518"></area>
like image 516
user306472 Avatar asked Dec 17 '22 22:12

user306472


2 Answers

You can do it like this:

$("area").each(function() {
    var pairs = $(this).attr("coords").split(', ');
    for(var i=0; i<pairs.length; i++) {
        var nums = pairs[i].split(',');
        for(var j=0; j<nums.length; j++) {
            nums[j] = parseFloat(nums[j]) /2;
        }
        pairs[i] = nums.join(',');
    }
    $(this).attr("coords", pairs.join(', '));
});

This maintains the formats and converts each valid carefully, here's the output:

<div id="map">
  <img class="map" src="images/us_map.jpg" width="960" height="593" usemap="#usa"> 
  <map name="usa"> 
    <area href="#" title="SC" shape="poly" coords="367.5,209, 367,209.5, 365.5,209, 365.5,208, 364.5,206.5, 363.5,205.5, 362.5,205, 361.5,202.5, 360,199.5, 358,199, 357,198, 356.5,196.5, 355.5,195.5, 354.5,195, 353.5,193.5, 352,192.5, 349.5,191.5, 349.5,191, 348.5,189.5, 348,189, 346.5,186.5, 345,186.5, 343,185.5, 342,184.5, 342,184, 342.5,183, 343.5,182.5, 343.5,181.5, 346.5,180, 350.5,178, 354,177.5, 362,177.5, 363.5,178, 364,180, 366,179.5, 372.5,179, 373.5,179, 380,183, 384.5,187, 382,189.5, 381,192.5, 380.5,195.5, 379.5,196, 379,197, 378,197.5, 377,199, 375.5,200.5, 374.5,202, 374,202.5, 372,204, 370.5,204.5, 371,206, 368.5,208.5, 367.5,209">
    <area href="#" title="HI" shape="poly" coords="112.5,260.5, 113.5,259, 114.5,258.5, 114.5,259, 113.5,260.5, 112.5,260.5">
    <area href="#" title="HI" shape="poly" coords="117.5,259, 120.5,260, 121.5,260, 122,258, 122,256.5, 120,256, 118,257, 117.5,259"> 
  </map>
</div>

You can give it a try here.

like image 99
Nick Craver Avatar answered Dec 27 '22 13:12

Nick Craver


I know you said you're just shrinking your image map by half, but I thought I'd give you a bit of code that would make your map responsive. As the image that is using the map is re-sized, the coords change appropriately.

First thing it does is store the original coordinates of the image map, and then runs the function mapResize whenever the page re-sizes.

$(function() {
  $("area").each(function() { $(this).attr('data-coords', $(this).attr('coords')) });
  $(window).resize(mapResize);
  setTimeout(mapResize, 1);
});

var mapResize = function() {

Here you'll see that we grab the image that is using the usemap name. This is here in case you have any other maps on the site that you'd like to use as well.

Then the code divides the images current width by its original width. We later use that number multiplied by the coordinates to give the new value of the coords.

  $("map").each(function() {
    var img = $("img[usemap='#" + $(this).attr("name") + "']");

    if (img[0].naturalWidth) {
      widthchange = img.width() / img[0].naturalWidth;
    }
    else {
      widthchange = 1;
      setTimeout(mapResize, 1000);
    }
    //borrowed this from Nick's answer.  It was spot on!
    $("area").each(function() {
      var pairs = $(this).attr("data-coords").split(', ');
      for(var i=0; i<pairs.length; i++) {
          var nums = pairs[i].split(',');
          for(var j=0; j<nums.length; j++) {
              nums[j] = parseFloat(nums[j]) * widthchange;
          }
          pairs[i] = nums.join(',');
      }
      $(this).attr("coords", pairs.join(', '));
    });
  });
}

So yeah, that might not be the answer to your exact question, but I think it answers your question and goes a bit further.

I also know this is a 2 year old question, but I was searching for an answer to a question of my own and this was the most helpful thread. Just wanted to add in my adjustment =)

like image 20
dannycodes Avatar answered Dec 27 '22 14:12

dannycodes