レスポンシブイメージマップ


145

レスポンシブhtmlレイアウトの既存のイメージマップがあります。画像はブラウザのサイズに従って拡大縮小されますが、画像の座標は明らかに固定されたピクセルサイズです。イメージマップ座標のサイズを変更するには、どのようなオプションが必要ですか?


6
この質問は地理的な地図ではなく、<map> htmlタグ
jdog

4
画像マッププラグインをチェックしてください。Javascript、Node、jQueryで動作します
Travis Clarke

2
別の方法として、SVG画像を使用できます。イメージマップの代わりにSVGを使用することをお勧めします
イメージマップの

1
私たちが望んでいるように聞こえるのは、JPEG(または画像マップドットネットなど)上のマップの場所を指定できるアプリに類似した機能をアップロードする機能です。これにより、バックグラウンドで、本質的に透明なSVGファイルが生成されます。 。次に、マップをSVGに適用し、WebブラウザーでJPGの上にSVGをレンダリングします。ブラウザがJPGのサイズを変更すると、SVGもサイズ変更され、SVGは常にイメージマップをクリックしたときに呼び出されます。この部分について何か提案はありますか?
youcantryreachingme 2018年

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
これはまだ関連していますか?アップデートを提供していただけませんか?
マラキ2014年

1
@Malachiはい、これはまだ関連しています
トム

トムは、私たちが....今私は疑問を覚えていることがしたい、コードレビューの問題について議論を持ったあなたに感謝
マラキ

私たちはその後、別の画像を置き、その第二と第三の画像のために働くことなど...ただ...それをチェックしませimage..if @Tomこれは一つだけの作品
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 2017年

これは素晴らしいソリューションです。私はそれをうまく使い、魅力のように働いています。ありがとう!
Jaume Mussons Abad

3
2020年にはこれまでで最高のソリューションです。このコードジェネレーターを試して、非常にシンプルにしてください。imagemapper.noc.io/#
Brett Donald

1
これは、2020年のトップ最良の応答ソリューションである必要があります
mythicalcoder

39

1
eveyroneの正義と参考までに...これはうまく機能するが、アコーディオンの内部では機能しないことがわかりました。私はBootstrap 3を使用しています。画像上でアコーディオンを開いた状態でページをロードしない場合、アコーディオンを開いても、ブラウザーウィンドウのサイズを変更しない限り、画像マップは表示されません。
jasonflaherty 2013年

1
@jasonflahertyは、サイズ変更イベントをトリガーしてマップを強制的に表示できますか?$(window).trigger('resize');
Steve Meisner、2014年

@SteveMeisnerまだ試していません...しかし、強制的に更新しませんか?
jasonflaherty 2014年

@jasonflahertyいいえ バインドする要素(windowこの場合は)のサイズ変更イベントを「トリガー」するだけです。幸運を。
Steve Meisner

このプラグインを使用して、超基本的で便利なDrupalモジュールを作成しました:drupal.org/project/responsive_imagemaps
Joshua Stewardson

19

画像マップをまったく使用せず、画像の上に絶対的に配置されたアンカータグを使用するソリューションを見つけました。唯一の欠点は、ホットスポットが長方形である必要があることですが、プラスに、このソリューションはJavaScriptに依存せず、CSSにのみ依存します。アンカーのHTMLコードを生成するために使用できるWebサイトがあります:http : //www.zaneray.com/responsive-image-map/

画像と生成されたアンカータグを相対的に配置されたdivタグに配置すると、ウィンドウのサイズ変更と携帯電話ですべてが完璧に機能しました。


2
素敵な発見!このリストにご協力いただきありがとうございます
jdog

1
私はこの名声を十分に賛成できない!優れたチュートリアル。包括的でわかりやすい。すべてを読む必要がありますが、特に興味深いのはtutorials.jenkov.com/svg/scripting.htmlです
Mawgはモニカを2017

クリックされる領域が長方形の場合、これは本当にシンプルでありながら優れたソリューションです。
user2875289

これはすごいです。DNNサイトで私も働いた。ジェフリーが述べたように、私は<img>と生成されたhtmlを相対位置のdivの中にドロップしました。ありがとう!
Ted Krapf、

18

長方形のヒット領域で大丈夫な場合、これに対処するための非JSの方法を見つけました。

まず、画像が相対的に配置されたdivにあることを確認してください。次に、このdiv内に画像を配置します。つまり、div内のすべてのスペースを占有します。最後に、画像の下、メインdiv内に絶対位置の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または選択したブラウザのコードインスペクタでこのコードを使用し、ボックスが適切になるまでパーセンテージを調整します(正確には10進数のパーセンテージを使用できます)。また、選択したbackground-colorのをtransparent、あなたはあなたのヒット領域が見えないようにしたいので、それを使用する準備ができたら。


これは素晴らしいソリューションです!ありがとう
xims

素敵な解決策!UIkitは同じ手法をマーカーに使用します。getuikit.com
docs

素晴らしいソリューション、共有してくれてありがとう!私はこれをモバイルアプリで使用しており、さまざまな画面の問題を解決しています。
JohnGIS

11

David Bradshawがこの問題を解決する素敵な小さなライブラリを書いた。jQueryの有無にかかわらず使用できます。

ここで利用可能:https : //github.com/davidjbradshaw/imagemap-resizer


このコメントの時点で、Chrome / IE / FFの最新バージョンで動作することを確認しました。
James Paterson

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つのことを変更することを忘れないでください):

  • previousWidth(画像の元のサイズ)

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

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が将来的にパーセント単位をサポートするという通知を受け取りましたが、しばらくの間、これに関する進展は見られません(サポートが近づくと聞いてから1年以上経過している可能性があります)。そのため、回避策はJavaScript / ECMAScriptに慣れている場合は、おそらく一見の価値があります。



1

場合によっては、jQueryを使用して範囲を比例的に調整できると思います。ところで、なぜイメージマップを使うのですか?スケーリングdivまたはその他の要素を使用できませんか?


正確なソリューションはスケーリングされたdivで機能しますが、イメージマップは「コンテンツ管理」であり、あらゆる種類のリージョンを許可します。おかげで、これについてjqueryをチェックします。
jdog 2011年

1

JavaScriptに頼りたくない人のために、画像スライスの例を以下に示します。

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

ウィンドウを拡大縮小すると、それに応じてピエロの画像が拡大縮小し、拡大すると、ピエロの鼻がハイパーリンクのままになります。


2
悪夢をありがとう!
jerrygarciuh 14年

1
画像リンクはすべて壊れています。
タイラーフォーサイス2017年

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番目のレベルのdiv内に並べて配置できます。


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

コードと2015年のNiente0の回答の違いを示すコンテンツをさらに追加できます か?
マイケル-クレイシャーキーはどこですか
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.