あなたはこの回答を愛していないかもしれませんが、他に誰も何も示唆していないので、ここで私はそれをやっていますか(実際には複数のレイヤーを持つ画像マップを使用していますが、 ):
オプション1:SVGとしてマップとピン全体を行い、svgコードをhtmlに貼り付けて、javascriptクリックイベントを貼り付けます。 SVG要素はhtml要素と同じDOMイベントを使用でき、配置、拡大縮小、および整形できます。あなたはCSSルールとクラスでそれらを隠すことさえできます!
SVGは実に洗練されたブラウザで、非常に洗練されたソリューションであり、あなたのアート資産をその形にすることができれば、それはおそらく私がやる方法でしょう。あなたはsvgのための様々なツールとチュートリアルをオンラインで手に入れることができるので、これを残しておきます。ちょうどjavascriptのイベントがそれを処理することを覚えておいてください!
オプション2:HTMLで自分でやってください。それはデスクトップアプリケーションで使用されているのと同じアイデアですが、ウェブではあまり標準ではないので、もう少し詳しく説明してください。
リニア検索を使用すると、四分木のような他のアルゴリズム/データ構造のためにウェブを検索することができ、実装するのが最も簡単です、あなたは何千ものアイテムを持っている場合は、この小さなを最適化する必要があるかもしれませんが、かなりうまく動作します。しかし、多くのオブジェクトを持っているなら、おそらくマップはおそらくユーザーにとっては使えないでしょう!
基本的に、クリックはすべてオフになるのではなく、データ配列を調整します。画像はユーザー専用です。
私はあなたのイメージを使用してテクニックのデモを打ちました。ピンをカット+ペーストして怠惰にハッキングしました。元の画像があれば、はるかに良い仕事をすることができます。
ライブリンク(一時的でもよい)後世のためのコードの http://arsdnet.net/demo.html
コピー/貼り付け:
<!DOCTYPE html>
<html>
<head>
<title>Demo of map idea</title>
<script>
window.onload = function() {
var map = document.querySelector(".ny-map");
// on each click on the map, we need to loop through
// the bounding boxes of the pins and see which one we hit.
map.addEventListener("click", function(event) {
var pins = map.querySelectorAll(".pin");
var i;
// we are searching BACKWARD so it checks
// for clicks on the topmost pin first, then
// proceeds down to the bottom ones.
for(i = pins.length - 1; i >= 0; i--) {
var rect = pins[i].getBoundingClientRect();
if (event.clientX >= rect.left
&& event.clientX < rect.right
&& event.clientY >= rect.top
&& event.clientY < rect.bottom)
{
// if we're inside the bounding box,
// next we need to check the transparency
// bitmap to see if it is an actual hit
var x = event.clientX - rect.left;
var y = event.clientY - rect.top;
// pinBitmap is defined below
// "." happens to be the char my Gimp export
// gave to the clickable region, so we check for it
if(pinBitmap[y].charAt(x) == ".") {
// we hit this one!
// toggle class "showing"
if(pins[i].className.indexOf(" showing") == -1)
pins[i].className += " showing";
else
pins[i].className = pins[i].className.replace(" showing", "");
break; // all done
}
// if we didn't hit on the bitmap, continue
// searching the one below by proceeding with the loop
}
}
});
};
</script>
</head>
<body>
<div class="ny-map">
<div class="shipyard pin" style="left: 140px; top: 450px;">
<p>This is information about shipyard #1.</p>
</div>
<div class="shipyard pin" style="left: 150px; top: 450px;">
<p>This is information about shipyard #2, which overlaps shipyard #1.</p>
</div>
<div class="shipyard pin" style="left: 460px; top: 350px;">
<p>This is information about a shipyard pin in the Syracuse area.</p>
</div>
</div>
<script>
var pinBitmap = [
"+++++++++++.++.............++++++++++++++",
"+++++++++++..................++++++++++++",
"++++++++++.....................++++++++++",
"+++++++..........................++++++++",
"+++++................................++++",
"++.......................................",
"....+...............................+++++",
".+++.................................++++",
"+++...................................+++",
"+++...................................+++",
"++.....................................++",
"++.....................................++",
"+.......................................+",
"+.......................................+",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
".........................................",
"+.......................................+",
"+.......................................+",
"+.......................................+",
"++.....................................++",
"++.....................................++",
"+++...................................+++",
"+++...................................+++",
"+++...................................+++",
"++++.................................++++",
"++++.................................++++",
"+++++...............................+++++",
"+++++...............................+++++",
"++++++.............................++++++",
"++++++.............................++++++",
"+++++++...........................+++++++",
"+++++++...........................+++++++",
"++++++++.........................++++++++",
"+++++++++.......................+++++++++",
"+++++++++.......................+++++++++",
"++++++++++.....................++++++++++",
"++++++++++.....................++++++++++",
"+++++++++++....................++++++++++",
"+++++++++++....................++++++++++",
"++++++++++++...................++++++++++",
"+++++++++++++...............+..++++++++++",
"+++++++++++++...............+..++++++++++",
"++++++++++++++.............++..++++++++++",
"+++++++++++++++...........+++..++++++++++",
"+++++++++++++++...........+++..++++++++++",
"++++++++++++++++.........++++..++++++++++",
"++++++++++++++++.........++++..++++++++++",
"+++++++++++++++++.......+++++..++++++++++",
"++++++++++.................++..++++++++++",
"++++++.........................++++++++++",
"++++..............................+++++++",
"+++................................++++++",
"+++................................++++++",
"++++..............................+++++++",
"++++++..........................+++++++++",
"++++++++++..................+..++++++++++"];
</script>
<style>
.ny-map {
width: 985px;
height: 815px;
background-image: url('demo/qDOGS-fs8.png');
position: relative;
}
.pin {
width: 41px;
height: 66px;
margin-left: -20px;
margin-top: -66px;
position: absolute;
}
.shipyard.pin {
background-image: url('demo/pin.png');
background-repeat: no-repeat;
}
.pin:not(.showing) > * {
display: none;
}
.pin.showing {
background-color: rgba(255, 255, 255, 0.8);
padding-left: 48px;
padding-right: 4px;
width: auto;
}
</style>
</body>
</html>
ここで私はそれをやった方法です。まず、pinBitmap
部分が奇妙な形状を処理する部分:
ピン画像を取り出し、GIMPで開きます。色選択ツールを使用して、すべての透明部分をクリックして選択します。バケツの塗りつぶしを使用し、「全体選択を塗りつぶす」を選択してすべて黒にします。 「選択」 - >「反転」を押して画像の残りの部分を選択し、バケットを白く塗りつぶします。
ファイルをXPMとしてエクスポートします。これをテキストエディタで開き、7行目(画像データを持つ最初の長いもの、それがあなたのものであればどんなものでも)を最後までコピーして、それをJavascriptに貼り付けます。
pinBitmap
を変数にするために配列の角括弧を置き、Gimpで生成された文字列のため、関数内に文字列を使用しました。
ファイルの下部にあるCSSは、マップとピン画像を作成します。 showing
クラスが詳細情報の表示を管理します。あなたはもちろん、物の表示を切り替えるために.ny-map .powerplant { display: none; }
などのようなことをすることもできます。クリックするアイテムを検索するときは、それらがcomputedStyle
のいずれかで表示されているか、いくつかのフラグ変数とともに表示されているかどうかを確認し、そうでない場合は続行してください。
あなたはそれらを配置するだけで、インラインスタイルで、ピン自体はHTMLで半セマンティックていることがわかります。 CSSでは、私は座標を欲しかったところでピンポイントをもっと見せるためにいくつかのマイナスマージントリックを行いましたが、これを調整することは可能です - JSはこのCSSの調整をすべて行い、それを信じていますか?ちょうどgimpか何かからイメージに相対的な座標を取得してください。
ピンの詳細をHTMLに書いてありますので、内容もうまくグループ化されています。
そして最後に、ファイルの先頭にマジック機能、。これは、ピンをループする通常のイベントリスナーです。 getBoundingClientRect
関数は標準DOMの一部であり、アイテムが内部にある矩形を生成します。シンプルな4つの部分からなるチェックは、私たちがその箱にいるかどうかを調べます。
もしそうなら、私たちは単純な減算によって得られた矩形に相対的な座標を求め、それが実際にクリック可能ならチェックします。それだけです!そうでない場合、我々はそれを欠場と見なし、ループを継続する。もしそうなら、私はshowing
クラスをトグルして残りの作業を行います。
このコードは、プラグインやライブラリスクリプトを必要とせずにIE9 +ブラウザで確実に動作するはずです。
私のアプローチ/コードに関するご質問がありましたら教えてください。
EDIT:笑私はそれを「造船所」と呼びましたが、発電所の画像は切り取っていました。ああ、あなたは私が何を意味しているか知っています。
答えが有用な場合は、受け入れるかコメントするのを忘れないでください! –