code

반응형 이미지 맵

starcafe 2023. 10. 15. 17:32
반응형

반응형 이미지 맵

반응형 html 레이아웃의 기존 이미지 맵을 가지고 있습니다.이미지는 브라우저 크기에 따라 확장되지만 이미지 좌표는 분명히 고정된 픽셀 크기입니다.이미지 맵 좌표의 크기를 조정하려면 어떤 옵션이 있어야 합니까?

응답 이미지 맵의 경우 플러그인을 사용해야 합니다.

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

이미지 맵 대신 SVG를 사용할 수도 있습니다.이것을 하는 방법에 대한 튜토리얼이 있습니다.아래 샘플, 이 jsfiddle에서 가져온 것입니다.

.hover_group:hover {
  opacity: 1;
}

#projectsvg {
  position: relative;
  width: 100%;
  padding-bottom: 77%;
  vertical-align: middle;
  margin: 0;
  overflow: hidden;
  background: lightgreen;
}

#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" />

    <!-- create the regions -->
    <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>

이 문제를 해결할 수 있는 no-JS 방법을 찾았습니다.테두리 반경을 변경하여 원형 또는 타원형 영역을 만들지 않는 한 히트 영역은 직사각형이 됩니다.

우선 이미지가 상대적으로 위치한 디브인지 확인합니다.그러면 이 디브 안에 이미지를 넣으면 디브 안의 공간을 모두 차지하게 됩니다.마지막으로 이미지 아래, 메인 디브 내에 절대 위치한 디브를 추가하고 상단, 왼쪽, 너비 및 높이에 대한 사용 백분율을 사용하여 원하는 크기와 위치의 링크 히트 영역을 얻습니다.

처음 작업할 때 디바에 검은색 배경색을 부여하고(아래에 링크된 내용을 볼 수 있도록 알파 페이딩이 있는 것이 이상적입니다) 브라우저에서 코드 검사기를 사용하여 실시간으로 백분율을 조정하여 올바르게 작업할 수 있습니다.

작업할 수 있는 기본 개요입니다.모든 작업을 백분율로 수행하면 요소가 모두 이미지 스케일과 동일한 상대 크기와 위치를 유지할 수 있습니다.

<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-colortransparent사용할 준비가 되어 있는 경우에 사용할 수 있습니다. 히트 영역이 보이지 않기를 원하기 때문입니다.

Matt Stow의 Response Image Maps jQuery 플러그인

이미지 맵을 전혀 사용하지 않고 이미지 위에 절대적으로 위치한 앵커 태그를 사용하는 솔루션을 우연히 발견했습니다.유일한 단점은 핫스팟이 직사각형이어야 한다는 것이지만, 이 솔루션은 자바스크립트에만 의존하지 않고 CSS에만 의존한다는 것입니다.앵커들을 위한 HTML 코드를 생성하기 위해 사용할 수 있는 웹사이트가 있습니다: http://www.zaneray.com/responsive-image-map/

이미지와 생성된 앵커 태그를 비교적 위치에 있는 div 태그에 넣었고 모든 것이 윈도우 크기와 휴대폰에서 완벽하게 작동했습니다.

데이비드 브래드쇼는 이 문제를 해결하는 멋진 작은 도서관을 썼습니다.jQuery 사용 여부와 상관없이 사용할 수 있습니다.

여기서 이용 가능: https://github.com/davidjbradshaw/imagemap-resizer

다음 방법이 완벽하게 적용되므로 전체 구현 방법은 다음과 같습니다.

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

이 이미지 맵퍼를 사용하는 것을 고려합니다.

https://imagemapper.noc.io/ #/ | github | 대체 링크

그것의 SVG 기반과 그것의 반응성 그리고

지도를 만들 수 있는 좋은 마법사들이 있습니다.

그것은 라이브러리를 사용하지 않기 때문에 페이지에 충분히 간단합니다.

나를 위해 일하는 것(코드에서 3가지를 변경하는 것을 기억하세요):

  • 이전의너비(이미지의 원래 크기)

  • map_ID(이미지 맵의 ID)

  • img_ID(이미지의 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>

자바스크립트:

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/

Github에서 이미지 맵 플러그인을 확인해보세요.바닐라 자바스크립트와 jQuery 플러그인 모두에서 작동합니다.

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

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

데모를 확인해 보세요.

화면 크기에 상관없이 크기를 조정할 수 있는 반응형 이미지 맵을 보여주고 싶고 중요한 것은 좌표를 강조하고 싶은 것과 같은 요구사항을 발견했습니다.

그래서 화면 크기와 이벤트에 따라 좌표 크기를 조절할 수 있는 라이브러리를 많이 시도했습니다.그리고 거의 모든 브라우저에서 잘 작동하는 최고의 솔루션(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>

누군가에게 도움이 되길 바랍니다.

자바스크립트에 의존하지 않으려는 사람들을 위해 이미지 슬라이싱 예를 들어보겠습니다.

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

창을 확대하면 광대 이미지가 그에 따라 확대되고, 확대되면 광대의 코가 과결합 상태로 유지됩니다.

따라서, jQuery를 사용하여 범위를 비례적으로 조정할 수 있을 것 같습니다.그런데 왜 이미지 맵을 사용합니까?스케일링 디브나 다른 요소를 사용할 수는 없나요?

여기서 올랜드의 답변과 유사합니다: 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단계 디브 안에서 서로 옆에 배치할 수 있습니다.

어떤 이유에서인지 이러한 해결책은 저에게 효과가 없었습니다.저는 변신을 이용해 최고의 성공을 거두었습니다.

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

Tom Bisciglia가 제안한 해결책의 자바스크립트 버전을 만들었습니다.

내 코드를 사용하면 일반 이미지 맵을 사용할 수 있습니다.CSS 몇 줄과 JS 몇 줄만 로드하면 되고...BOOM... 이미지 맵에 호버 상태가 있고 응답이 완벽합니다!마술이죠?

var images = document.querySelectorAll('img[usemap]');
images.forEach( function(image) {
    var mapid = image.getAttribute('usemap').substr(1);
    var imagewidth = image.getAttribute('width');
    var imageheight = image.getAttribute('height');
    var imagemap = document.querySelector('map[name="'+mapid+'"]');
    var areas = imagemap.querySelectorAll('area');

    image.removeAttribute('usemap');
    imagemap.remove();

    // create wrapper container
    var wrapper = document.createElement('div');
    wrapper.classList.add('imagemap');
    image.parentNode.insertBefore(wrapper, image);
    wrapper.appendChild(image);

    areas.forEach( function(area) {
        var coords = area.getAttribute('coords').split(',');
        var xcoords = [parseInt(coords[0]),parseInt(coords[2])];
        var ycoords = [parseInt(coords[1]),parseInt(coords[3])];
        xcoords = xcoords.sort(function(a, b){return a-b});
        ycoords = ycoords.sort(function(a, b){return a-b});
        wrapper.innerHTML += "<a href='"+area.getAttribute('href')+"' title='"+area.getAttribute('title')+"' class='area' style='left: "+((xcoords[0]/imagewidth)*100).toFixed(2)+"%; top: "+((ycoords[0]/imageheight)*100).toFixed(2)+"%; width: "+(((xcoords[1] - xcoords[0])/imagewidth)*100).toFixed(2)+"%; height: "+(((ycoords[1] - ycoords[0])/imageheight)*100).toFixed(2)+"%;'></a>";
    });
});
img {max-width: 100%; height: auto;}

.imagemap {position: relative;}
.imagemap img {display: block;}
.imagemap .area {display: block; position: absolute; transition: box-shadow 0.15s ease-in-out;}
.imagemap .area:hover {box-shadow: 0px 0px 1vw rgba(0,0,0,0.5);}
<!-- Image Map Generated by http://www.image-map.net/ -->
<img src="https://i.imgur.com/TwmCyCX.jpg" width="2000" height="2604" usemap="#image-map">
<map name="image-map">
    <area target="" alt="Zirconia Abutment" title="Zirconia Abutment" href="/" coords="3,12,199,371" shape="rect">
    <area target="" alt="Gold Abutment" title="Gold Abutment" href="/" coords="245,12,522,371" shape="rect">
    <area target="" alt="CCM Abutment" title="CCM Abutment" href="/" coords="564,12,854,369" shape="rect">
    <area target="" alt="EZ Post Abutment" title="EZ Post Abutment" href="/" coords="1036,12,1360,369" shape="rect">
    <area target="" alt="Milling Abutment" title="Milling Abutment" href="/" coords="1390,12,1688,369" shape="rect">
    <area target="" alt="Angled Abutment" title="Angled Abutment" href="/" coords="1690,12,1996,371" shape="rect">
    <area target="" alt="Temporary Abutment [Metal]" title="Temporary Abutment [Metal]" href="/" coords="45,461,506,816" shape="rect">
    <area target="" alt="Fuse Abutment" title="Fuse Abutment" href="/" coords="1356,461,1821,816" shape="rect">
    <area target="" alt="Lab Analog" title="Lab Analog" href="/" coords="718,935,1119,1256" shape="rect">
    <area target="" alt="Transfer Impression Coping Driver" title="Transfer Impression Coping Driver" href="/" coords="8,1330,284,1731" shape="rect">
    <area target="" alt="Impression Coping [Transfer]" title="Impression Coping [Transfer]" href="/" coords="310,1330,697,1731" shape="rect">
    <area target="" alt="Impression Coping [Pick-Up]" title="Impression Coping [Pick-Up]" href="/" coords="1116,1330,1560,1733" shape="rect">
</map>

var images = document.querySelectorAll('img[usemap]');
images.forEach( function(image) {
    var mapid = image.getAttribute('usemap').substr(1);
    var imagewidth = image.getAttribute('width');
    var imageheight = image.getAttribute('height');
    var imagemap = document.querySelector('map[name="'+mapid+'"]');
    var areas = imagemap.querySelectorAll('area');

    image.removeAttribute('usemap');
    imagemap.remove();

    // create wrapper container
    var wrapper = document.createElement('div');
    wrapper.classList.add('imagemap');
    image.parentNode.insertBefore(wrapper, image);
    wrapper.appendChild(image);

    areas.forEach( function(area) {
        var coords = area.getAttribute('coords').split(',');
        var xcoords = [parseInt(coords[0]),parseInt(coords[2])];
        var ycoords = [parseInt(coords[1]),parseInt(coords[3])];
        xcoords = xcoords.sort(function(a, b){return a-b});
        ycoords = ycoords.sort(function(a, b){return a-b});
        wrapper.innerHTML += "<a href='"+area.getAttribute('href')+"' title='"+area.getAttribute('title')+"' class='area' style='left: "+((xcoords[0]/imagewidth)*100).toFixed(2)+"%; top: "+((ycoords[0]/imageheight)*100).toFixed(2)+"%; width: "+(((xcoords[1] - xcoords[0])/imagewidth)*100).toFixed(2)+"%; height: "+(((ycoords[1] - ycoords[0])/imageheight)*100).toFixed(2)+"%;'></a>";
    });
});
img {max-width: 100%; height: auto;}

.imagemap {position: relative;}
.imagemap img {display: block;}
.imagemap .area {display: block; position: absolute; transition: box-shadow 0.15s ease-in-out;}
.imagemap .area:hover {box-shadow: 0px 0px 1vw rgba(0,0,0,0.5);}
<!-- Image Map Generated by http://www.image-map.net/ -->
<img src="https://i.imgur.com/TwmCyCX.jpg" width="2000" height="2604" usemap="#image-map">
<map name="image-map">
    <area target="" alt="Zirconia Abutment" title="Zirconia Abutment" href="/" coords="3,12,199,371" shape="rect">
    <area target="" alt="Gold Abutment" title="Gold Abutment" href="/" coords="245,12,522,371" shape="rect">
    <area target="" alt="CCM Abutment" title="CCM Abutment" href="/" coords="564,12,854,369" shape="rect">
    <area target="" alt="EZ Post Abutment" title="EZ Post Abutment" href="/" coords="1036,12,1360,369" shape="rect">
    <area target="" alt="Milling Abutment" title="Milling Abutment" href="/" coords="1390,12,1688,369" shape="rect">
    <area target="" alt="Angled Abutment" title="Angled Abutment" href="/" coords="1690,12,1996,371" shape="rect">
    <area target="" alt="Temporary Abutment [Metal]" title="Temporary Abutment [Metal]" href="/" coords="45,461,506,816" shape="rect">
    <area target="" alt="Fuse Abutment" title="Fuse Abutment" href="/" coords="1356,461,1821,816" shape="rect">
    <area target="" alt="Lab Analog" title="Lab Analog" href="/" coords="718,935,1119,1256" shape="rect">
    <area target="" alt="Transfer Impression Coping Driver" title="Transfer Impression Coping Driver" href="/" coords="8,1330,284,1731" shape="rect">
    <area target="" alt="Impression Coping [Transfer]" title="Impression Coping [Transfer]" href="/" coords="310,1330,697,1731" shape="rect">
    <area target="" alt="Impression Coping [Pick-Up]" title="Impression Coping [Pick-Up]" href="/" coords="1116,1330,1560,1733" shape="rect">
</map>

응답 폭 & 높이

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

언급URL : https://stackoverflow.com/questions/7844399/responsive-image-map

반응형