Адаптивная карта изображения

145

У меня есть существующая карта изображения в отзывчивом HTML-макете. Изображения масштабируются в соответствии с размером браузера, но координаты изображения, очевидно, имеют фиксированный размер в пикселях. Какие варианты у меня есть, чтобы изменить размер координат карты изображения?

jdog
источник
6
Этот вопрос не о географической карте, а о теге <map> html
jdog
4
Проверьте плагин image-map . Он работает с Javascript, Node и jQuery
Трэвис Кларк,
2
В качестве альтернативы вы можете использовать изображение SVG. Я рекомендую прочитать Использование SVG в качестве альтернативы графическим картам
Моуг говорит восстановить Monica
1
Похоже, что нам нужно, это возможность загружать JPEG или подобное приложение, которое позволяет вам указывать местоположения карты на изображении (например, в точечной сети изображения-карты) - в фоновом режиме это создает SVG-файл, который является по существу прозрачным , Затем мы хотим, чтобы карта применялась к SVG и отображала SVG поверх JPG в веб-браузере. Поскольку браузер изменяет размер JPG, SVG также изменяется, и SVG всегда вызывается при нажатии на карту изображения. Любые предложения по любой части этого?
youcantryreachingme
2
Да, это то, что я хотел в 2011 году
JDOG

Ответы:

90

Для адаптивных карт изображений вам понадобится плагин:

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
что-нибудь из этого по-прежнему актуально? не могли бы вы предоставить обновление, пожалуйста?
Малахи
1
@Malachi Да, это все еще актуально
Том
спасибо, Том, у нас была дискуссия по вопросу о CodeReview, теперь я хотел бы вспомнить вопрос ....
Малахи
@ Это работает только для одного изображения .. если мы поместим другое изображение, то оно не будет работать для второго и третьего изображения и т. Д. ... просто проверьте это ..
User2413
1
Я нашел инструмент онлайн-генератора, который использует SVG, которые все основные браузеры понимают imagemapper.noc.io
frthjf
43

Вы также можете использовать svg вместо карты изображений. ;)

Существует учебник о том, как это сделать.

  • Вот jsfiddle с некоторыми хорошими эффектами при наведении, описание и ссылки: http://jsfiddle.net/eLbpmsaj/

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

belgac
источник
1
Ссылка на учебник не работает. Изображение из jsfiddle также.
Криштиану Майя
Я дал понять, что ссылка на учебник была сломана, и обновил jsfiddle и фрагменты кода. Спасибо за хедз-ап
Бельгак
Это удивительное решение. Я использую его успешно и работает как шарм. Спасибо!
Хауме Муссон Абад
3
На сегодняшний день лучшее решение в 2020 году. Попробуйте этот генератор кода, чтобы сделать его очень простым. imagemapper.noc.io/#
Бретт Дональд
1
Это должно быть самое лучшее адаптивное решение в 2020 году.
mythicalcoder
39

Адаптивное изображение карты плагин jQuery Мэтт Стоу

Джошуа Стюардсон
источник
1
Просто и к вашему сведению для eveyrone ... Я обнаружил, что это работает хорошо, но не внутри гармошки. Я использую Bootstrap 3, и если вы не загружаете страницу с открытым аккордеоном на изображении, то, когда вы открываете аккордеон, карта изображения не появляется, если размер окна браузера не изменяется.
Джейсон Флаэрти
1
@jasonflaherty, не могли бы вы вызвать событие изменения размера для отображения карты? $(window).trigger('resize');
Стив Мейснер,
@ SteveMeisner Я не пробовал это ... но не заставит ли это обновиться?
Джейсон Флаэрти
@jasonflaherty Нету! Он просто «запускает» событие изменения размера на элементе, который вы связываете ( windowв данном случае). Удачи.
Стив Мейснер
Только что создал супер базовый, но удобный модуль Drupal, используя этот плагин: drupal.org/project/responsive_imagemaps
Джошуа
19

Я наткнулся на решение, которое вообще не использует карты изображений, а привязывает теги, которые абсолютно расположены над изображением. Единственным недостатком будет то, что точка доступа должна быть прямоугольной, но плюс в том, что это решение не опирается на Javascript, а только на CSS. Существует веб-сайт, который можно использовать для создания HTML-кода для якорей: http://www.zaneray.com/responsive-image-map/

Я поместил изображение и сгенерированные теги привязки в относительно расположенный тег div, и все отлично работало при изменении размера окна и на моем мобильном телефоне.

Джеффри Лэнгхэм
источник
2
Хорошая находка! Спасибо за участие в этом списке
jdog
1
Я не могу высоко оценить этот насвер !! Отличный учебник; всеобъемлющий и легкий для понимания. Надо все это прочитать, но особый интерес представляет tutorials.jenkov.com/svg/scripting.html
Моуг говорит восстановить Монику
Это действительно простое, но приятное решение, если область, на которую нужно щелкнуть, - это прямоугольник.
user2875289
Это так круто. У меня тоже работал с сайтом DNN. Как сказал Джеффри, я только что опустил <img> и сгенерированный html внутри относительного позиционного элемента div. Спасибо!
Тед Крапф
18

Я нашел не-JS способ решить эту проблему, если вы в порядке с прямоугольными областями попадания.

Прежде всего, убедитесь, что ваше изображение находится в относительном позиционировании. Затем поместите изображение в этот div, что означает, что оно займет все пространство в div. Наконец, добавьте абсолютно позиционированные div-ы под изображением, внутри основного div-элемента и используйте проценты для top, left, width и height, чтобы получить области попадания ссылок нужного размера и позиции.

Я считаю, что проще всего дать div черный фоновый цвет (в идеале с некоторым альфа-замиранием, чтобы вы могли видеть связанный контент под ним), когда вы впервые работаете, и использовать инспектор кода в вашем браузере, чтобы корректировать проценты в реальном времени , так что вы можете получить это правильно.

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

<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из transparentкогда вы будете готовы использовать его , так как вы хотите , чтобы ваши хиты области , чтобы быть невидимым.

Том Бисглия
источник
Это отличное решение! Спасибо
XIMS
Отличное решение! UIkit использует ту же технику для своих маркеров: getuikit.com/docs/marker
xela84
Отличное решение, спасибо, что поделились! Я использую это в мобильном приложении, и это решает проблему разных экранов.
JohnGIS
11

Дэвид Брэдшоу написал хорошую маленькую библиотеку, которая решает эту проблему. Может использоваться с или без jQuery.

Доступно здесь: https://github.com/davidjbradshaw/imagemap-resizer

Grodriguez
источник
Подтверждено для работы в последних версиях Chrome / IE / FF на этот комментарий.
Джеймс Патерсон
1
Работал отлично для меня, супер простой интерфейс тоже
Брайан
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>
chimeraha
источник
4

Работая на меня (не забудьте изменить 3 вещи в коде):

  • previousWidth (оригинальный размер изображения)

  • map_ID (идентификатор вашей карты изображений)

  • img_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/

Niente0
источник
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.

Джон Урбан
источник
2

Проверьте плагин image-map на Github. Работает как с ванильным JavaScript, так и с плагином jQuery.

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

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

Проверьте демо .

Трэвис Кларк
источник
1

Это зависит от того, как вы думаете, вы можете использовать jQuery для пропорциональной настройки диапазонов. Почему вы используете карту изображения, кстати? Разве вы не можете использовать для этого масштабирующие элементы div или другие элементы?

Рейнир Капер
источник
в то время как точное решение будет работать с масштабированными div, карта изображения «управляется контентом» и учитывает любой вид региона. Спасибо, я проверю jquery для этого.
JDog
1

Для тех, кто не хочет прибегать к JavaScript, вот пример нарезки изображения:

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

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

Джонни Ошика
источник
2
Спасибо за ночные кошмары!
jerrygarciuh
1
Все ссылки на изображения не работают.
Тайлер Форсайт
0

Аналогично ответу Орланда здесь: 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>

Вы можете использовать наценку в%. Кроме того, «космические» изображения могут быть размещены рядом друг с другом внутри div 3-го уровня.

Пит
источник
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 года?
Майкл - Где Клэй Ширки