私は現在、ウィンドウのサイズに応じてサイズを変更するイメージマップを自分のサイトで作成しようとしています... HTMLでこれを行う方法があるのか、Javascriptまたは別の方法でこれを行う必要があるのか疑問に思っていました言語。
<div style="text-align:center; width:1920px; margin-left:auto; margin-right:auto;">
<img id="Image-Maps_5201211070133251" src="Site.png" usemap="#Image-Maps_5201211070133251" border="0" width="1920" height="1080" alt="" />
<map id="_Image-Maps_5201211070133251" name="Image-Maps_5201211070133251">
<area shape="poly" coords="737,116,1149,118,944,473," href="http://essper.bandcamp.com" alt="Bandcamp" title="Bandcamp" />
<area shape="poly" coords="1006,589,1418,590,1211,945," href="http://soundcloud.com/essper" alt="Soundcloud" title="Soundcloud" />
<area shape="poly" coords="502,590,910,591,708,944," href="http://facebook.com/the.essper" alt="Facebook" title="Facebook" />
</map>
JavaScriptを使用してタスクを実行することになった場合は、MAP
要素内のすべての領域のサイズを変更するためのクロスブラウザーコードスニペットがあります。
window.onload = function () {
var ImageMap = function (map) {
var n,
areas = map.getElementsByTagName('area'),
len = areas.length,
coords = [],
previousWidth = 1920;
for (n = 0; n < len; n++) {
coords[n] = areas[n].coords.split(',');
}
this.resize = function () {
var n, m, clen,
x = document.body.clientWidth / 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 = document.body.clientWidth;
return true;
};
window.onresize = this.resize;
},
imageMap = new ImageMap(document.getElementById('map_ID'));
imageMap.resize();
}
previousWidth
は元の画像の幅と等しくなければなりません。また、HTMLでいくつかの相対単位を使用する必要があります。
<div style="width:100%;">
<img id="Image-Maps_5201211070133251" src="Site.png" usemap="#Image-Maps_5201211070133251" border="0" width="100%" alt="" />
jsFiddle での作業デモ。 IEでフィドルを開くと、実際にクリックするとAREA
sが表示されます。
ImageMapをサイズ変更可能な画像にスケーリングするために小さな小さなライブラリを作成したため、画像がスケーリングしてもマップは同期したままになります。パーセンテージでスケーリングされた画像などをマップする場合に便利です。
JQueryの有無にかかわらず使用できます。
https://github.com/davidjbradshaw/imagemap-resizer
そして、あなたはそれが動くのを見ることができます。
クラスとして(ES6):
class ResponsiveImageMap {
constructor(map, img, width) {
this.img = img;
this.originalWidth = width;
this.areas = [];
for (const area of map.getElementsByTagName('area')) {
this.areas.Push({
element: area,
originalCoords: area.coords.split(',')
});
}
window.addEventListener('resize', e => this.resize(e));
this.resize();
}
resize() {
const ratio = this.img.offsetWidth / this.originalWidth;
for (const area of this.areas) {
const newCoords = [];
for (const originalCoord of area.originalCoords) {
newCoords.Push(Math.round(originalCoord * ratio));
}
area.element.coords = newCoords.join(',');
}
return true;
};
}
使用法:
var map = document.getElementById('myMapId');
var image = document.getElementById('myImageId');
new ResponsiveImageMap(map, image, 800);
元の画像とスタイル設定された画像の比率を座標に掛けることができます。
<img id="paredea" usemap="#PAREDE-A" src="https://i.imgur.com/o9nrUMR.png">
<map name="PAREDE-A">
<area id="paredea0" shape="rect" onclick="alert('colmeia A')">
<area id="paredea1" shape="rect" onclick="alert('colmeia B')">
<area id="paredea2" shape="rect" onclick="alert('colmeia C')">
<area id="paredea3" shape="rect" onclick="alert('colmeia D')">
<area id="paredea4" shape="rect" onclick="alert('colmeia E')">
<area id="paredea5" shape="rect" onclick="alert('comeia F')">
<area id="paredea6" shape="rect" onclick="alert('colmeia G')">
<area id="paredea7" shape="rect" onclick="alert('colmeia H')">
<area id="paredea8" shape="rect" onclick="alert('colmeia I')">
<area id="paredea9" shape="rect" onclick="alert('colmeia J')">
<area id="paredea10" shape="rect" onclick="alert('colmeia K')">
<area id="paredea11" shape="rect" onclick="alert('colmeia L')">
<area id="paredea12" shape="rect" onclick="alert('colmeia M')">
<area id="paredea13" shape="rect" onclick="alert('colmeia N')">
<area id="paredea14" shape="rect" onclick="alert('colmeia O')">
</map>
<script>
var coordsA = [];
coordsA[0] = "0,0,200,130";
coordsA[1] = "200,0,400,130";
coordsA[2] = "400,0,600,130";
coordsA[3] = "600,0,800,130";
coordsA[4] = "800,0,1000,130";
coordsA[5] = "0,160,200,240";
coordsA[6] = "200,160,400,240";
coordsA[7] = "400,160,600,240";
coordsA[8] = "600,160,800,240";
coordsA[9] = "800,160,1000,240";
coordsA[10] = "0,270,200,400";
coordsA[11] = "200,270,400,400";
coordsA[12] = "400,270,600,400";
coordsA[13] = "600,270,800,400";
coordsA[14] = "800,270,1000,400";
function setcoords(areaid, totalOfAreas) {
document.getElementById('paredea').style.width = "auto";
var width1 = document.getElementById('paredea').width;
document.getElementById('paredea').style.width = "100%";
var width2 = document.getElementById('paredea').width;
var ratio = width2 / width1;
for (var i = 0; i < totalOfAreas; i++) {
var temp = coordsA[i].split(",");
var newcoords = "";
for (var j = 0; j < temp.length; j++) {
temp[j] *= ratio;
newcoords += temp[j] + ",";
}
newcoords = newcoords.substr(0, newcoords.length - 1);
document.getElementById(areaid + i).coords = newcoords;
}
}
window.onload = function () {
setcoords("paredea", 15);
};
window.onresize = function () {
setcoords("paredea", 15);
};
</script>
私は先週同じ問題を抱えていたため、最終的にjQueryプラグインを作成しました。
プロジェクトgitHubは次のとおりです。
https://github.com/etienne-martin/mapify
基本的な使用法:
$("img[usemap]").mapify();
実例
これが機能するためには、data-original-coords
元の画像へのcoords
を持つ属性
$(function () {
function adjeustCoords() {
var image=$('img'); //change that to your image selector
var originalWidth=image[0].naturalWidth;
var currentWidth=image.width();
var ratio=currentWidth/originalWidth;
$("map area").each(function(){
//change that to your area selector
var coords=$(this).attr('data-original-coords').split(',');
coords = coords.map(function (x) {
return Math.round(x*ratio);
//i don't know if all browsers can accept floating point so i round the result
});
$(this).attr('coords',coords.join());
});
}
adjeustCoords();
$(window).resize(function(){
adjeustCoords();
});
});
これはchrome、firefoxおよびEdgeの最小バージョンで動作します
CSSスプライトを使用してこれを実現できます。画像の断片は1つの画像に収まるので、この方法ですべての画像を読み込むために1つのhttpリクエストを作成します。この手法はJavaScriptを必要とせず、単にbackground-position;
プロパティを使用して画像を移動します。
これは、ページ最適化の効率的な手法です。
私はこれを直交座標でのみテストしましたが、円形または多角形に一般化する必要があると思います
function wrap ( img, map ) {
var originalCoords = [ ],
test = new Image();
for ( var i = 0; i < map.areas.length; ++i ) {
var coords = map.areas[i].coords;
originalCoords.Push( coords.split( "," ).map( parseFloat ) );
}
function resize () {
var ratio = img.width / test.width;
for ( var i = 0; i < map.areas.length; ++i ) {
map.areas[i].coords = originalCoords[i].map( function ( n ) {
return ratio * n;
} ).join( "," );
}
}
test.addEventListener( "load", function () {
window.addEventListener( "resize", resize, false );
resize();
}, false );
test.src = img.src;
}
var imgs = document.querySelectorAll( "img[usemap]" );
for ( var i = 0; i < imgs.length; ++i ) {
var map = document.querySelector( "map[name=" + imgs[i].useMap.substring( 1 ) + "]" );
wrap( imgs[i], map );
}
IllustratorまたはSVGを生成できる別のプログラムにアクセスできる場合、SVGを使用して動的イメージマップを作成するのは簡単です。
これはプログラミングを必要としません。
ここにIllustratorの手順があります(数秒しかかかりません):
illustratorで画像を開き、新しい名前で保存します
ドキュメントを画像と同じサイズに変更します
マップパーツの塗りつぶされた四角形を描画します(不透明度を50%にするのに役立ちます)
「属性」パレットを使用して、各長方形へのリンクを追加します
すべての長方形の不透明度を0%に変更します
画像を選択し、[リンク]パレットメニューで[埋め込みなし]を選択します(名前は関係ありません。画像は使用しません)
ファイル› SVGとして保存(画像の場所:リンク、CSSプロパティ:スタイル要素、レスポンシブがオンになっています)
結果のsvgファイルを開きます
最初の2行を削除します(XMLおよびAdobeコメント)
画像ソースを更新する
svgコードをHTMLドキュメントに貼り付けます
これはすべての主要なブラウザで機能します。以下は、IllustratorのSVGエクスポート設定のスクリーンキャプチャです。
これが私の最も簡単な解決策です。 jqueryやプラグインは必要ありません。注意、このソリューションでは、マークアップのエラーや、サイズが比例しない画像は処理しません。
function mapResizer(maps) {
if (!maps) {maps = document.getElementsByTagName('map');}
for (const map of maps) {
map.img = document.querySelectorAll(`[usemap="#${map.name}"]`)[0];
map.areas = map.getElementsByTagName('area');
for (const area of map.areas) {
area.coordArr = area.coords.split(',');
}
}
function resizeMaps() {
for (const map of maps) {
const scale = map.img.offsetWidth / (map.img.naturalWidth || map.img.width);
for (const area of map.areas) {
area.coords = area.coordArr.map(coord => Math.round(coord * scale)).join(',');
}
}
}
window.addEventListener('resize', () => resizeMaps());
resizeMaps();
}
if (document.readyState == 'complete') {
mapResizer();
} else {
window.addEventListener('load', () => mapResizer());
}
イメージマップを管理するために作成したばかりの別のプラグインを次に示します。 https://github.com/gestixi/pictarea
とりわけ、領域は画像のサイズに応じて自動的にスケーリングされます。キャンバスを使用して領域をレンダリングしていることに注意してください。
基本的な使用法:
$(function() {
$('#map').pictarea({
rescaleOnResize: true
});
});