0

I want to be able to scale a polygon of an image on hover.

To be precise, its a world-map, and I want to scale the country bigger, when you hover over it, and then make it smaller again, when not hovering any more.

I know, that there is the transform: scale(2) for CSS for example, and it works fine with normal images or also with world map. But actually I don't want to scale the hole map, but a polygon of the map (or at least, if a polygon is not possible, then a square (so only a little part of the map).

Is there any way to do this? Doesn't have to be CSS only, can also be JS/jQuery.

The hover part is not part of the question, thats simple jQuery, but the question is how to scale only a specific part of an image.

Thanks for any help!

nameless
  • 1,483
  • 5
  • 32
  • 78
  • You’d have to have one image per country to do that, or a big SVG where each country is a separate feature. – bfontaine Oct 01 '17 at 11:43
  • Is using a canvas element an available option for you? – enhzflep Oct 01 '17 at 11:44
  • @bfontaine what do you mean with "seperate feature"? Actually, the image is really huge (is has a width of 6400px), but its only displayed in about 1000px width, so I would have enough image size to show it 6 times as big and still be clear – nameless Oct 01 '17 at 11:45
  • @enhzflep sure, every option working is welcome. – nameless Oct 01 '17 at 11:46
  • @nameless you need a way to separate each country from the others; I’m thinking about something like this: http://simplemaps.com/resources/svg-world – bfontaine Oct 01 '17 at 11:48
  • @bfontaine can I not use pixeldata for that? I already defined a polygon (an area) for every country I need, so I know the borders of every country – nameless Oct 01 '17 at 11:49
  • You might be able to do something with a canvas but if you can SVG would be an easier solution. It’ll also give you the highest image quality. – bfontaine Oct 01 '17 at 11:51
  • @bfontaine actually the map is a little bit customized and there are few other things which already deepend on this map, so it would be very very much effort to use another map... how could a solution with canvas look? – nameless Oct 01 '17 at 11:53
  • @nameless I’m less familiar with the canvas but it seems you can select polygons so I guess you can manipulate them: https://stackoverflow.com/q/12128073/735926 – bfontaine Oct 01 '17 at 11:57
  • @bfontaine another idea I just had now: what if I would really have every country as a seperate image and put that image in something like a tooltip when hovering? – nameless Oct 01 '17 at 11:59
  • @nameless - then you can use javascript and a canvas for the task. When an area is hovered, an event fires. Inside the handler, you get the co-ords for the polygon hovered. You then create a canvas of that size, copy the image inside the polygon to it, before showing the canvas at whatever size you want. It's a little work, but presents the most general solution. Just need an image and an image-map. I'll have a play if I get enough spare time. (don't hold your breath waiting for me!) Consider: https://stackoverflow.com/questions/12661124/how-to-apply-hovering-on-html-area-tag/12667751#12667751 – enhzflep Oct 01 '17 at 12:09
  • @enhzflep okay, especially the part when copying the image in a canvas and then showing this "scaled" canvas would be the interesting part for me. I already can react on the hover of the area and I also have an image-map already. The only part which is "critical" for me, is how to copy the polygon of the image in a canvas then, resize it (make it bigger) and then show it as something like a tooltip or popover or whatever and then have it disappear again, when not hovering any more – nameless Oct 01 '17 at 12:12
  • @nameless - I imagine I'd create a second canvas that I used as a mask. I reckon it would involve an empty canvas with either a black or white polygon in the appropriate place. Combined with canvas compositing modes, it would make copying the right part of the image easy-peasy (you 'draw' a rectangular are of the image, but only the appropriate part ends up on the target canvas) From there, I'd be using z-order to position the resultant canvas in front of the initial image. Too tired to think clearly now, I'm sorry to not be more useful. :( – enhzflep Oct 01 '17 at 12:22
  • @enhzflep alright, I'll give that a try, if you have further tips or code snippets / sketches for it, feel free :) – nameless Oct 01 '17 at 12:23

2 Answers2

1

It's been a noisy night here. So I've thrown together something to play with. It's an incomplete implementation - I just grab the part of the image hovered and throw it into a picture along-side the original.

It's up to you to (0) show the image larger than full size (1) position it in front of the original, using absolute positioning and z-index (2) handle mouseout on the hovered area.

The answer I linked to in the comments demonstrates positioning, z-ordering and passing pointer events to the underlying map elements.

You'll need to decide just how/where you wish the enlarged version to appear. Perhaps you'd want it 150%, with the center-point atop the center-point of the map element.

As the comments indicate, you'd normally use an existing image, rather than creating one from scratch, as I've done here.

First, the complete source in a single piece - just copy it all and past into a new html file.

<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
window.addEventListener('load', onDocLoaded, false);


function onDocLoaded(e)
{
    createImageFromMapAreasForUseAtStackoverflow();
    attachHoverHandlers();
}


// this function is only used for the purpose of answering this question. 
// Ordinarily, you would set the src of #img1 to be that of your image. - since cross-origin contamination prevents
//  access to the image data if the image comes from a different server, I've just opted to create the image from scratch.
//
// the original image may be found here: https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Australia_location_map_recolored.png/500px-Australia_location_map_recolored.png
function createImageFromMapAreasForUseAtStackoverflow()
{
    var imgWidth = 500, imgHeight = 360;
    var can = newEl('canvas');
    can.width = imgWidth;
    can.height = imgHeight;
    var ctx = can.getContext('2d');
    ctx.fillStyle = '#ecf5f6';
    ctx.fillRect(0,0,imgWidth,imgHeight);

    var areas = document.querySelectorAll('area');
    var i, n = areas.length;
    var colours = ['#f4f100', '#b2d025', '#f67c60', '#8fbce1', '#f4f236', '#fca164', '#bc9eee', 'black'];

    for (i=0; i<n; i++)
    {
        var areaType = areas[i].getAttribute('shape');
        if ((areaType == 'polygon') || (areaType == 'poly'))
            drawMapPoly(areas[i].getAttribute('coords'), colours[i]);
    }
    byId('img1').src = can.toDataURL();

    function drawMapPoly(coordStr, colour)
    {
        ctx.beginPath();
        var ptArray = coordStrToPointArray(coordStr);
        var i, n=ptArray.length;
        ctx.moveTo(ptArray[0].x, ptArray[0].y);
        for (i=0;i<n;i++)
            ctx.lineTo(ptArray[i].x,ptArray[i].y);
        ctx.closePath();
        ctx.fillStyle=colour;
        ctx.fill();
    }
}

function attachHoverHandlers()
{
    //
    // Attach event-listeners to each of the areas in the image-map to handle mouseover
    //
    var areas = document.querySelectorAll('area');
    var i, n = areas.length;
    for (i=0; i<n; i++)
    {
        areas[i].addEventListener('mouseover', onAreaHovered, false);
    }
}

function onAreaHovered(e)
{
    var hoveredElement = this;
    var coordStr = this.getAttribute('coords');
    var areaType = this.getAttribute('shape');

    switch (areaType)
    {
        case 'polygon':
        case 'poly':
            showPolyCoords(coordStr);
            break;

        default:
            alert("You need to add a handler for areas of type '" + areaType + "'");
    }
}

function coordStrToPointArray(coordStr)
{
    var mCoords = coordStr.split(',');
    var i, n = mCoords.length;
    var coordArray = [];

    coordArray.push( new p2d(mCoords[0], mCoords[1]) );
    for (i=2; i<n; i+=2)
    {
        coordArray.push( new p2d(mCoords[i], mCoords[i+1]) );
    }
    coordArray.push( new p2d(mCoords[0], mCoords[1]) );
    return coordArray;
}


// takes a string that contains coords eg - "227,307,261,309, 339,354, 328,371, 240,331"
// draws a line from each co-ord pair to the next - assumes starting point needs to be repeated as ending point.
function showPolyCoords(coOrdStr)
{
    var coordArray = coordStrToPointArray(coOrdStr);

    var sortedArray = coordArray.slice();
    sortedArray.sort(sortX);
    var minX = sortedArray[0].x;
    var maxX = sortedArray[sortedArray.length-1].x;

    sortedArray.sort(sortY);
    var minY = sortedArray[0].y;
    var maxY = sortedArray[sortedArray.length-1].y;

    var topLeft = new p2d(minX, minY);
    var botRight = new p2d(maxX, maxY);

    testFuncWithClipping(topLeft, botRight, 'img1', coordArray);
}

function p2d(x, y)
{
    this.x = Number(x);
    this.y = Number(y);
    return this;
}

// unneccesary - just makes displaying the point easier. 
// Having this prototype available means that (in chrome at least) 
// the code: "console.log( pt2d );" or "alert( pt2d );"  will result in "<xCoord, yCoord>" being printed/alerted
p2d.prototype.toString = function()
{
    return "<"+this.x+", "+this.y+">";
}

// comparison functions used when sorting the point list to obtain the min/max values of both X and Y
function sortX(a, b){return a.x - b.x;}
function sortY(a, b){return a.y - b.y;}

function testFuncWithClipping(topLeft, botRight, srcImgId, pointArray)
{
    var width = botRight.x - topLeft.x;
    var height = botRight.y - topLeft.y;

    var can = newEl('canvas');
    can.width = width;
    can.height = height;
    var ctx = can.getContext('2d');
    var img = byId(srcImgId);

    ctx.beginPath();
    ctx.moveTo( pointArray[0].x - topLeft.x, pointArray[0].y-topLeft.y );
    var i, n = pointArray.length;
    for (i=0; i<n; i++)
    {
        ctx.lineTo( pointArray[i].x - topLeft.x, pointArray[i].y-topLeft.y );
    }
    ctx.clip();

    ctx.drawImage(img, topLeft.x, topLeft.y, width, height, 0,0, width,height);
    byId('img2').src = can.toDataURL();
}
</script>
<style>
body
{
    background-color: gray;
}

#canvas2
{
    pointer-events: none;       /* make the canvas transparent to the mouse - needed since canvas is position infront of image */
    position: absolute;         /* you'll need to use this trick to allow the area to know when the mouse leaves it, so you can hide/destroy the */
}                               /* enlarged version of the hovered area */
</style>
</head>
<body>
    <!-- 
        Usually, you would use this element.
        For the purpose of making a working demo, I've used the next element and have created the picture using the map data and
        the funtion createImageFromMapAreasForUseAtStackoverflow
        As mentioned above, the original image is:
            https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Australia_location_map_recolored.png/500px-Australia_location_map_recolored.png
        which was saved as ausMap.png in the img folder of my localhost.

        <img id='img1' usemap='#imgMap1' src='img/ausMap.png' /> 

    -->
    <img id='img1' usemap='#imgMap1'/>

    <map name='imgMap1' id='imgMap1'>
        <area shape="polygon" coords="359, 324, 373, 332, 392, 327, 393, 346, 375, 356, 364, 343" title="Tasmania">
        <area shape="polygon" coords="325, 258, 335, 258, 339, 265, 346, 265, 347, 271, 357, 279, 360, 279, 361, 276, 368, 278, 380, 279, 388, 277, 390, 288, 406, 293, 405, 296, 391, 297, 377, 308, 376, 310, 372, 308, 356, 303, 350, 307, 338, 303, 332, 301, 325, 300" title="Victoria">
        <area shape="polygon" coords="325, 207, 397, 206, 403, 201, 417, 203, 420, 209, 425, 205, 427, 200, 440, 197, 440, 204, 436, 222, 432, 235, 432, 241, 424, 245, 419, 255, 415, 267, 408, 277, 408, 293, 391, 286, 389, 278, 381, 279, 373, 279, 364, 276, 361, 278, 348, 271, 346, 265, 340, 266, 338, 261, 333, 258, 325, 258" title="New South Wales">
        <area shape="polygon" coords="325, 206, 398, 207, 404, 201, 417, 203, 423, 207, 427, 201, 434, 198, 441, 198, 436, 169, 429, 159, 419, 150, 416, 142, 410, 138, 406, 139, 400, 121, 397, 114, 375, 101, 372, 82, 367, 79, 365, 61, 357, 52, 353, 56, 349, 39, 345, 31, 341, 22, 336, 18, 336, 27, 330, 35, 334, 38, 331, 41, 330, 46, 331, 60, 329, 66, 329, 74, 326, 77, 326, 85, 320, 90, 312, 88, 308, 82, 298, 78, 298, 175, 325, 175" title="Queensland">
        <area shape="polygon" coords="297, 175, 297, 79, 273, 60, 286, 34, 281, 30, 276, 33, 268, 33, 254, 29, 250, 25, 247, 22, 243, 22, 244, 26, 249, 31, 246, 33, 237, 33, 235, 33, 234, 31, 236, 28, 236, 23, 231, 25, 228, 24, 225, 27, 230, 29, 233, 33, 229, 37, 223, 41, 227, 45, 222, 46, 218, 54, 221, 62, 214, 63, 213, 175" title="Northern Territory">
        <area shape="polygon" coords="214, 234, 214, 61, 211, 60, 205, 65, 205, 59, 197, 50, 194, 54, 190, 52, 187, 56, 180, 56, 179, 62, 174, 64, 174, 75, 163, 74, 167, 81, 164, 85, 160, 77, 150, 82, 149, 90, 153, 93, 148, 97, 143, 108, 127, 114, 122, 113, 121, 115, 111, 120, 103, 118, 94, 125, 90, 130, 85, 132, 80, 138, 78, 136, 80, 131, 73, 138, 75, 144, 75, 148, 72, 150, 72, 160, 75, 170, 78, 176, 75, 179, 69, 172, 76, 187, 76, 193, 82, 200, 82, 205, 84, 210, 84, 218, 91, 234, 92, 241, 93, 250, 90, 253, 86, 253, 86, 261, 92, 262, 99, 269, 112, 269, 125, 263, 132, 256, 145, 254, 164, 257, 168, 248, 172, 248, 186, 241, 192, 242" title="Western Australia">
        <area shape="polygon" coords="324, 299, 323, 175, 213, 175, 213, 234, 233, 232, 242, 238, 249, 236, 261, 242, 258, 246, 265, 249, 269, 256, 270, 261, 272, 263, 277, 267, 277, 261, 281, 257, 288, 254, 291, 249, 295, 246, 295, 243, 297, 250, 294, 254, 290, 259, 291, 265, 287, 269, 294, 268, 297, 262, 301, 268, 299, 272, 295, 275, 290, 273, 285, 274, 283, 277, 290, 278, 294, 275, 301, 273, 315, 286, 314, 291" title="South Australia">
        <area shape='rect' coords='0,0,100,100' title='unsupported area type'>
    </map>
    <img id='img2'/>
</body>
</html>

Next, a working demo that you can try right here on the page (use full-screen for the best experience)

"use strict";
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
window.addEventListener('load', onDocLoaded, false);


function onDocLoaded(e)
{
 createImageFromMapAreasForUseAtStackoverflow();
 attachHoverHandlers();
}


// this function is only used for the purpose of answering this question. 
// Ordinarily, you would set the src of #img1 to be that of your image. - since cross-origin contamination prevents
//  access to the image data if the image comes from a different server, I've just opted to create the image from scratch.
//
// the original image may be found here: https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Australia_location_map_recolored.png/500px-Australia_location_map_recolored.png
function createImageFromMapAreasForUseAtStackoverflow()
{
 var imgWidth = 500, imgHeight = 360;
 var can = newEl('canvas');
 can.width = imgWidth;
 can.height = imgHeight;
 var ctx = can.getContext('2d');
 ctx.fillStyle = '#ecf5f6';
 ctx.fillRect(0,0,imgWidth,imgHeight);
 
 var areas = document.querySelectorAll('area');
 var i, n = areas.length;
 var colours = ['#f4f100', '#b2d025', '#f67c60', '#8fbce1', '#f4f236', '#fca164', '#bc9eee', 'black'];
 
 for (i=0; i<n; i++)
 {
  var areaType = areas[i].getAttribute('shape');
  if ((areaType == 'polygon') || (areaType == 'poly'))
   drawMapPoly(areas[i].getAttribute('coords'), colours[i]);
 }
 byId('img1').src = can.toDataURL();

 function drawMapPoly(coordStr, colour)
 {
  ctx.beginPath();
  var ptArray = coordStrToPointArray(coordStr);
  var i, n=ptArray.length;
  ctx.moveTo(ptArray[0].x, ptArray[0].y);
  for (i=0;i<n;i++)
   ctx.lineTo(ptArray[i].x,ptArray[i].y);
  ctx.closePath();
  ctx.fillStyle=colour;
  ctx.fill();
 }
}

function attachHoverHandlers()
{
 //
 // Attach event-listeners to each of the areas in the image-map to handle mouseover
 //
 var areas = document.querySelectorAll('area');
 var i, n = areas.length;
 for (i=0; i<n; i++)
 {
  areas[i].addEventListener('mouseover', onAreaHovered, false);
 }
}

function onAreaHovered(e)
{
 var hoveredElement = this;
 var coordStr = this.getAttribute('coords');
 var areaType = this.getAttribute('shape');

 switch (areaType)
 {
  case 'polygon':
  case 'poly':
   showPolyCoords(coordStr);
   break;

  default:
   alert("You need to add a handler for areas of type '" + areaType + "'");
 }
}

function coordStrToPointArray(coordStr)
{
 var mCoords = coordStr.split(',');
 var i, n = mCoords.length;
 var coordArray = [];
 
 coordArray.push( new p2d(mCoords[0], mCoords[1]) );
 for (i=2; i<n; i+=2)
 {
  coordArray.push( new p2d(mCoords[i], mCoords[i+1]) );
 }
 coordArray.push( new p2d(mCoords[0], mCoords[1]) );
 return coordArray;
}


// takes a string that contains coords eg - "227,307,261,309, 339,354, 328,371, 240,331"
// draws a line from each co-ord pair to the next - assumes starting point needs to be repeated as ending point.
function showPolyCoords(coOrdStr)
{
 var coordArray = coordStrToPointArray(coOrdStr);
 
 var sortedArray = coordArray.slice();
 sortedArray.sort(sortX);
 var minX = sortedArray[0].x;
 var maxX = sortedArray[sortedArray.length-1].x;

 sortedArray.sort(sortY);
 var minY = sortedArray[0].y;
 var maxY = sortedArray[sortedArray.length-1].y;
 
 var topLeft = new p2d(minX, minY);
 var botRight = new p2d(maxX, maxY);

 testFuncWithClipping(topLeft, botRight, 'img1', coordArray);
}

function p2d(x, y)
{
 this.x = Number(x);
 this.y = Number(y);
 return this;
}

// unneccesary - just makes displaying the point easier. 
// Having this prototype available means that (in chrome at least) 
// the code: "console.log( pt2d );" or "alert( pt2d );"  will result in "<xCoord, yCoord>" being printed/alerted
p2d.prototype.toString = function()
{
 return "<"+this.x+", "+this.y+">";
}

// comparison functions used when sorting the point list to obtain the min/max values of both X and Y
function sortX(a, b){return a.x - b.x;}
function sortY(a, b){return a.y - b.y;}

function testFuncWithClipping(topLeft, botRight, srcImgId, pointArray)
{
 var width = botRight.x - topLeft.x;
 var height = botRight.y - topLeft.y;
 
 var can = newEl('canvas');
 can.width = width;
 can.height = height;
 var ctx = can.getContext('2d');
 var img = byId(srcImgId);
 
 ctx.beginPath();
 ctx.moveTo( pointArray[0].x - topLeft.x, pointArray[0].y-topLeft.y );
 var i, n = pointArray.length;
 for (i=0; i<n; i++)
 {
  ctx.lineTo( pointArray[i].x - topLeft.x, pointArray[i].y-topLeft.y );
 }

 // comment the below line to see the effect of drawing a rectangular
 // portion of the image without clipping.
 ctx.clip();
 
 ctx.drawImage(img, topLeft.x, topLeft.y, width, height, 0,0, width,height);
 byId('img2').src = can.toDataURL();
}
body
{
 background-color: gray;
}

#canvas2
{
 pointer-events: none;  /* make the canvas transparent to the mouse - needed since canvas is position infront of image */
 position: absolute;   /* you'll need to use this trick to allow the area to know when the mouse leaves it, so you can hide/destroy the */
}        /* enlarged version of the hovered area */
 <!-- 
  Usually, you would use this element.
  For the purpose of making a working demo, I've used the next element and have created the picture using the map data and
  the funtion createImageFromMapAreasForUseAtStackoverflow
  As mentioned above, the original image is:
   https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Australia_location_map_recolored.png/500px-Australia_location_map_recolored.png
  which was saved as ausMap.png in the img folder of my localhost.
  
  <img id='img1' usemap='#imgMap1' src='img/ausMap.png' /> 
  
 -->
 <img id='img1' usemap='#imgMap1'/>
 
 <map name='imgMap1' id='imgMap1'>
  <area shape="polygon" coords="359, 324, 373, 332, 392, 327, 393, 346, 375, 356, 364, 343" title="Tasmania">
  <area shape="polygon" coords="325, 258, 335, 258, 339, 265, 346, 265, 347, 271, 357, 279, 360, 279, 361, 276, 368, 278, 380, 279, 388, 277, 390, 288, 406, 293, 405, 296, 391, 297, 377, 308, 376, 310, 372, 308, 356, 303, 350, 307, 338, 303, 332, 301, 325, 300" title="Victoria">
  <area shape="polygon" coords="325, 207, 397, 206, 403, 201, 417, 203, 420, 209, 425, 205, 427, 200, 440, 197, 440, 204, 436, 222, 432, 235, 432, 241, 424, 245, 419, 255, 415, 267, 408, 277, 408, 293, 391, 286, 389, 278, 381, 279, 373, 279, 364, 276, 361, 278, 348, 271, 346, 265, 340, 266, 338, 261, 333, 258, 325, 258" title="New South Wales">
  <area shape="polygon" coords="325, 206, 398, 207, 404, 201, 417, 203, 423, 207, 427, 201, 434, 198, 441, 198, 436, 169, 429, 159, 419, 150, 416, 142, 410, 138, 406, 139, 400, 121, 397, 114, 375, 101, 372, 82, 367, 79, 365, 61, 357, 52, 353, 56, 349, 39, 345, 31, 341, 22, 336, 18, 336, 27, 330, 35, 334, 38, 331, 41, 330, 46, 331, 60, 329, 66, 329, 74, 326, 77, 326, 85, 320, 90, 312, 88, 308, 82, 298, 78, 298, 175, 325, 175" title="Queensland">
  <area shape="polygon" coords="297, 175, 297, 79, 273, 60, 286, 34, 281, 30, 276, 33, 268, 33, 254, 29, 250, 25, 247, 22, 243, 22, 244, 26, 249, 31, 246, 33, 237, 33, 235, 33, 234, 31, 236, 28, 236, 23, 231, 25, 228, 24, 225, 27, 230, 29, 233, 33, 229, 37, 223, 41, 227, 45, 222, 46, 218, 54, 221, 62, 214, 63, 213, 175" title="Northern Territory">
  <area shape="polygon" coords="214, 234, 214, 61, 211, 60, 205, 65, 205, 59, 197, 50, 194, 54, 190, 52, 187, 56, 180, 56, 179, 62, 174, 64, 174, 75, 163, 74, 167, 81, 164, 85, 160, 77, 150, 82, 149, 90, 153, 93, 148, 97, 143, 108, 127, 114, 122, 113, 121, 115, 111, 120, 103, 118, 94, 125, 90, 130, 85, 132, 80, 138, 78, 136, 80, 131, 73, 138, 75, 144, 75, 148, 72, 150, 72, 160, 75, 170, 78, 176, 75, 179, 69, 172, 76, 187, 76, 193, 82, 200, 82, 205, 84, 210, 84, 218, 91, 234, 92, 241, 93, 250, 90, 253, 86, 253, 86, 261, 92, 262, 99, 269, 112, 269, 125, 263, 132, 256, 145, 254, 164, 257, 168, 248, 172, 248, 186, 241, 192, 242" title="Western Australia">
  <area shape="polygon" coords="324, 299, 323, 175, 213, 175, 213, 234, 233, 232, 242, 238, 249, 236, 261, 242, 258, 246, 265, 249, 269, 256, 270, 261, 272, 263, 277, 267, 277, 261, 281, 257, 288, 254, 291, 249, 295, 246, 295, 243, 297, 250, 294, 254, 290, 259, 291, 265, 287, 269, 294, 268, 297, 262, 301, 268, 299, 272, 295, 275, 290, 273, 285, 274, 283, 277, 290, 278, 294, 275, 301, 273, 315, 286, 314, 291" title="South Australia">
  <area shape='rect' coords='0,0,100,100' title='unsupported area type'>
 </map>
 <img id='img2'/>

Have fun!

enhzflep
  • 12,927
  • 2
  • 32
  • 51
  • Wow, thank you so much. I'll have a precise look at it as soon as possible and try to implement it among the other things needed (0,1, 2) and then come back to you if everything worked. But thanks for that much effort! – nameless Oct 02 '17 at 05:32
  • One direct question, scanning the code: What is the `colours` array for? Just to color the copied polygon? Cause my map would have always the same color. Can I simply add one color to the array or what would be neded then? – nameless Oct 02 '17 at 05:34
  • And another thing (just quickly tried it and it's generally working fine for my page as well which is awesome). With the normal `scale`-function, the poly gets blurry then, which is not what I want...Actually, as already mentioned in the comments: the image is really huge (is has a width of 6400px), but its only displayed in about 1000px width, so I would have enough image size to show it 6 times as big and still be clear.... But of course, I cut the poly from the smaller version.. Is there a way, to cut the polygons from a image that is not displayed at all? (when providing the areas?) – nameless Oct 02 '17 at 05:47
  • @nameless - I suppose to do that, you'd just need to know the precise ratio between the displayed size and the actual size. Once this is known, you could scale the polygon coords by the same amount and they would then be accurate for the larger image. Certainly, the larger source image needn't be visible on the page. :) Another thing you can do, is set the `. imageSmoothingEnabled` flag of the context (the context is the result of canvas.getContext('2d') call) setting it to true will help smooth things out a bit, but your idea to grab part of the full-size image will almost certainly be better – enhzflep Oct 02 '17 at 06:02
  • Oh, sorry I missed your question about the colours - yes. The colours array is simply used for creating the image from scratch. I just used an eye-dropper on the states in the png image I downloaded. You don't need to use that array at all. That's why I put it inside the drawing function, `createImageFromMapAreasForUseAtStackoverflow` – enhzflep Oct 02 '17 at 06:13
  • alright, thanks for that information. I'll try that as soon as I find some time. Thank you so much :) – nameless Oct 02 '17 at 16:09
-1

I would honestly make every country its own image and rescale that on hover. Image effects aren't very well supported in JS/jQuery/CSS and if you don't want multiple images then I would start looking for a library to do that for you.

For instance you might want to consider using Pieces

Another possibility would be to use canvas or svg to draw your map and make it interactive using JS.

SourceOverflow
  • 1,960
  • 1
  • 8
  • 22