响应式图像图


145

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


6
这个问题与地理地图无关,而是<map> html标签
jdog

4
查看图片地图插件。它可与Javascript,Node和jQuery配合使用
Travis Clarke

2
或者,您可以使用SVG图像。我建议阅读使用SVG替代图像映射
Mawg说恢复Monica的时间

1
听起来我们想要的是能够上传JPEG或类似的应用程序,该应用程序可让您在图像上指定地图位置(例如,在图像地图点网处)-在后台,这会生成实质上透明的SVG文件。然后,我们希望将地图应用于SVG并在Web浏览器中的JPG顶部上渲染SVG。当浏览器调整JPG大小时,SVG也会调整大小,并且SVG始终是单击图像映射时调用的SVG。关于此部分的任何建议?
youcantryreachingme '18

2
是的,这就是我在2011
jdog

Answers:


89

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

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


5
这些还相关吗?你能提供一个更新吗?
玛拉基2014年

1
@Malachi是的,这仍然很重要
Tom

谢谢汤姆,我们对代码审查的一个问题是有讨论,现在我希望我能记得的问题....

@Tom这仅适用于一个图像。.如果我们放置另一个图像,则它不适用于第二个和第三个图像,等等...只是检查它
。–

1
我发现一个在线生成工具,使用SVGs所有主要的浏览器理解imagemapper.noc.io
frthjf

43

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

有一个有关如何执行此操作的教程

.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>


1
教程链接已损坏。来自jsfiddle的图像也是如此。
克里斯蒂亚诺·玛雅

我表示该教程链接已损坏,并更新了jsfiddle和代码段。感谢您的
注意-belgac

这是一个了不起的解决方案。我已经成功地使用了它,并且像一种魅力。谢谢!
Jaume Mussons Abad

3
到目前为止,这是2020年最好的解决方案。尝试使用此代码生成器使其超级简单。imagemapper.noc.io/#
布雷特·唐纳德

1
这必须是在2020年上最好的响应解决方案
mythicalcoder

39

马特·斯托(Matt Stow)的自适应图像地图jQuery插件


1
Just和FYI一起使用eveyrone ...我发现这很好用,但是在手风琴内部却不行。我正在使用Bootstrap 3,如果您没有在图像上打开手风琴的情况下加载页面,则在打开手风琴时,除非调整浏览器窗口的大小,否则图像映射将不存在。
jasonflaherty

1
@jasonflaherty您可以触发调整大小事件以强制显示地图吗?$(window).trigger('resize');
史蒂夫·迈斯纳

@SteveMeisner我没有尝试过...但是会不会强制刷新?
jasonflaherty 2014年

@jasonflaherty不!它只是“触发”绑定元素上的调整大小事件(window在本例中为)。祝好运。
史蒂夫·迈斯纳

刚刚使用此插件创建了超级基本但方便的Drupal模块:drupal.org/project/sensitive_imagemaps
Joshua Stewardson

19

我遇到了一个根本不使用图像映射,而是完全定位在图像上方的定位标记的解决方案。唯一的缺点是,热点必须为矩形,但优点是此解决方案不依赖Javascript,而仅依赖CSS。您可以使用一个网站来生成锚点的HTML代码: http //www.zaneray.com/sensitive-image-map/

我将图像和生成的锚标签放置在相对放置的div标签中,并且在调整窗口大小和移动电话上一切正常。


2
好发现!感谢您为该列表做出贡献
jdog

1
我不能足够的支持这个!! 一个优秀的教程; 全面且易于理解。应该阅读所有内容,但特别有趣的是tutorials.jenkov.com/svg/scripting.html
Mawg说要恢复Monica的状态为

如果要单击的区域是矩形,这是一个非常简单但不错的解决方案。
user2875289 '18

太棒了 在DNN网站上也为我工作。正如Jeffrey所说,我只是将<img>和生成的html放在了相对定位的div中。谢谢!
Ted Krapf

17

如果您对矩形点击区域没问题,我发现了一种无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-colortransparent因为您希望隐藏区域。


这是一个很好的解决方案!谢谢
Xims

不错的解决方案!UIkit对其标记使用相同的技术:getuikit.com/docs/marker
xela84

出色的解决方案,谢谢分享!我在移动应用程序中使用它,它解决了不同屏幕的问题。
JohnGIS


7

以下方法对我来说非常有效,因此这是我的完整实现:

<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>

4

为我工作(记住要更改代码中的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/


3

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

因此,我尝试了许多可以根据屏幕大小和事件调整坐标大小的库。而且我有最好的解决方案(jquery.imagemapster.min.js),该解决方案几乎可以在所有浏览器上正常工作。我也将其与创建图像映射的Summer Plgin集成在一起。

 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);
img[usemap] {
        border: none;
        height: auto;
        max-width: 100%;
        width: auto;
    }
<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>

希望对某人有所帮助。


2

http://home.comcast.net/~urbanjost/semaphore.html是讨论的首页,实际上具有指向基于JavaScript的问题解决方案的链接。我已经收到通知,HTML将来会支持百分比单位,但是我已经有一段时间没有看到任何进展了(自从我听到支持即将到来,可能已经一年多了),所以解决方法是如果您对JavaScript / ECMAScript感到满意,那么可能值得一看。



1

这取决于您是否可以使用jQuery按比例调整范围。为什么要顺便使用图片地图?您不能为其使用缩放div或其他元素吗?


虽然确切的解决方案适用于按比例缩放的div,但是图像贴图是“内容管理的”,并且允许任何类型的区域。谢谢,我将为此签出jquery。
jdog 2011年


0

类似于Orland在这里的答案: https //stackoverflow.com/a/32870380/462781

结合克里斯的代码在这里: https //stackoverflow.com/a/12121309/462781

如果这些区域适合网格,则可以使用透明图片覆盖这些区域,并使用百分比形式的宽度(保持其纵横比)覆盖。

    .wrapperspace {
      width: 100%;
      display: inline-block;
      position: relative;
    }
    .mainspace {
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
    }
<div class="wrapperspace">
 <img style="float: left;" title="" src="background-image.png" width="100%" />
 <div class="mainspace">
     <div>
         <img src="space-top.png" style="margin-left:6%;width:15%;"/>
     </div>
     <div>
       <a href="http://www.example.com"><img src="space-company.png" style="margin-left:6%;width:15%;"></a>
     </div>
  <div>
   <a href="http://www.example.com"><img src="space-company.png" style="margin-left:6%;width:10%;"></a>
   <a href="http://www.example.com"><img src="space-company.png" style="width:20%;"></a>
  </div>
 </div>
</div>

您可以使用以%为单位的边距。另外,“空间”图像可以在第3级div中彼此相邻放置。


0

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

transform: translateX(-5.8%) translateY(-5%) scale(0.884);

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;
    }

您是否可以添加更多内容来显示您的代码与Niente0自2015年以来的回答之间的区别 ?
Michael-Clay Shirky在哪里,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.