Mam istniejącą mapę obrazu w responsywnym układzie html. Obrazy są skalowane zgodnie z rozmiarem przeglądarki, ale współrzędne obrazu mają oczywiście stałe rozmiary w pikselach. Jakie mam opcje zmiany rozmiaru współrzędnych mapy obrazu?
Mam istniejącą mapę obrazu w responsywnym układzie html. Obrazy są skalowane zgodnie z rozmiarem przeglądarki, ale współrzędne obrazu mają oczywiście stałe rozmiary w pikselach. Jakie mam opcje zmiany rozmiaru współrzędnych mapy obrazu?
Odpowiedzi:
Aby uzyskać responsywne mapy obrazu, musisz użyć wtyczki:
https://github.com/stowball/jQuery-rwdImageMaps (nie jest już obsługiwane)
Lub
https://github.com/davidjbradshaw/imagemap-resizer
Żadne większe przeglądarki nie rozumieją poprawnie współrzędnych procentowych i wszystkie interpretują współrzędne procentowe jako współrzędne pikseli.
http://www.howtocreate.co.uk/tutorials/html/imagemaps
A także ta strona do testowania, czy przeglądarki obsługują
Możesz także użyć SVG zamiast mapy obrazu. ;)
Istnieje poradnik, jak to zrobić.
.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>
Responsywne mapy obrazów Wtyczka jQuery autorstwa Matt Stow
$(window).trigger('resize');
window
w tym przypadku). Powodzenia.
Natrafiłem na rozwiązanie, które w ogóle nie używa map obrazów, ale raczej znaczniki kotwicy, które są absolutnie umieszczone nad obrazem. Jedyną wadą byłoby to, że hotspot musiałby być prostokątny, ale plusem jest to, że to rozwiązanie nie opiera się na Javascript, tylko na CSS. Istnieje witryna internetowa, której można użyć do wygenerowania kodu HTML dla kotwic: http://www.zaneray.com/responsive-image-map/
Umieściłem obraz i wygenerowane znaczniki kotwicy we względnie umieszczonym znaczniku DIV i wszystko działało idealnie przy zmianie rozmiaru okna i na moim telefonie komórkowym.
Znalazłem sposób bez JS, aby rozwiązać ten problem, jeśli nie przeszkadzają ci prostokątne obszary uderzenia.
Przede wszystkim upewnij się, że obraz znajduje się w elemencie div, który jest względnie ustawiony. Następnie umieść obraz wewnątrz tego elementu div, co oznacza, że zajmie on całą przestrzeń w elemencie div. Na koniec dodaj absolutnie pozycjonowane elementy div pod obrazem, w głównym div, i użyj wartości procentowych dla góry, lewej, szerokości i wysokości, aby uzyskać żądany rozmiar i pozycję obszarów kliknięcia linków.
Uważam, że najłatwiej jest nadać elementowi div koloru czarnego tła (najlepiej z pewnym zanikaniem alfa, aby można było zobaczyć połączoną zawartość pod spodem) podczas pierwszej pracy i użyć inspektora kodu w przeglądarce, aby dostosować wartości procentowe w czasie rzeczywistym , abyś mógł to zrobić dobrze.
Oto podstawowy zarys, z którym możesz pracować. Robiąc wszystko z procentami, upewniasz się, że wszystkie elementy mają ten sam względny rozmiar i położenie, co skalowanie obrazu.
<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>
Użyj tego kodu z inspektorem kodu w Chrome lub w wybranej przeglądarce i dostosuj wartości procentowe (możesz użyć procent dziesiętnych, aby być dokładniejszym), aż pola będą odpowiednie. Również wybrać background-color
od transparent
kiedy jesteś gotowy, aby go używać, ponieważ chcesz, aby obszary obrażeń być niewidoczne.
David Bradshaw napisał ładną małą bibliotekę, która rozwiązuje ten problem. Może być używany z jQuery lub bez niego.
Dostępne tutaj: https://github.com/davidjbradshaw/imagemap-resizer
Poniższa metoda działa idealnie dla mnie, więc oto moja pełna realizacja:
<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>
Pracuje dla mnie (pamiętaj o zmianie 3 rzeczy w kodzie):
previousWidth (oryginalny rozmiar obrazu)
map_ID (identyfikator mapy obrazu)
img_ID (identyfikator Twojego obrazu)
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/
Spotykam się z tym samym wymaganiem, w którym chcę pokazać responsywną mapę obrazu, która może zmieniać rozmiar z dowolnym rozmiarem ekranu i ważne jest, aby podkreślić te współrzędne .
Wypróbowałem więc wiele bibliotek, które mogą zmieniać rozmiar współrzędnych w zależności od rozmiaru ekranu i zdarzenia. I mam najlepsze rozwiązanie (jquery.imagemapster.min.js), które działa dobrze z prawie wszystkimi przeglądarkami. Zintegrowałem go również z Summer Plgin, która tworzy mapę obrazu.
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>
Mam nadzieję, że komuś pomogę.
http://home.comcast.net/~urbanjost/semaphore.html to główna strona dyskusji i tak naprawdę zawiera linki do rozwiązania problemu opartego na JavaScript. Otrzymałem powiadomienie, że HTML będzie obsługiwał jednostki procentowe w przyszłości, ale nie widziałem żadnych postępów w tej sprawie od dłuższego czasu (prawdopodobnie minął ponad rok, odkąd usłyszałem, że wsparcie będzie się zbliżać), więc obejście jest takie prawdopodobnie warto się temu przyjrzeć, jeśli dobrze znasz JavaScript / ECMAScript.
Sprawdź wtyczkę mapy obrazu na Github. Działa zarówno z waniliowym JavaScriptem, jak i jako wtyczka jQuery.
$('img[usemap]').imageMap(); // jQuery
ImageMap('img[usemap]') // JavaScript
Sprawdź demo .
To zależy, myślę, że możesz użyć jQuery do proporcjonalnej regulacji zakresów. Dlaczego przy okazji korzystasz z mapy obrazu? Nie możesz użyć do tego skalujących elementów div lub innych elementów?
Dla tych, którzy nie chcą uciekać się do JavaScript, oto przykład wycinania obrazu:
http://codepen.io/anon/pen/cbzrK
Gdy skalujesz okno, obraz klauna będzie odpowiednio skalowany, a kiedy to nastąpi, nos klauna pozostaje hiperłączem.
Podobnie jak odpowiedź Orlanda tutaj: https://stackoverflow.com/a/32870380/462781
W połączeniu z kodem Chrisa tutaj: https://stackoverflow.com/a/12121309/462781
Jeśli obszary mieszczą się w siatce, można je nałożyć przezroczystymi obrazami, używając szerokości w%, które zachowują proporcje.
.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>
Możesz użyć marginesu w%. Dodatkowo obrazy „kosmiczne” mogą być umieszczane obok siebie wewnątrz div 3 poziomu.
Z jakiegoś powodu żadne z tych rozwiązań nie zadziałało. Największy sukces odniosłem, używając transformacji.
transform: translateX(-5.8%) translateY(-5%) scale(0.884);
responsywna szerokość i wysokość
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;
}