Динамическое изменение размеров Image-карт и изображений

27

В настоящее время я пытаюсь сделать Image-Map на своем сайте, который будет изменять размер в зависимости от размера окна... Мне было интересно, если бы все-таки было сделано это с 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>

  • 0
    Вы можете использовать css для настройки размера div и / или img, но, поскольку координаты области являются абсолютными, вам, возможно, придется сделать это с помощью javascript
  • 0
    Пожалуйста, поправьте меня, если я неправильно понял ваш вопрос. У вас есть фиксированный размер и центрированное IMG которое не будет изменяться в соответствии с окном, и теперь вы хотите MAP который всегда будет покрывать только видимую часть IMG ?
Показать ещё 1 комментарий
Теги:
image
map

11 ответов

38
Лучший ответ

Если вы закончите выполнение задачи с помощью 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 при нажатии на них.

  • 0
    Хорошо, так что если я изменил размер изображения, это должно сработать, чем?
  • 0
    @ultrazoid В своем вопросе вы сказали, что размер изображения будет изменяться в соответствии с окном, код изменяет размер MAP при изменении размера окна, если размер изображения связан с размером окна.
Показать ещё 18 комментариев
34

Я написал небольшую небольшую библиотеку, чтобы сохранить масштабируемое изображение с масштабируемым изображением, поэтому карта остается синхронно с масштабированием изображения. Полезно, если вы хотите сопоставить процентное масштабированное изображение и т.д.

Он может использоваться с jQuery или без него.

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

и вы можете видеть, как он работает.

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

  • 6
    Это круто! Хотел бы я поднять голос несколько раз
  • 0
    Это довольно круто! Но есть ли простой способ подсветить область при наведении?
Показать ещё 8 комментариев
1

Как класс (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);
1

У меня была та же проблема на прошлой неделе, и я закончил писать плагин jQuery для этого.

Здесь проект gitHub:

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

Основное использование:

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

Живой пример

http://emartin.ca/mapify/

  • 0
    Документация неоднозначна: она работает только для изображения .svg или для всего (jpg, png ...)?
  • 0
    Неоднозначность? emartin.ca/mapify
Показать ещё 3 комментария
0

Вы можете умножить координаты на соотношение исходного изображения и стилизованного изображения.

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

Если у вас есть доступ к Illustrator или другой программе, которая может генерировать SVG, то создать динамическую карту изображений с помощью SVG довольно просто.

Это не требует какого-либо программирования.

Вот инструкции для Illustrator (это займет всего несколько секунд) :

  1. открыть изображение в Illustrator, сохранить под новым именем

  2. изменить размер документа до размера изображения

  3. рисовать заполненные прямоугольники для частей карты (полезно, чтобы прозрачность была 50%)

  4. с помощью палитры "Атрибуты" добавьте ссылку на каждый прямоугольник

  5. изменить непрозрачность всех прямоугольников до 0%

  6. выберите изображение и в меню палитры "ссылки" выберите "Unembed…" (имя не имеет значения, мы не собираемся использовать изображение)

  7. файл ›сохранить как SVG (Местоположение изображения: Ссылка, Свойства CSS: Элементы стиля, Адаптивный отмечен)

  8. откройте полученный файл SVG

  9. удалить первые две строки (XML и комментарий Adobe)

  10. обновить источник изображения

  11. вставьте код SVG в ваш HTML-документ

Это работает во всех основных браузерах. Вот снимок экрана настроек экспорта SVG для Illustrator:

Изображение 117470

0

Вот еще один плагин, который я только что написал для управления картами изображений: https://github.com/gestixi/pictarea

Кроме того, области автоматически масштабируются в зависимости от размера изображения. Обратите внимание, что для отображения областей используется холст.

Основное использование:

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

для этого вам нужно иметь атрибут data-original-coords, имеющий coords к исходному изображению

$(function () {
    function adjeustCoords() {
        var image=$('img'); //change that to your image selector
        var originalWidth=image[0].naturalWidth;
        var currentWidth=image.width();
        var ratio=currentWidth/originalWidth;
        $("map area").each(function(){
            //change that to your area selector
            var coords=$(this).attr('data-original-coords').split(',');
            coords = coords.map(function (x) {
                return Math.round(x*ratio);
                //i don't know if all browsers can accept floating point so i round the result
            });
            $(this).attr('coords',coords.join());
        });
    }
    adjeustCoords();
    $(window).resize(function(){
        adjeustCoords();
    });
});

это работает с хром, firefox и крайними наименьшими версиями

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

Вы можете попытаться использовать процент в координатах, но он не будет работать в большинстве браузеров (если не все). Поэтому вы должны использовать JavaScript. Или используйте абсолютные позиционные divs с процентными координатами вместо карты.

0

Для достижения этой цели вы можете использовать спрайты CSS. У вас будут части изображения, вписывающиеся в одно изображение, и таким образом вы просто будете делать один HTTP-запрос для загрузки всех изображений. Этот метод не требует javascript, и вы просто будете использовать свойство background-position; для перемещения изображений.

Это эффективный метод оптимизации страницы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню