动态调整图像映射和图像的大小

时间:2012-11-10 10:04:49

标签: javascript html image map

我正在尝试在我的网站上制作一个图片地图,它会根据窗口的大小调整大小...我想知道是否有任何方式使用HTML来执行此操作或我是否必须使用HTML Javascript或其他语言。

<div style="text-align:center; width:1920px; margin-left:auto; margin-right:auto;">
<img id="Image-Maps_5201211070133251" src="Site.png" usemap="#Image-Maps_5201211070133251" border="0" width="1920" height="1080" alt="" />
<map id="_Image-Maps_5201211070133251" name="Image-Maps_5201211070133251">
<area shape="poly" coords="737,116,1149,118,944,473," href="http://essper.bandcamp.com" alt="Bandcamp" title="Bandcamp"   />
<area shape="poly" coords="1006,589,1418,590,1211,945," href="http://soundcloud.com/essper" alt="Soundcloud" title="Soundcloud"   />
<area shape="poly" coords="502,590,910,591,708,944," href="http://facebook.com/the.essper" alt="Facebook" title="Facebook"   />
</map>

12 个答案:

答案 0 :(得分:40)

如果你最终使用JavaScript完成任务,这里有一个跨浏览器的代码片段来调整MAP元素中所有区域的大小。

window.onload = function () {
    var ImageMap = function (map) {
            var n,
                areas = map.getElementsByTagName('area'),
                len = areas.length,
                coords = [],
                previousWidth = 1920;
            for (n = 0; n < len; n++) {
                coords[n] = areas[n].coords.split(',');
            }
            this.resize = function () {
                var n, m, clen,
                    x = document.body.clientWidth / 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'));
    imageMap.resize();
}

previousWidth必须等于原始图像的宽度。您还需要在HTML中使用一些相对单位:

<div style="width:100%;">
<img id="Image-Maps_5201211070133251" src="Site.png" usemap="#Image-Maps_5201211070133251" border="0" width="100%" alt="" />

jsFiddle的工作演示。如果你在IE中打开小提琴,你可以在点击时看到AREA

答案 1 :(得分:37)

我写了一个小的lib来保持imageMap缩放到可调整大小的图像,因此图像在图像缩放时保持同步。当您想要映射百分比缩放图像等时很有用。

它可以在有或没有jQuery的情况下使用。

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

你可以看到它在工作。

http://davidjbradshaw.com/imagemap-resizer/example/

答案 2 :(得分:2)

作为一个班级(ES6):

class ResponsiveImageMap {
    constructor(map, img, width) {
        this.img = img;
        this.originalWidth = width;
        this.areas = [];

        for (const area of map.getElementsByTagName('area')) {
            this.areas.push({
                element: area,
                originalCoords: area.coords.split(',')
            });
        }

        window.addEventListener('resize', e => this.resize(e));
        this.resize();
    }

    resize() {
        const ratio = this.img.offsetWidth / this.originalWidth;

        for (const area of this.areas) {
            const newCoords = [];
            for (const originalCoord of area.originalCoords) {
                newCoords.push(Math.round(originalCoord * ratio));
            }
            area.element.coords = newCoords.join(',');
        }

        return true;
    };
}

用法:

var map = document.getElementById('myMapId');
var image = document.getElementById('myImageId');
new ResponsiveImageMap(map, image, 800);

答案 3 :(得分:1)

上周我遇到了同样的问题,最后我为此编写了一个jQuery插件。

这是项目gitHub:

https://github.com/etienne-martin/mapify

基本用法:

$("img[usemap]").mapify();

实例

http://emartin.ca/mapify/

答案 4 :(得分:1)

您可以将坐标乘以原始图像和样式图像的比例。

<img id="paredea" usemap="#PAREDE-A"  src="https://i.imgur.com/o9nrUMR.png">

    <map name="PAREDE-A">
        <area id="paredea0" shape="rect"  onclick="alert('colmeia A')">
        <area id="paredea1" shape="rect"  onclick="alert('colmeia B')">
        <area id="paredea2" shape="rect"  onclick="alert('colmeia C')">
        <area id="paredea3" shape="rect"  onclick="alert('colmeia D')">
        <area id="paredea4" shape="rect"  onclick="alert('colmeia E')"> 

        <area id="paredea5" shape="rect"  onclick="alert('comeia F')">
        <area id="paredea6" shape="rect"  onclick="alert('colmeia G')">
        <area id="paredea7" shape="rect"  onclick="alert('colmeia H')">
        <area id="paredea8" shape="rect"  onclick="alert('colmeia I')">
        <area id="paredea9" shape="rect"  onclick="alert('colmeia J')">  

        <area id="paredea10" shape="rect"  onclick="alert('colmeia K')">
        <area id="paredea11" shape="rect"  onclick="alert('colmeia L')">
        <area id="paredea12" shape="rect"  onclick="alert('colmeia M')">
        <area id="paredea13" shape="rect"  onclick="alert('colmeia N')">
        <area id="paredea14" shape="rect"  onclick="alert('colmeia O')">  
    </map>

    <script>


        var coordsA = [];
        coordsA[0] = "0,0,200,130";
        coordsA[1] = "200,0,400,130";
        coordsA[2] = "400,0,600,130";
        coordsA[3] = "600,0,800,130";
        coordsA[4] = "800,0,1000,130";

        coordsA[5] = "0,160,200,240";
        coordsA[6] = "200,160,400,240";
        coordsA[7] = "400,160,600,240";
        coordsA[8] = "600,160,800,240";
        coordsA[9] = "800,160,1000,240";

        coordsA[10] = "0,270,200,400";
        coordsA[11] = "200,270,400,400";
        coordsA[12] = "400,270,600,400";
        coordsA[13] = "600,270,800,400";
        coordsA[14] = "800,270,1000,400";


        function setcoords(areaid, totalOfAreas) {
            document.getElementById('paredea').style.width = "auto";
            var width1 = document.getElementById('paredea').width;
            document.getElementById('paredea').style.width = "100%";
            var width2 = document.getElementById('paredea').width;
            var ratio = width2 / width1;

            for (var i = 0; i < totalOfAreas; i++) {
                var temp = coordsA[i].split(",");
                var newcoords = "";
                for (var j = 0; j < temp.length; j++) {
                    temp[j] *= ratio;
                    newcoords += temp[j] + ",";
                }
                newcoords = newcoords.substr(0, newcoords.length - 1);

                document.getElementById(areaid + i).coords = newcoords;
            }
        }


       window.onload = function () {
            setcoords("paredea", 15);
        };

        window.onresize = function () {
            setcoords("paredea", 15);
        };
    </script>

答案 5 :(得分:0)

您可以使用CSS sprites来实现此目的。您将使图像块只适合一个图像,这样您只需要一个http请求来加载所有图像。此技术不需要javascript,您只需使用background-position;属性来移动图像。

这是一种有效的页面优化技术。

答案 6 :(得分:0)

我只针对直角坐标测试了这个,但我认为它应该推广到圆形或多边形

function wrap ( img, map ) {
  var originalCoords = [ ],
      test = new Image();

  for ( var i = 0; i < map.areas.length; ++i ) {
    var coords = map.areas[i].coords;
    originalCoords.push( coords.split( "," ).map( parseFloat ) );
  }

  function resize () {
    var ratio = img.width / test.width;
    for ( var i = 0; i < map.areas.length; ++i ) {
      map.areas[i].coords = originalCoords[i].map( function ( n ) {
        return ratio * n;
      } ).join( "," );
    }
  }

  test.addEventListener( "load", function () {
    window.addEventListener( "resize", resize, false );
    resize();
  }, false );

  test.src = img.src;
}

var imgs = document.querySelectorAll( "img[usemap]" );
for ( var i = 0; i < imgs.length; ++i ) {
  var map = document.querySelector( "map[name=" + imgs[i].useMap.substring( 1 ) + "]" );
  wrap( imgs[i], map );
}

答案 7 :(得分:0)

为了实现此目的,您需要"dependencies": { "axios": "^0.9.0", "react": "^0.14.3", "react-dom": "^0.14.3", "react-redux": "^4.0.6", "react-router": "^2.0.0", "redux": "^3.3.1", "redux-thunk": "^1.0.3" }, "devDependencies": { "babel-core": "^6.3.13", "babel-loader": "^6.2.0", "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "babel-preset-stage-2": "^6.3.13", "gulp": "^3.9.0", "gulp-serve": "^1.2.0", "json-server": "^0.8.6", "webpack-stream": "^3.1.0" } 属性data-original-coords到原始图片

coords

这适用于chrome,firefox和最少版本

答案 8 :(得分:0)

这是我刚刚编写的另一个用于管理图像地图的插件:https://github.com/gestixi/pictarea

除此之外,区域会根据图像的大小自动缩放。请注意,它使用画布来渲染区域。

基本用法:

$(function() {
  $('#map').pictarea({
    rescaleOnResize: true
  });
});

答案 9 :(得分:0)

如果您可以访问Illustrator或其他可以生成SVG的程序,则使用SVG创建动态图像映射非常容易

这不需要任何编程。

以下是Illustrator的说明 (只需几秒钟)

  1. 在Illustrator中打开图像,以新名称保存

  2. 将文档调整为与图像相同的大小

  3. 为地图零件绘制填充的矩形(有助于将不透明度设置为 50%)

  4. 使用“属性”选项板为每个矩形添加一个链接

  5. 将所有矩形的不透明度更改为0%

  6. 选择图像,然后在“链接”调板菜单中选择“未嵌入…” (名称无关紧要,我们不会使用图片)

  7. 文件›另存为SVG(图像位置:链接,CSS属性:样式 元素,已选中响应式)

  8. 打开生成的svg文件

  9. 删除前两行(XML和Adobe注释)

  10. 更新图像源

  11. 将svg代码粘贴到html文档中

这在所有主要的浏览器中都有效。这是Illustrator的SVG导出设置的屏幕截图:

enter image description here

答案 10 :(得分:0)

这是我最简单的解决方案。 无需jQuery或任何插件。 注意,此解决方案不处理标记中的任何错误或尺寸不成比例的图像。

function mapResizer(maps) {
    if (!maps) {maps = document.getElementsByTagName('map');}
    for (const map of maps) {
        map.img = document.querySelectorAll(`[usemap="#${map.name}"]`)[0];
        map.areas = map.getElementsByTagName('area');
        for (const area of map.areas) {
            area.coordArr = area.coords.split(',');
        }
    }
    function resizeMaps() {
        for (const map of maps) {
            const scale = map.img.offsetWidth / (map.img.naturalWidth || map.img.width);
            for (const area of map.areas) {
                area.coords = area.coordArr.map(coord => Math.round(coord * scale)).join(',');
            }
        }
    }
    window.addEventListener('resize', () => resizeMaps());
    resizeMaps();
}
if (document.readyState == 'complete') {
    mapResizer();
} else {
    window.addEventListener('load', () => mapResizer());
}

答案 11 :(得分:0)

我发现,通过适当地调整background-size和所有其他CSS属性的大小和位置,可以从单个图像映射中获得多个图像大小。

以下CSS用于ImageMap,其中包含多个社交网络的图像。使用CSS可以提取单个Twitter图标的三种不同大小。

.twitterIcon64 { /* Actual Size */
    background-size: 300px 282px;
    background: url('/images/social-media-icons.png') no-repeat -18px -109px;
    width: 64px;
    height: 64px;
}
.twitterIcon32 { /* 1/2 size */
    background-size: 150px 141px;
    background: url('/images/social-media-icons.png') no-repeat -9px -54px;
    width: 32px;
    height: 32px;
}
.twitterIcon21 { /* 1/3 size */
    background-size: 100px 94px;
    background: url('/images/social-media-icons.png') no-repeat -6px -36px;
    width: 22px;  /* Round up to avoid truncation */
    height: 22px; /* Round up to avoid truncation */
}

这对于媒体查询(非常动态)非常有效。

如有必要,可以使用javascript选择合适的类或计算合适的大小。

在IE 11,Edge,Firefox和Chrome上进行了测试。