Duyarlı resim haritası


145

Duyarlı bir html düzeninde mevcut bir görüntü eşlem var. Görüntüler tarayıcı boyutuna göre ölçeklenir, ancak görüntü koordinatları açıkça sabit piksel boyutlarındadır. Görüntü haritası koordinatlarını yeniden boyutlandırmak için hangi seçeneklere ihtiyacım var?


6
Bu soru bir coğrafi harita değil, <map> html etiketi
jdog

4
Görüntü haritası eklentisine göz atın . Javascript, Node ve jQuery ile çalışır
Travis Clarke

2
Alternatif olarak, bir SVG görüntüsü kullanabilirsiniz. Ben okumanızı tavsiye Alternatif için imagemaps olarak SVG Kullanılması
Mawg Monica yeniden diyor

1
İstediğimiz gibi, görüntüdeki harita konumlarını (resim-harita nokta ağında olduğu gibi) belirtmenize izin veren bir JPEG veya bir uygulamaya benzer şekilde yükleme yeteneği - arka planda, bu esasen şeffaf bir SVG dosyası üretir . Daha sonra haritanın SVG'ye uygulanmasını ve SVG'yi web tarayıcısında JPG'nin üstünde oluşturmasını istiyoruz. Tarayıcı JPG'yi yeniden boyutlandırdıkça, SVG de yeniden boyutlandırılır ve resim haritasına tıklandığında SVG daima çağrılır. Bunun herhangi bir parçası hakkında herhangi bir öneriniz var mı?
youcantryreachingme

2
Evet 2011'de istediğim
buydu

Yanıtlar:


90

Duyarlı görüntü haritaları için bir eklenti kullanmanız gerekir:

https://github.com/stowball/jQuery-rwdImageMaps (Artık bakım yapılmıyor)

Veya

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


Hiçbir büyük tarayıcı yüzde koordinatlarını doğru olarak anlamaz ve yüzde koordinatlarını piksel koordinatları olarak yorumlamaz.

http://www.howtocreate.co.uk/tutorials/html/imagemaps

Ayrıca, tarayıcıların uygulanıp uygulanmadığını test etmek için bu sayfa

http://home.comcast.net/~urbanjost/IMG/resizeimg3.html


5
bunlardan herhangi biri hala geçerli mi? bir güncelleme verebilir misiniz lütfen?
Malachi

1
@Malachi Evet, bu hala alakalı
Tom

teşekkür ederim Tom, CodeReview ile ilgili bir soru hakkında bir tartışma yapıyorduk, şimdi soruyu hatırlayabilseydim ....
Malachi

@ Bu sadece bir görüntü için çalışır .. başka bir görüntü yerleştirirseniz, ikinci ve üçüncü görüntü vb için çalışmıyorsa ... sadece kontrol edin ..
Kullanıcı2413

1
Ben tüm büyük tarayıcı imagemapper.noc.io
SVGs

43

Görüntü eşlemesi yerine svg'yi de kullanabilirsiniz. ;)

Bunun nasıl yapılacağı konusunda bir eğitim vardır .

.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
Öğretici bağlantısı bozuk. Ayrıca jsfiddle görüntü.
Cristiano Maia

Ben öğretici bağlantı kırıldı ve jsfiddle ve kod parçacıkları güncelledi sinyal.
Head

Bu inanılmaz bir çözüm. Ben başarılı bir şekilde kullandım ve bir cazibe gibi çalışır. Teşekkürler!
Jaume Mussons Abad

3
Çok basit hale getirmek için bu kod üretecini deneyin. imagemapper.noc.io/#
Brett Donald

1
Bu, 2020'de en iyi yanıt veren en iyi çözüm olmalı.
mythicalcoder

39

1
Just ve FYI for eveyrone ... Bunun iyi olduğunu gördüm, ama bir akordeonun içinde değil. Bootstrap 3 kullanıyorum ve görüntüyü akordeon açıkken sayfayı yüklemezseniz, akordeonu açtığınızda, tarayıcı penceresi yeniden boyutlandırılmadığı sürece görüntü haritası orada değildir.
jasonflaherty

1
@jasonflaherty haritayı göstermeye zorlamak için bir yeniden boyutlandırma etkinliği tetikleyebilir misiniz? $(window).trigger('resize');
Steve Meisner

@SteveMeisner Bunu denemedim ... ama bu yenilemeyi zorlamaz mı?
jasonflaherty

@jasonflaherty hayır! Yalnızca, bağladığınız öğedeki resize olayını "tetikler" ( windowbu durumda). İyi şanslar.
Steve Meisner

Sadece bu eklentiyi kullanarak süper temel ama kullanışlı Drupal modülünü oluşturduk: drupal.org/project/responsive_imagemaps
Joshua Stewardson

19

Hiç görüntü haritaları kullanmayan bir çözümle karşılaştım, daha ziyade görüntünün üzerine yerleştirilmiş bağlantı etiketleriyle karşılaştım. Tek dezavantajı, sıcak noktanın dikdörtgen olması gerektiğidir, ancak artı, bu çözümün Javascript'e, sadece CSS'ye dayanmamasıdır. Bağlantılar için HTML kodu oluşturmak üzere kullanabileceğiniz bir web sitesi vardır: http://www.zaneray.com/responsive-image-map/

Görüntüyü ve oluşturulan bağlantı etiketlerini nispeten konumlandırılmış bir div etiketine koydum ve her şey pencere yeniden boyutlandırma ve cep telefonumda mükemmel çalıştı.


2
Güzel bulmak! Bu listeye katkıda bulunduğunuz için teşekkür ederiz
jdog

1
Bu naswer yeterince upvote olamaz !! Bir mükemmel öğretici; kapsamlı ve kolay. Her şey okunmalı, ama özellikle ilgi çekici olan tutorials.jenkov.com/svg/scripting.html
Mawg, Monica'nın

Tıklanacak alan dikdörtgense bu gerçekten basit ama güzel bir çözümdür.
user2875289

Bu çok harika. Benim için de bir DNN sitesi ile çalıştım. Jeffrey'in belirttiği gibi, <img> ve üretilen html'yi göreceli konumlandırılmış bir div'ın içine bıraktım. Teşekkürler!
Ted Krapf

18

Dikdörtgen isabet alanlarıyla iyi iseniz, bunu çözmek için bir JS olmayan yol buldum.

Her şeyden önce, resminizin nispeten konumlandırılmış bir div içinde olduğundan emin olun. Sonra görüntüyü bu div içine koyun, yani div içindeki tüm alanı kaplayacaktır. Son olarak, ana div içinde görüntünün altına kesinlikle konumlandırılmış div'lar ekleyin ve bağlantı hit alanlarını istediğiniz boyut ve konuma getirmek için üst, sol, genişlik ve yükseklik için yüzdeleri kullanın.

İlk çalışırken siyah bir arka plan rengi (ideal olarak bazı alfa solmasıyla, altındaki bağlantılı içeriği görebilmeniz için) vermek ve yüzdeleri gerçek zamanlı olarak ayarlamak için tarayıcınızda bir kod denetçisi kullanmak en kolay yolu buluyorum , böylece doğru şekilde elde edebilirsiniz.

İşte çalışabileceğiniz temel anahat. Yüzdeleri olan her şeyi yaparak, öğelerin tümünün görüntü ölçekleriyle aynı göreceli boyut ve konumda kalmasını sağlarsınız.

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

Bu kodu Chrome'daki kod denetçinizle veya seçtiğiniz tarayıcınızla kullanın ve kutular doğru olana kadar yüzdeleri ayarlayın (daha kesin olması için ondalık yüzdeleri kullanabilirsiniz). Ayrıca seçim background-colorarasında transparentsize isabet alanlar görünmez olmak istiyorum çünkü kullanmaya hazır olduğunuzda.


Bu harika bir çözüm! Teşekkür ederim
xims

Güzel çözüm! UIkit işaretçileri için aynı tekniği kullanıyor: getuikit.com/docs/marker
xela84

Mükemmel çözüm, paylaştığınız için teşekkürler! Bunu bir mobil uygulamada kullanıyorum ve farklı ekranlar sorununu çözüyor.
JohnGIS


7

Aşağıdaki yöntem benim için mükemmel çalışıyor, bu yüzden tam uygulamam:

<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

Benim için çalışmak (koddaki 3 şeyi değiştirmeyi unutmayın):

  • previousGenişlik (görüntünün orijinal boyutu)

  • map_ID (resim haritanızın kimliği)

  • img_ID (resminizin kimliği)

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

Aynı gereksinimle karşılaşıyorum, herhangi bir ekran boyutu ve yeniden boyutlandırma ile yeniden boyutlandırabilen duyarlı görüntü haritası göstermek istiyorum, bu koordinatları vurgulamak istiyorum .

Bu yüzden ekran boyutuna ve olaya göre koordinatları yeniden boyutlandırabilen birçok kütüphaneyi denedim. Ve hemen hemen tüm tarayıcılarda iyi çalışan en iyi çözümü (jquery.imagemapster.min.js) aldım. Ayrıca görüntü haritası oluşturmak Summer Plgin ile entegre ettim .

 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>

Umarım birine yardım eder.


2

http://home.comcast.net/~urbanjost/semaphore.html , tartışmanın en üst sayfasıdır ve aslında sorunun JavaScript tabanlı bir çözümüne bağlantıları vardır. HTML'nin gelecekte yüzde birimleri destekleyeceğine dair bir bildirim aldım, ancak bu konuda oldukça uzun bir süredir ilerleme kaydetmedim (desteğin geleceğini duyduğumdan bu yana muhtemelen bir yıldan fazla oldu) muhtemelen JavaScript / ECMAScript ile rahat olup olmadığınıza bakmaya değer.


2

Github'daki resim haritası eklentisine göz atın . Hem vanilya JavaScript ile hem de jQuery eklentisi olarak çalışır.

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

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

Check demo .


1

Bağlıdır, bence aralıkları orantılı olarak ayarlamak için jQuery kullanabilirsiniz. Bu arada neden bir görüntü haritası kullanıyorsunuz? Ölçeklendirme div'larını veya başka öğeleri kullanamaz mısınız?


kesin çözüm ölçeklendirilmiş div'larla çalışırken, resim haritası "içerikle yönetilir" ve her türlü bölgeye izin verir. Teşekkürler, bunun için jquery'ye bakacağım.
jdog


0

Orland'ın cevabına benzer: https://stackoverflow.com/a/32870380/462781

Chris'in kodu ile burada: https://stackoverflow.com/a/12121309/462781

Alanlar bir ızgaraya sığarsa, en boy oranını koruyan% olarak bir genişlik kullanarak alanları saydam resimlerle kaplayabilirsiniz.

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

% Olarak bir kenar boşluğu kullanabilirsiniz. Ek olarak "boşluk" görüntüleri 3. seviyeli bir div içine yan yana yerleştirilebilir.


0

Nedense bu çözümlerin hiçbiri benim için çalışmadı. Dönüşümleri kullanarak en iyi başarıyı elde ettim.

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

0

duyarlı genişlik ve yükseklik

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

Kodunuzla Niente0'ın 2015'teki cevabı arasındaki farkları gösteren daha fazla içerik ekleyebilir misiniz ?
Michael - Clay Shirky
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.