Bản đồ hình ảnh đáp ứng


145

Tôi có một bản đồ hình ảnh hiện có trong một bố cục html đáp ứng. Hình ảnh tỷ lệ theo kích thước trình duyệt, nhưng tọa độ hình ảnh rõ ràng là kích thước pixel cố định. Tôi có những lựa chọn nào để thay đổi kích thước tọa độ bản đồ hình ảnh?


6
Câu hỏi này không phải là về bản đồ địa lý mà là thẻ html <map>
jdog

4
Kiểm tra các plugin hình ảnh bản đồ . Nó hoạt động với Javascript, Node và jQuery
Travis Clarke

2
Để thay thế, bạn có thể sử dụng hình ảnh SVG. Tôi khuyên bạn nên đọc Sử dụng SVG như một giải pháp thay thế cho hình ảnh
Mawg nói rằng hãy phục hồi Monica

1
Âm thanh giống như những gì chúng ta muốn là khả năng tải lên JPEG hoặc tương tự như ứng dụng cho phép bạn chỉ định vị trí bản đồ trên hình ảnh (chẳng hạn như tại mạng chấm bản đồ hình ảnh) - trong nền, điều này tạo ra tệp SVG về cơ bản trong suốt . Sau đó, chúng tôi muốn bản đồ áp dụng cho SVG và hiển thị SVG trên đầu JPG trong trình duyệt web. Khi trình duyệt thay đổi kích thước JPG, SVG cũng được thay đổi kích thước và SVG luôn luôn được gọi khi nhấp vào bản đồ hình ảnh. Bất kỳ đề nghị về bất kỳ phần nào của điều này?
youcantryreachingme

2
Vâng, đó là những gì tôi muốn trong năm 2011
jdog 15/03/18

Câu trả lời:


89

Đối với bản đồ hình ảnh đáp ứng, bạn sẽ cần sử dụng một plugin:

https://github.com/stowball/jQuery-rwdImageMaps (Không còn được duy trì)

Hoặc là

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


Không có trình duyệt chính nào hiểu chính xác tọa độ phần trăm và tất cả diễn giải tọa độ phần trăm dưới dạng tọa độ pixel.

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

Và cũng trang này để kiểm tra xem trình duyệt có thực hiện không

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


5
bất kỳ điều này vẫn còn có liên quan? bạn có thể cung cấp một bản cập nhật xin vui lòng?
Malachi

1
@Malachi Có, điều này vẫn có liên quan
Tom

cảm ơn Tom, chúng tôi đã có một cuộc thảo luận về một câu hỏi trên CodeReview, bây giờ tôi ước tôi có thể nhớ câu hỏi ....
Malachi

@ Tom này chỉ hoạt động cho một image..if chúng ta đặt hình ảnh khác thì không nó làm việc cho hình ảnh thứ hai và thứ ba vv ... chỉ cần kiểm tra nó ..
User2413

1
Tôi đã tìm thấy một công cụ phát trực tuyến mà sử dụng SVGs đó tất cả các trình duyệt lớn hiểu imagemapper.noc.io
frthjf

43

Bạn cũng có thể sử dụng svg thay vì bản đồ hình ảnh. ;)

Có một hướng dẫn về cách làm điều này.

.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
Liên kết hướng dẫn bị hỏng. Hình ảnh từ jsfiddle là tốt.
Cristiano Maia

Tôi báo hiệu liên kết hướng dẫn đã bị hỏng và cập nhật đoạn mã jsfiddle và đoạn mã. Cảm ơn bạn đã ngẩng cao đầu
belgac

Đây là một giải pháp tuyệt vời. Tôi đã sử dụng nó thành công và hoạt động như một bùa mê. Cảm ơn!
Jaume Mussons Abad

3
Cho đến nay, giải pháp tốt nhất vào năm 2020. Hãy thử trình tạo mã này để làm cho nó siêu đơn giản. fantemapper.noc.io/#
Brett Donald

1
Đây phải là giải pháp đáp ứng tốt nhất hàng đầu vào năm 2020.
huyền thoại mã hóa

39

1
Chỉ và FYI cho eveyrone ... Tôi đã thấy rằng điều này hoạt động tốt, nhưng không phải trong một hiệp ước. Tôi đang sử dụng Bootstrap 3 và nếu bạn không tải trang với accordion mở trên hình ảnh, khi bạn mở accordion, bản đồ hình ảnh sẽ không ở đó trừ khi cửa sổ trình duyệt được thay đổi kích thước.
jasonflaherty

1
@jasonflaherty bạn có thể kích hoạt một sự kiện thay đổi kích thước để buộc bản đồ hiển thị không? $(window).trigger('resize');
Steve Meisner

@SteveMeisner Tôi chưa thử điều đó ... nhưng điều đó có buộc phải làm mới không?
jasonflaherty

@jasonflaherty không! Nó chỉ "kích hoạt" sự kiện thay đổi kích thước trên phần tử bạn liên kết ( windowtrong trường hợp này). Chúc may mắn.
Steve Meisner

Chỉ cần tạo mô-đun Drupal siêu cơ bản nhưng tiện dụng bằng cách sử dụng plugin này: drupal.org/project/responsive_imagemaps
Joshua Stewardson

19

Tôi đã chạy qua một giải pháp hoàn toàn không sử dụng bản đồ hình ảnh mà thay vào đó là các thẻ neo được định vị tuyệt đối trên hình ảnh. Hạn chế duy nhất là điểm nóng sẽ phải là hình chữ nhật, nhưng điểm cộng là giải pháp này không phụ thuộc vào Javascript, chỉ là CSS. Có một trang web mà bạn có thể sử dụng để tạo mã HTML cho các neo: http://www.zaneray.com/responsive-image-map/

Tôi đặt hình ảnh và các thẻ neo được tạo trong thẻ div tương đối định vị và mọi thứ hoạt động hoàn hảo trên thay đổi kích thước cửa sổ và trên điện thoại di động của tôi.


2
Đẹp tìm thấy! Cảm ơn bạn đã đóng góp vào danh sách này
jdog

1
Tôi không thể nâng cấp chiếc khăn này đủ !! Một hướng dẫn tuyệt vời ; toàn diện và dễ dàng để hiểu Người ta phải đọc nó tất cả, nhưng quan tâm đặc biệt là tutorials.jenkov.com/svg/scripting.html
Mawg nói Khôi phục Monica

Đây là một giải pháp thực sự đơn giản nhưng tốt đẹp nếu khu vực cần nhấp là hình chữ nhật.
dùng2875289

Việc này thật là tuyệt. Làm việc cho tôi cũng như với một trang web DNN. Như Jeffrey đã nói, tôi vừa bỏ <img> và html được tạo bên trong một div có vị trí tương đối. Cảm ơn!
Ted Krapf

17

Tôi đã tìm thấy một cách không có JS để giải quyết vấn đề này nếu bạn thấy ổn với các khu vực hình chữ nhật.

Trước hết, hãy chắc chắn rằng hình ảnh của bạn ở vị trí tương đối chính xác. Sau đó đặt hình ảnh bên trong div này, có nghĩa là nó sẽ chiếm hết không gian trong div. Cuối cùng, thêm div vị trí tuyệt đối dưới hình ảnh, trong div chính và sử dụng tỷ lệ phần trăm cho đỉnh, trái, chiều rộng và chiều cao để có được các vùng nhấn liên kết kích thước và vị trí bạn muốn.

Tôi thấy dễ dàng nhất để cung cấp cho div màu nền đen (lý tưởng nhất là với một số fading alpha để bạn có thể thấy nội dung được liên kết bên dưới) khi bạn làm việc lần đầu và sử dụng trình kiểm tra mã trong trình duyệt của bạn để điều chỉnh tỷ lệ phần trăm trong thời gian thực , để bạn có thể làm cho nó vừa phải.

Đây là phác thảo cơ bản mà bạn có thể làm việc với. Bằng cách thực hiện mọi thứ với tỷ lệ phần trăm, bạn đảm bảo tất cả các yếu tố giữ nguyên kích thước và vị trí tương đối như tỷ lệ hình ảnh.

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

Sử dụng mã này với trình kiểm tra mã của bạn trong Chrome hoặc trình duyệt bạn chọn và điều chỉnh tỷ lệ phần trăm (bạn có thể sử dụng tỷ lệ phần trăm thập phân để chính xác hơn) cho đến khi các hộp vừa phải. Đồng thời chọn một background-colortrong những transparentkhi bạn đã sẵn sàng để sử dụng nó vì bạn muốn các khu vực đánh của bạn trở nên vô hình.


Đây là một giải pháp tuyệt vời! Cảm ơn bạn
xims

Giải pháp tốt đẹp! UIkit sử dụng kỹ thuật tương tự cho các điểm đánh dấu của họ: getuikit.com/docs/marker
xela84

Giải pháp tuyệt vời, cảm ơn đã chia sẻ! Tôi đang sử dụng điều này trong một ứng dụng di động và nó giải quyết vấn đề của các màn hình khác nhau.
JohnGIS

11

David Bradshaw đã viết một thư viện nhỏ đẹp để giải quyết vấn đề này. Nó có thể được sử dụng có hoặc không có jQuery.

Có sẵn tại đây: https://github.com/davidjbradshaw/imagemap-resizer


Xác nhận đã hoạt động trong các phiên bản Chrome / IE / FF mới nhất kể từ nhận xét này.
James Paterson

1
Làm việc rất tốt với tôi, giao diện siêu đơn giản nữa
Brian

7

Phương pháp sau đây hoạt động hoàn hảo đối với tôi, vì vậy đây là cách thực hiện đầy đủ của tôi:

<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

Làm việc cho tôi (nhớ thay đổi 3 điều trong mã):

  • trướcWidth (kích thước ban đầu của hình ảnh)

  • map_ID (id của bản đồ hình ảnh của bạn)

  • img_ID (id hình ảnh của bạn)

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

Mã thông báo: http://jsfiddle.net/p7EyT/154/


3

Tôi bắt gặp cùng một yêu cầu, ở đó, tôi muốn hiển thị bản đồ hình ảnh phản hồi có thể thay đổi kích thước với bất kỳ kích thước màn hình nào và điều quan trọng là, tôi muốn làm nổi bật tọa độ đó .

Vì vậy, tôi đã thử nhiều thư viện có thể thay đổi kích thước tọa độ theo kích thước màn hình và sự kiện. Và tôi đã có giải pháp tốt nhất (jquery.imagemapster.min.js) hoạt động tốt với hầu hết tất cả các trình duyệt. Ngoài ra tôi đã tích hợp nó với Summer Plgin để tạo bản đồ hình ảnh.

 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>

Hy vọng giúp nó cho một ai đó.


2

http://home.comcast.net/~urbanjost/semaphore.html là trang hàng đầu cho cuộc thảo luận và thực sự có các liên kết đến một giải pháp dựa trên JavaScript cho vấn đề. Tôi đã nhận được một thông báo rằng HTML sẽ hỗ trợ các đơn vị phần trăm trong tương lai nhưng tôi đã không thấy bất kỳ tiến triển nào về vấn đề này trong một thời gian khá lâu (có lẽ đã hơn một năm kể từ khi tôi nghe nói sẽ có hỗ trợ) có lẽ đáng xem nếu bạn cảm thấy thoải mái với JavaScript / ECMAScript.



1

Tôi nghĩ, bạn có thể sử dụng jQuery để điều chỉnh các phạm vi theo tỷ lệ tôi nghĩ. Tại sao bạn sử dụng một bản đồ hình ảnh bằng cách này? Bạn không thể sử dụng div quy mô hoặc các yếu tố khác cho nó?


trong khi giải pháp chính xác sẽ hoạt động với các div được chia tỷ lệ, bản đồ hình ảnh là "nội dung được quản lý" và không cho phép bất kỳ loại khu vực nào. Cảm ơn, tôi sẽ kiểm tra jquery cho điều này.
jdog

1

Đối với những người không muốn dùng đến JavaScript, đây là một ví dụ cắt ảnh:

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

Khi bạn chia tỷ lệ cửa sổ, hình ảnh chú hề sẽ chia tỷ lệ tương ứng, và khi đó, mũi của chú hề vẫn siêu liên kết.


2
Cảm ơn những cơn ác mộng!
jerrygarciuh

1
Liên kết hình ảnh đều bị hỏng.
Tyler Forsythe

0

Tương tự như câu trả lời của Dessert tại đây: https://stackoverflow.com/a/32870380/462781

Kết hợp với mã của Chris tại đây: https://stackoverflow.com/a/12121309/462781

Nếu các khu vực vừa với lưới, bạn có thể che phủ các khu vực bằng hình ảnh trong suốt bằng cách sử dụng chiều rộng theo% giữ tỷ lệ khung hình của chúng.

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

Bạn có thể sử dụng ký quỹ theo%. Ngoài ra, hình ảnh "không gian" có thể được đặt cạnh nhau trong div cấp 3.


0

Đối với một số lý do không có giải pháp nào trong số này làm việc cho tôi. Tôi đã thành công nhất khi sử dụng biến đổi.

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

0

chiều rộng đáp ứng && chiều cao

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

Bạn có thể thêm một số nội dung cho thấy sự khác biệt giữa mã của bạn và câu trả lời của Niente0 từ năm 2015 không?
Michael - Clay Shirky
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.