基本上,我必须在HTML / CSS / Javascript中创建它:
如你所见,它是纽约的地图。当用户点击地图下方的其中一个图标时,地图左下方的图钉应显示在某些位置。然后,用户应该可以单击它们,以便从其中弹出另一个带有一些文本的div。这是我不知所措的地方。这就是我到目前为止的想法:
- 创建另外3个图像,其中包含所有动力装置销,所有造船厂销和所有钢厂销钉,并使用z-index将它们定位在地图顶部。唯一的问题是,用户只能点击具有最高z-index的图像。例如,如果他们同时启用造船厂和钢厂,他们只能点击最后添加的销钉。这是我放弃这个想法的地方。
- 使用具有绝对位置的div来复制地图的细分。但是,div是矩形的,而细分则不是。所以这也不好。
- 使用图像映射。自1990年代以来,我没有听说有人使用这些。无论如何,我不知道地图会如何帮助我。我需要定位它们,而不是超链接它们。
我愿意接受任何建议/插件。
答案 0 :(得分:4)
嗯,你可能不喜欢这个答案,但是因为没有其他人提出任何建议,这就是我的做法(或者实际上可能使用多层图像地图,但是你的引脚需要在图像上):
选项1:将整个地图和图钉作为SVG并将svg代码粘贴到您的html中,并将javascript点击事件附加到它。 SVG元素可以使用与html元素相同的DOM事件,可以定位,缩放和整形。您甚至可以使用CSS规则和类隐藏它们!
SVG是一个非常优雅的解决方案,拥有可靠的浏览器支持,如果能够以这种形式获得您的艺术资产,那么我可能就是这样做的。您可以在线获取svg的各种工具和教程,因此我将其留在此处,只需记住javascript事件就可以了!
选项2:使用HTML自己动手。让我更多地说明这一点,因为它在网络上并不是标准,尽管它与桌面应用程序中使用的理念相同。
创建四个图像:地图和图钉。
创建一个数据数组,该数组是该引脚的位图,显示透明且可单击的部分。这是一个带有1的矩形,您可以在其中单击0,在此处可以形成形状。这种技术在桌面程序中用于鼠标光标和类似的东西。最简单的方法是使用图像编辑器将其清除为白色和黑色,然后导出。 GIMP可以导出到xpm,您可以手动修复,以便轻松地制作成Javascript。
创建每个引脚位置的数据数组。 (理想情况下,我将此作为绝对定位的HTML链接元素的列表,因为这是一种优雅地降级的数据格式 - 如果不完美 - 没有Javascript,但您不想在它们上侦听事件。)< / p>
在包含所有图像的div 上放置一个事件侦听器,并使用单击的坐标查找数据数组中的引脚。如果需要,使用位图下降 - 循环遍历可能的对象并查看您是否在边界矩形中。如果是这样,请检查位图。如果它是可点击的,你有一个打击!如果没有,请转到下一个。
线性搜索最容易实现并且运行良好,但如果您有数千个项目可能需要稍微优化一下,您可以在网上搜索其他算法/数据结构,如四叉树(如果需要)。但是如果你有那么多物体,那么地图可能无法用户使用!
所以基本上,点击将全部解决数据阵列的坐标而不是关闭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中打开它。使用颜色选择工具通过单击选择所有透明部分。使用桶填充,选择&#34;填写整个选择&#34;使它全黑。点击选择 - &gt;反转选择图像的其余部分并将其全部填充为白色。
现在将文件导出为XPM。在你的文本编辑器中打开它,然后将第7行(好的,第一个带有图像数据的长文件,无论它在你的图像数据中)发送到最后并将其粘贴到Javascript中。
我在其周围放置数组括号以生成pinBitmap
变量,并且由于Gimp生成了字符串,我只是在函数中使用了字符串。
文件底部的CSS生成我们的地图和图钉图像。 showing
类管理更多信息的显示。您当然也可以执行.ny-map .powerplant { display: none; }
等操作来切换事物的显示。搜索要点击的项目时,请确保使用computedStyle
或仅使用某些标记变量显示这些项目,如果不是,则继续显示!
您会注意到这些引脚本身在HTML中是半语义的,只是使用内联样式来定位它们。在CSS中,我做了一些负边缘技巧,让它在我想要坐标的位置显示更多的针脚点,但是你可以调整这个 - 但是JS解释了所有这些css的调整,信不信由你!只需从gimp或其他任何地方获取相对于图像的坐标。
我在HTML中放置了有关引脚的详细信息,因此它也与内容很好地分组。
最后,魔术函数位于文件的顶部。它只是地图上一个普通的事件监听器,它通过引脚循环。 getBoundingClientRect
函数是标准DOM的一部分,并生成项目所在的矩形。一个简单的4部分检查看看我们是否在那个盒子里。
如果是这样,我们想要通过简单的减法实现相对于矩形的坐标,然后检查位图是否实际上是可点击的......那就是它!如果没有,我们认为它是一个错过并继续循环。如果是这样,我切换showing
课程来完成剩下的工作。
此代码应该可以在IE9 +浏览器上可靠地运行,而无需任何插件或库脚本。
如果您对我的方法/代码有任何疑问,请与我们联系。
编辑:大声笑我打电话给#34;造船厂&#34;但切断了发电厂的形象。哦,你知道我的意思。