响应式图像映射

时间:2011-10-21 02:39:14

标签: html css imagemap

我在响应式html布局中有一个现有的图像映射。图像根据浏览器大小进行缩放,但图像坐标显然是固定的像素大小。我有什么选项来调整图像地图坐标的大小?

19 个答案:

答案 0 :(得分:83)

对于自适应图像地图,您需要使用插件:

https://github.com/stowball/jQuery-rwdImageMaps(不再维护)

或者

https://github.com/davidjbradshaw/imagemap-resizer


  

没有主流浏览器正确理解百分比坐标,以及所有   将百分比坐标解释为像素坐标。

http://www.howtocreate.co.uk/tutorials/html/imagemaps

此页面还用于测试浏览器是否实现

http://home.comcast.net/~urbanjost/IMG/resizeimg3.html

答案 1 :(得分:39)

答案 2 :(得分:33)

您也可以使用svg代替图像映射。 ;)

how to do this.

上有一个教程



.hover_group:hover {
  opacity: 1;
}
#projectsvg {
  position: relative;
  width: 100%;
  padding-bottom: 77%;
  vertical-align: middle;
  margin: 0;
  overflow: hidden;
}
#projectsvg svg {
  display: inline-block;
  position: absolute;
  top: 0;
  left: 0;
}

<figure id="projectsvg">
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1080" preserveAspectRatio="xMinYMin meet" >
<!-- set your background image -->
<image width="1920" height="1080" xlink:href="http://placehold.it/1920x1080" />
<g class="hover_group" opacity="0">
  <a xlink:href="https://example.com/link1.html">
    <text x="652" y="706.9" font-size="20">First zone</text>
    <rect x="572" y="324.1" opacity="0.2" fill="#FFFFFF" width="264.6" height="387.8"></rect>
  </a>
</g>
<g class="hover_group" opacity="0">
  <a xlink:href="https://example.com/link2.html">
    <text x="1230.7" y="952" font-size="20">Second zone</text>
    <rect x="1081.7" y="507" opacity="0.2" fill="#FFFFFF" width="390.2" height="450"></rect>
  </a>
</g>
  </svg>
</figure>
&#13;
&#13;
&#13;

答案 3 :(得分:14)

我遇到了一个根本没有使用图像映射的解决方案,而是在图像上绝对定位的锚标签。唯一的缺点是热点必须是矩形的,但优点是这个解决方案并不依赖于Javascript,只有CSS。有一个网站可用于生成锚点的HTML代码:http://www.zaneray.com/responsive-image-map/

我将图像和生成的锚标签放在相对定位的div标签中,一切都在窗口调整大小和手机上完美运行。

答案 4 :(得分:11)

David Bradshaw写了一个很好的小库来解决这个问题。它可以在有或没有jQuery的情况下使用。

此处可用:https://github.com/davidjbradshaw/imagemap-resizer

答案 5 :(得分:6)

以下方法对我来说非常合适,所以这是我的完整实现:​​

<img id="my_image" style="display: none;" src="my.png" width="924" height="330" border="0" usemap="#map" />

<map name="map" id="map">
    <area shape="poly" coords="774,49,810,21,922,130,920,222,894,212,885,156,874,146" href="#mylink" />
    <area shape="poly" coords="649,20,791,157,805,160,809,217,851,214,847,135,709,1,666,3" href="#myotherlink" />
</map>

<script>
$(function(){
    var image_is_loaded = false;
    $("#my_image").on('load',function() {
        $(this).data('width', $(this).attr('width')).data('height', $(this).attr('height'));
        $($(this).attr('usemap')+" area").each(function(){
            $(this).data('coords', $(this).attr('coords'));
        });

        $(this).css('width', '100%').css('height','auto').show();

        image_is_loaded = true;
        $(window).trigger('resize');
    });


    function ratioCoords (coords, ratio) {
        coord_arr = coords.split(",");

        for(i=0; i < coord_arr.length; i++) {
            coord_arr[i] = Math.round(ratio * coord_arr[i]);
        }

        return coord_arr.join(',');
    }
    $(window).on('resize', function(){
        if (image_is_loaded) {
            var img = $("#my_image");
            var ratio = img.width()/img.data('width');

            $(img.attr('usemap')+" area").each(function(){
                console.log('1: '+$(this).attr('coords'));
                $(this).attr('coords', ratioCoords($(this).data('coords'), ratio));
            });
        }
    });
});
</script>

答案 6 :(得分:4)

You can get responsive map image using the below link

window.onload = function () {
    var ImageMap = function (map, img) {
            var n,
                areas = map.getElementsByTagName('area'),
                len = areas.length,
                coords = [],
                previousWidth = 128;
            for (n = 0; n < len; n++) {
                coords[n] = areas[n].coords.split(',');
            }
            this.resize = function () {
                var n, m, clen,
                    x = img.offsetWidth / previousWidth;
                for (n = 0; n < len; n++) {
                    clen = coords[n].length;
                    for (m = 0; m < clen; m++) {
                        coords[n][m] *= x;
                    }
                    areas[n].coords = coords[n].join(',');
                }
                previousWidth = document.body.clientWidth;
                return true;
            };
            window.onresize = this.resize;
        },
        imageMap = new ImageMap(document.getElementById('map_ID'), document.getElementById('img_ID'));
    imageMap.resize();
    return;
}
<div style="width:100%;">
    <img id="img_ID" src="http://www.gravatar.com/avatar/0865e7bad648eab23c7d4a843144de48?s=128&d=identicon&r=PG" usemap="#map" border="0" width="100%" alt="" />
</div>
<map id="map_ID" name="map">
<area shape="poly" coords="48,10,80,10,65,42" href="javascript:;" alt="Bandcamp" title="Bandcamp" />
<area shape="poly" coords="30,50,62,50,46,82" href="javascript:;" alt="Facebook" title="Facebook" />
<area shape="poly" coords="66,50,98,50,82,82" href="javascript:;" alt="Soundcloud" title="Soundcloud" />
</map>

答案 7 :(得分:3)

为我工作(记得在代码中更改3件事):

  • previousWidth(图片的原始尺寸)

  • map_ID(图片地图的ID)

  • img_ID(您图片的ID)

HTML:

<div style="width:100%;">
    <img id="img_ID" src="http://www.gravatar.com/avatar/0865e7bad648eab23c7d4a843144de48?s=128&d=identicon&r=PG" usemap="#map" border="0" width="100%" alt="" />
</div>
<map id="map_ID" name="map">
<area shape="poly" coords="48,10,80,10,65,42" href="javascript:;" alt="Bandcamp" title="Bandcamp" />
<area shape="poly" coords="30,50,62,50,46,82" href="javascript:;" alt="Facebook" title="Facebook" />
<area shape="poly" coords="66,50,98,50,82,82" href="javascript:;" alt="Soundcloud" title="Soundcloud" />
</map>

使用Javascript:

window.onload = function () {
    var ImageMap = function (map, img) {
            var n,
                areas = map.getElementsByTagName('area'),
                len = areas.length,
                coords = [],
                previousWidth = 128;
            for (n = 0; n < len; n++) {
                coords[n] = areas[n].coords.split(',');
            }
            this.resize = function () {
                var n, m, clen,
                    x = img.offsetWidth / previousWidth;
                for (n = 0; n < len; n++) {
                    clen = coords[n].length;
                    for (m = 0; m < clen; m++) {
                        coords[n][m] *= x;
                    }
                    areas[n].coords = coords[n].join(',');
                }
                previousWidth = img.offsetWidth;
                return true;
            };
            window.onresize = this.resize;
        },
        imageMap = new ImageMap(document.getElementById('map_ID'), document.getElementById('img_ID'));
    imageMap.resize();
    return;
}

JSFiddle:http://jsfiddle.net/p7EyT/154/

答案 8 :(得分:2)

http://home.comcast.net/~urbanjost/semaphore.html是讨论的首页,并且 实际上有链接到基于JavaScript的问题解决方案。我收到了通知 HTML将支持未来的百分比单位,但我没有看到任何进展 在相当长的一段时间内(自从我听到支持即将到来可能已经过去了一年多)所以如果你感觉舒服,那么解决方案可能值得一看 的JavaScript / ECMAScript的。

答案 9 :(得分:2)

我遇到了同样的要求,我想要显示可以调整任何屏幕大小的响应式图像地图,重要的是,我想突出显示坐标

所以我尝试了很多可以根据屏幕大小和事件调整坐标大小的库。我得到了最好的解决方案(jquery.imagemapster.min.js),几乎适用于所有浏览器。此外,我已将其与Summer Plgin集成,从而创建了图像映射。

&#13;
&#13;
 var resizeTime = 100;
 var resizeDelay = 100;    

$('img').mapster({
        areas: [
            {
                key: 'tbl',
                fillColor: 'ff0000',
                staticState: true,
                stroke: true
            }
        ],
        mapKey: 'state'
    });

    // Resize the map to fit within the boundaries provided

    function resize(maxWidth, maxHeight) {
        var image = $('img'),
            imgWidth = image.width(),
            imgHeight = image.height(),
            newWidth = 0,
            newHeight = 0;

        if (imgWidth / maxWidth > imgHeight / maxHeight) {
            newWidth = maxWidth;
        } else {
            newHeight = maxHeight;
        }
        image.mapster('resize', newWidth, newHeight, resizeTime);
    }

    function onWindowResize() {

        var curWidth = $(window).width(),
            curHeight = $(window).height(),
            checking = false;
        if (checking) {
            return;
        }
        checking = true;
        window.setTimeout(function () {
            var newWidth = $(window).width(),
                newHeight = $(window).height();
            if (newWidth === curWidth &&
                newHeight === curHeight) {
                resize(newWidth, newHeight);
            }
            checking = false;
        }, resizeDelay);
    }

    $(window).bind('resize', onWindowResize);
&#13;
img[usemap] {
        border: none;
        height: auto;
        max-width: 100%;
        width: auto;
    }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/jquery-imagemapster@1.2.10/dist/jquery.imagemapster.min.js"></script>

<img src="https://discover.luxury/wp-content/uploads/2016/11/Cities-With-the-Most-Michelin-Star-Restaurants-1024x581.jpg" alt="" usemap="#map" />
<map name="map">
    <area shape="poly" coords="777, 219, 707, 309, 750, 395, 847, 431, 916, 378, 923, 295, 870, 220" href="#" alt="poly" title="Polygon" data-maphilight='' state="tbl"/>
    <area shape="circle" coords="548, 317, 72" href="#" alt="circle" title="Circle" data-maphilight='' state="tbl"/>
    <area shape="rect" coords="182, 283, 398, 385" href="#" alt="rect" title="Rectangle" data-maphilight='' state="tbl"/>
</map>
&#13;
&#13;
&#13;

希望帮助别人。

答案 10 :(得分:2)

如果您对矩形点击区域没问题,我发现了一种无JavaScript的方法来解决这个问题。

首先,确保您的图片位于相对位置的div中。然后将图像放入该div中,这意味着它将占用div中的所有空间。最后,在主div内的图像下方添加绝对定位的div,然后对顶部,左侧,宽度和高度使用百分比,以使链接命中区域具有所需的大小和位置。

我发现最简单的方法是在初次工作时为div分配黑色背景色(理想情况下带有一些alpha褪色,以便您可以在下面看到链接的内容),并在浏览器中使用代码检查器来调整百分比实时,这样您就可以正确使用它。

这是您可以使用的基本轮廓。通过用百分比完成所有操作,可以确保所有元素都保持与图像比例相同的相对大小和位置。

<div style="position: relative;">
  <img src="background-image.png" style="width: 100%; height: auto;">
  <a href="/link1"><div style="position: absolute; left: 15%; top: 20%; width: 12%; height: 8%; background-color: rgba(0, 0, 0, .25);"></div></a>
  <a href="/link2"><div style="position: absolute; left: 52%; top: 38%; width: 14%; height: 20%; background-color: rgba(0, 0, 0, .25);"></div></a>
</div>

将此代码与您的Chrome或您选择的浏览器中的代码检查器一起使用,并调整百分比(您可以使用十进制百分比来更精确)直到方框正确。在准备使用background-color的{​​{1}}时,也要使用它,因为您希望隐藏点击区域。

答案 11 :(得分:1)

对于那些不想使用JavaScript的人来说,这是一个图像切片示例:

http://codepen.io/anon/pen/cbzrK

当您缩放窗口时,小丑图像会相应缩放,当它出现时,小丑的鼻子仍然是超链接。

答案 12 :(得分:1)

这取决于你可以使用jQuery来按比例调整范围。 为什么顺便使用图像映射?你不能使用缩放div或其他元素吗?

答案 13 :(得分:1)

查看Github上的image-map插件。它适用于vanilla JavaScript和jQuery插件。

$('img[usemap]').imageMap();     // jQuery

ImageMap('img[usemap]')          // JavaScript

查看demo

答案 14 :(得分:1)

我创建了Tom Bisciglia建议的解决方案的javascript版本。

我的代码允许您使用普通图像映射。您所要做的就是加载几行CSS和几行JS,然后... BOOM ...您的图像映射具有悬停状态并具有充分的响应能力!魔术对吗?

var images = document.querySelectorAll('img[usemap]');
images.forEach( function(image) {
    var mapid = image.getAttribute('usemap').substr(1);
    var imagewidth = image.getAttribute('width');
    var imageheight = image.getAttribute('height');
    var imagemap = document.querySelector('map[name="'+mapid+'"]');
    var areas = imagemap.querySelectorAll('area');

    image.removeAttribute('usemap');
    imagemap.remove();

    // create wrapper container
    var wrapper = document.createElement('div');
    wrapper.classList.add('imagemap');
    image.parentNode.insertBefore(wrapper, image);
    wrapper.appendChild(image);

    areas.forEach( function(area) {
        var coords = area.getAttribute('coords').split(',');
        var xcoords = [parseInt(coords[0]),parseInt(coords[2])];
        var ycoords = [parseInt(coords[1]),parseInt(coords[3])];
        xcoords = xcoords.sort(function(a, b){return a-b});
        ycoords = ycoords.sort(function(a, b){return a-b});
        wrapper.innerHTML += "<a href='"+area.getAttribute('href')+"' title='"+area.getAttribute('title')+"' class='area' style='left: "+((xcoords[0]/imagewidth)*100).toFixed(2)+"%; top: "+((ycoords[0]/imageheight)*100).toFixed(2)+"%; width: "+(((xcoords[1] - xcoords[0])/imagewidth)*100).toFixed(2)+"%; height: "+(((ycoords[1] - ycoords[0])/imageheight)*100).toFixed(2)+"%;'></a>";
    });
});
img {max-width: 100%; height: auto;}

.imagemap {position: relative;}
.imagemap img {display: block;}
.imagemap .area {display: block; position: absolute; transition: box-shadow 0.15s ease-in-out;}
.imagemap .area:hover {box-shadow: 0px 0px 1vw rgba(0,0,0,0.5);}
<!-- Image Map Generated by http://www.image-map.net/ -->
<img src="https://i.imgur.com/TwmCyCX.jpg" width="2000" height="2604" usemap="#image-map">
<map name="image-map">
    <area target="" alt="Zirconia Abutment" title="Zirconia Abutment" href="/" coords="3,12,199,371" shape="rect">
    <area target="" alt="Gold Abutment" title="Gold Abutment" href="/" coords="245,12,522,371" shape="rect">
    <area target="" alt="CCM Abutment" title="CCM Abutment" href="/" coords="564,12,854,369" shape="rect">
    <area target="" alt="EZ Post Abutment" title="EZ Post Abutment" href="/" coords="1036,12,1360,369" shape="rect">
    <area target="" alt="Milling Abutment" title="Milling Abutment" href="/" coords="1390,12,1688,369" shape="rect">
    <area target="" alt="Angled Abutment" title="Angled Abutment" href="/" coords="1690,12,1996,371" shape="rect">
    <area target="" alt="Temporary Abutment [Metal]" title="Temporary Abutment [Metal]" href="/" coords="45,461,506,816" shape="rect">
    <area target="" alt="Fuse Abutment" title="Fuse Abutment" href="/" coords="1356,461,1821,816" shape="rect">
    <area target="" alt="Lab Analog" title="Lab Analog" href="/" coords="718,935,1119,1256" shape="rect">
    <area target="" alt="Transfer Impression Coping Driver" title="Transfer Impression Coping Driver" href="/" coords="8,1330,284,1731" shape="rect">
    <area target="" alt="Impression Coping [Transfer]" title="Impression Coping [Transfer]" href="/" coords="310,1330,697,1731" shape="rect">
    <area target="" alt="Impression Coping [Pick-Up]" title="Impression Coping [Pick-Up]" href="/" coords="1116,1330,1560,1733" shape="rect">
</map>

答案 15 :(得分:0)

类似于Orland的回答: https://stackoverflow.com/a/32870380/462781

结合Chris'代码: https://stackoverflow.com/a/12121309/462781

如果区域适合网格,您可以使用宽度为%的透明图片覆盖区域,以保持其宽高比。

[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
    .wrapperspace {
      width: 100%;
      display: inline-block;
      position: relative;
    }
    .mainspace {
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
    }

您可以使用%的保证金。另外,“空间”图像可以在第3级div内彼此相邻放置。

答案 16 :(得分:0)

响应宽度和&高度

window.onload = function () {
        var ImageMap = function (map, img) {
                var n,
                    areas = map.getElementsByTagName('area'),
                    len = areas.length,
                    coords = [],
                    imgWidth = img.naturalWidth,
                    imgHeight = img.naturalHeight;
                for (n = 0; n < len; n++) {
                    coords[n] = areas[n].coords.split(',');
                }
            this.resize = function () {
                var n, m, clen,
                    x = img.offsetWidth / imgWidth,
                    y = img.offsetHeight / imgHeight;
                    imgWidth = img.offsetWidth;
                    imgHeight = img.offsetHeight;
                for (n = 0; n < len; n++) {
                    clen = coords[n].length;
                    for (m = 0; m < clen; m +=2) {
                        coords[n][m] *= x;
                        coords[n][m+1] *= y;
                    }
                    areas[n].coords = coords[n].join(',');
                }
                    return true;
                };
                window.onresize = this.resize;
            },
        imageMap = new ImageMap(document.getElementById('map_region'), document.getElementById('prepay_region'));
        imageMap.resize();
        return;
    }

答案 17 :(得分:0)

出于某些原因,这些解决方案都不适用于我。我使用变换获得了最大的成功。

o.division == 'x.b'

答案 18 :(得分:-1)

考虑使用这个图像映射器

https://imagemapper.noc.io/#/

基于 SVG 和响应式

它有很好的向导来构建地图

对于页面来说它足够简单,因为它不使用库