Чуйна карта зображень


145

У мене є існуюча карта зображень у чуйному форматі HTML. Масштаби зображень залежать від розміру браузера, але координати зображень очевидно мають фіксований розмір пікселів. Які параметри я маю змінити розмір координат карти зображень?


6
Це питання стосується не географічної карти, а тегу <map> html
jdog

4
Ознайомтесь із плагіном image-map . Він працює з Javascript, Node та jQuery
Travis Clarke

2
В якості альтернативи можна використовувати SVG-зображення. Я рекомендую прочитати Використання SVG як альтернативи Imagemap
Мауг каже, що поверніть Моніку

1
Схоже, що ми хочемо - це можливість завантажувати JPEG або подібну програму, яка дозволяє задавати розташування карт на зображенні (наприклад, у кратковій мережі net image) - у фоновому режимі це створює SVG-файл, який по суті є прозорим . Потім ми хочемо, щоб карта застосувала до SVG та відобразила SVG поверх JPG у веб-браузері. Оскільки браузер змінює розмір JPG, розмір SVG також змінюється і SVG завжди викликається при натисканні на карту зображення. Будь-які пропозиції щодо будь-якої частини цього?
youcantryreachingme

2
Так, саме цього я хотів у 2011 році
jdog

Відповіді:


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
чи все це є актуальним? Ви можете надати оновлення, будь ласка?
Малахій

1
@Malachi Так, це все ще актуально
Том,

дякую Томе, ми обговорювали питання щодо CodeReview, тепер я б хотів, щоб я міг згадати питання ....
Малахій

@Тому це працює лише для одного зображення ... якщо ми розмістимо інше зображення, то воно не працює для другого та третього зображення тощо ... просто перевірте це ..
User2413

1
Я знайшов інструмент онлайн генератор , який використовує SVGs , який все основні браузер зрозуміти 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>


1
Підручник посилання розірвано. Зображення також із jsfiddle.
Кріштіано Майя

Я сигналізував, що посилання на підручник було розірвано та оновлено фрагменти jsfiddle та коду. Дякую за голову вгору
belgac

Це дивовижне рішення. Я його успішно використовую і працює як шарм. Дякую!
Jaume Mussons Abad

3
На сьогодні найкраще рішення у 2020 році. Спробуйте цей генератор коду, щоб зробити його дуже простим. imagemapper.noc.io/#
Бретт Дональд

1
Це має бути найкращим найкращим рішенням у 2020 році.
mythicalcoder

39

1
Просто і FYI для еверону ... Я виявив, що це добре працює, але не в гармошці. Я використовую Bootstrap 3, і якщо ви не завантажуєте сторінку з відкритою на зображенні гармошкою, коли ви відкриваєте гармошку, карти зображень немає, якщо не змінити розмір вікна браузера.
jasonflaherty

1
@jasonflaherty Ви можете викликати подію зміни розміру, щоб змусити карту показувати? $(window).trigger('resize');
Стів Мейснер

@SteveMeisner Я цього не пробував ... але не хотів би ця сила оновити?
Jasonflaherty

@jasonflaherty nope! Він просто "запускає" подію зміни розміру на елементі, який ви прив'язуєте ( windowу цьому випадку). Удачі.
Стів Мейснер

Щойно створений супер базовий, але зручний модуль Drupal за допомогою цього плагіна: drupal.org/project/responsive_imagemaps
Джошуа Стюардсон,

19

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

Я помістив зображення та згенеровані теги якоря у відносно розміщений тег div, і все прекрасно працювало на розмірі вікон та на мобільному телефоні.


2
Приємна знахідка! Дякуємо, що
долучилися

1
Я не можу достатньо підкріпити цю проблему !! Відмінний підручник; всеосяжний та простий у розумінні. Слід прочитати все це, але особливий інтерес викликає tutorials.jenkov.com/svg/scripting.html
Мауг каже, що відновити Моніку

Це дійсно просте, але приємне рішення, якщо область, яку потрібно натиснути, прямокутник.
користувач2875289

Це так приголомшливо. Працював і для мене на сайті DNN. Як заявив Джеффрі, я просто скинув <img> і згенерований html всередині відносно розташованого div. Дякую!
Тед Крапф

18

Я не знайшов способу вирішити це, якщо ви добре з прямокутними ділянками влучень.

Перш за все, переконайтеся, що ваше зображення розміщене у розділі, яке розміщене відносно. Потім помістіть зображення всередину цього діла, це означає, що він займе весь простір у діві. Нарешті, додайте абсолютно розміщені div під зображенням у межах основного 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


Підтверджено для роботи в останніх версіях 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>

4

Працює для мене (не забудьте змінити 3 речі в коді):

  • попередня ширина (оригінальний розмір зображення)

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


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, щоб пропорційно регулювати діапазони. Для чого ви, до речі, використовуєте карту зображень? Ви не можете використовувати масштабування дівок чи інших елементів для цього?


в той час як точне рішення буде працювати з масштабованими дівками, карта зображень "керується вмістом" і дозволяє використовувати будь-який регіон. Дякую, я перевірю 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>

Ви можете використовувати маржу у%. Крім того, "космічні" зображення можуть бути розміщені поруч один з одним у розділі 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 року?
Майкл - Де Клей Ширкий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.