基本上,我必须在HTML/CSS/Javascript中创建这样的代码:

如你所见,这是一张纽约地图。当用户单击地图下方的一个图标时,图钉(如地图左下角的图钉)应该出现在地图的某些位置。然后,用户应该能够点击它们,以便从它们中弹出另一个带有文本的div。这就是我不知所措的地方。到目前为止,我是这样想的:
-Creating另外3张图片,包含所有动力装置销,所有造船厂别针和所有钢厂别针,并在地图上用z索引定位它们。唯一的问题是,用户只能单击具有最高z索引的图像。例如,如果它们同时启用了造船厂和钢厂,它们将只能点击上一次添加的别针。这就是我放弃这个想法的地方。
-Using div具有绝对位置来复制地图的细分区域。然而,div是矩形的,细分不是。所以这也不好。
-Using图像地图我从20世纪90年代起就没听说过有人用过这些东西。不管怎样,我看不出一张地图对我有什么帮助。我需要定位他们,而不是超链接他们。
我愿意接受任何建议/插件。
发布于 2016-07-03 02:49:12
好吧,您可能不喜欢这个答案,但由于没有其他人提出任何建议,我会这样做(或者实际上使用多层的图像映射,但是您的引脚需要放在图像上):
选项1:将整个映射和引脚作为SVG并将svg代码粘贴到您的html中,并将javascript单击事件附加到它。SVG元素可以使用与html元素相同的DOM事件,可以定位、缩放和成形。你甚至可以用CSS规则和类来隐藏它们!
SVG确实是一个非常优雅的解决方案,有坚实的浏览器支持,如果有可能以这种形式获得您的艺术资产,我可能就是这样做的。您可以在网上为svg获取各种工具和教程,所以我将把它放在这里,只需记住javascript事件就行了!
选项2:用HTML自己做。让我更详细地说明一下这一点,因为它在网络上并不完全是标准的,尽管它是桌面应用程序中使用的相同的想法。
线性搜索是最容易实现的,并且工作得很好,尽管如果您有数千项,您可能需要对其进行一些优化,如果需要的话,您可以在web上搜索其他算法/数据结构,如四叉树。但是,如果您有那么多对象,地图可能对用户是不可用的!
因此,基本上,点击将所有的工作坐标数据数组,而不是关闭HTML元素,这些图像只是为用户。
我用你的图像拼凑了一个技术演示,只是懒洋洋地用cut+paste把它从引脚上砍了出来。如果你有原始图像,你可以做一个更好的工作。
活动链接(可能是临时的) 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+浏览器上可靠工作,而不需要任何插件或库脚本。
如果你对我的方法/代码还有什么疑问,请告诉我。
编辑: lol我把它叫做“造船厂”,但是去掉了发电厂的形象。哦,你知道我的意思。
https://stackoverflow.com/questions/38164155
复制相似问题