使用SVG路径和多边形创建HTML5交互式地图






4.88/5 (12投票s)
使用SVG路径和多边形创建HTML5交互式地图,KineticJS,jQuery
目录
引言
最近我重新审视了Silverlight - 使用热点创建图像地图这篇我几年前用Silverlight和Expression Blend 3.0写的文章。我决定用HTML5重做它。本简短教程演示了如何使用HTML5、KineticJS和jQuery实现交互式地图。
入门
图1显示了示例项目中的文件。images文件夹包含所有国旗图片,InteractiveMapData.js文件包含所有地图信息。InteractiveMapPath.htm和InteractiveMapPoint.htm分别包含使用SVG路径和点的交互式地图示例。KineticJS是一个HTML5 Canvas JavaScript库,它通过为桌面和移动应用程序启用高性能路径检测和像素检测来扩展2d上下文。
图 1
如何创建交互式图片?
您可以使用Expression Blend创建SVG路径,有关更多信息,请参阅Silverlight - 使用热点创建图像地图。在InteractiveMapPath.htm示例中,我重用了前一个教程中的路径绘制。如果仔细观察,填充和描边与另一个示例相比略有偏差。我非常肯定,如果我重新绘制路径,就不会发生这种情况。市面上有许多免费工具可以用来绘制路径数据,但我发现最富有成效的一个来自Aviary。这是一篇关于如何使用它来生成和利用路径数据的简短教程。
- 在“启动新的Phoenix链接创建”下点击“启动Phoenix图像”链接
- 将打开一个新窗口,点击“加载图像文件”链接
- 您可以浏览PC上的图片,或提供图片的绝对链接,然后点击上传按钮。
- 右键单击新创建的图层,然后选择“将图层推送到Raven”
图 2
- 这将打开另一个窗口,其中包含一个类似于图3的钢笔工具
图 3
- 选择钢笔工具(黄色高亮显示),然后开始在图片上绘制路径。
- 完成图片上的路径绘制后,点击“文件” -> “导出” -> “导出到SVG” -> “确定”,然后保存文件
- 您可以使用记事本或其他HTML编辑器打开.svg文件来查看和复制路径数据
创建交互式地图/图片的另一个选项是使用SVG多边形。我最喜欢的是在线图像地图编辑器,因为这个编辑器有一个缩放选项,在绘制小区域的多边形时非常有用。
如何为图片路径添加事件?
我们将使用KineticJS JavaScript库为图像上的形状挂载事件监听器。您可以在HTML5 Canvas教程中找到许多关于如何利用该库的优秀示例。我将简要介绍实现过程。附件示例中的两种实现方式大致相同。主要区别在于一种使用了Kinetic.Polygon()构造函数,另一种使用了Kinetic.Path()构造函数。
列表 1
var path = new Kinetic.Path({ data: c, fill: '#fff', stroke: '#555', strokeWidth: .5 }); var shape = new Kinetic.Polygon({ points: points, fill: '#fff', stroke: '#555', strokeWidth: .5 });
body标签内的div元素用于容纳图像地图和菜单。最初我计划使用HTML5上下文菜单,但后来放弃了,因为许多浏览器不支持menu元素。最终我使用jQuery在鼠标点击时创建菜单。
列表 2
<div id="container"></div> <div id="contextMenu" style="display:none"> <div id="contextMenuH"></div> <div id="contextMenuB"></div> </div>
图3显示了与每个形状相关的鼠标事件。JavaScript非常直接。下面是对事件的简要说明。当鼠标悬停在形状上时,颜色将从白色变为绿色。您可以将其更改为您喜欢的颜色。鼠标离开形状时,将颜色设置回白色并隐藏工具提示。当鼠标沿形状移动时,会显示带有国家名称的工具提示。还有一个逻辑是在鼠标从一个形状移动到另一个形状时隐藏菜单。最后但同样重要的是,鼠标单击事件。我们使用jQuery来定位和生成菜单。菜单包含国家名称、国旗图片以及与所选国家相关的几个链接。
列表 3
//mouseover the country shape.on("mouseover", function () { this.setFill('#008000'); this.setOpacity(0.5); shapesLayer.drawScene(); }); //mouseout the country shape.on("mouseout", function () { this.setFill('#fff'); shapesLayer.drawScene(); tooltipBackground.hide(); tooltip.hide(); tooltipLayer.drawScene(); }); //mousemove around the country path shape.on("mousemove", function () { var mousePos = stage.getMousePosition(); var x = mousePos.x + 5; var y = mousePos.y + 10; drawTooltip(tooltip, x, y, k); //keep track of previous key if (previousK !== k) { previousK = k; previousSelected = this; //hide the menu if different country path is selected $("[id$='contextMenu']").css({ display: 'none' }); } }); //onclick the country path shape.on("mousedown", function (e) { $("[id$='contextMenu']").css({ display: 'inline', position: 'absolute', top: e.pageY, left: e.pageX + 5, opacity: .8 }); //menu header $("[id$='contextMenuH']").html(''); //flag $('<img />').attr('src', area.flag).appendTo($("[id$='contextMenuH']")); $('<span />').html(k).appendTo($("[id$='contextMenuH']")); //build links $("[id$='contextMenuB']").html(''); //clear //countryReports $('<a target="_blank"></a>') .attr('href', 'http://www.countryreports.org/country/' + k + '.htm') .html('Country Reports').appendTo($("[id$='contextMenuB']")); //Economy $('<br/><a target="_blank"></a>') .attr('href', 'http://www.economicexpert.com/a/' + k + '.htm').html('Economy') .appendTo($("[id$='contextMenuB']")); //The world Factbook $('<br/><a target="_blank"></a>') .attr('href', 'https://www.cia.gov/library/publications/the-world-factbook/geos/' + area.abbreviation + '.html') .html('Factbook').appendTo($("[id$='contextMenuB']")); //Global Statistics $('<br/><a target="_blank"></a>') .attr('href', 'http://www.geohive.com/cntry/' + k + '.aspx') .html('Global Statistics').appendTo($("[id$='contextMenuB']")); //Wiki $('<br/><a target="_blank"></a>') .attr('href', 'http://en.wikipedia.org/wiki/' + k).html('Wiki') .appendTo($("[id$='contextMenuB']")); });
看点
多边形还是路径?我认为它们表现相同,差别不大,这取决于我们拥有的工具。
将kinetic-v3.9.7替换为kinetic-v4.3.3
最近,我发现示例代码HTML5 - 使用SVG路径/数据创建交互式地图在Firefox 19.0中不再正常工作。mouseover事件完全失灵。起初我以为简单更新KineticJS库就能解决问题,但事实并非如此。原因是某些属性/方法在kinetic-v4.3.3中已被移除或替换。例如,Layer.draw()现在是Layer.drawScene(),setAlpha()被setOpacity()取代,颜色名称不再有效,我们应该使用HTML颜色代码,等等。在kinetic-v3.9.7中,我们可以通过Kinetic.Text构造函数设置文本背景颜色。但在最新的KineticJS库中,我们必须将Rectangle和Text对象组合起来才能创建带背景色的文本。我已经更新了源代码以使用最新的库,欢迎大家下载。
结论
我希望这些信息对您有所帮助,并使您的编程工作更加轻松。如果您发现任何错误、不同意内容或想帮助改进本文,请给我留言,我会与您一起进行修正。我建议下载演示并进行探索,以掌握全部概念,因为我可能在本文中遗漏了一些重要信息。如果您想帮助改进本文,请给我发电子邮件。
测试于:Internet Explorer 9.0,Firefox 19.0,Google Chrome 25.0,Apple Safari 5.1.7

历史
2012年6月14日:初始版本。
2013年2月24日:v02.00.00
资源
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-path-tutorial/
http://www.mobilefish.com/services/image_map/image_map.php
http://www.mobilefish.com/services/image2svg/image2svg.php
http://www.image-maps.com/
http://code.google.com/p/imgmap/
https://w3schools.org.cn/svg/svg_path.asp
http://svg-edit.googlecode.com/svn/branches/2.5.1/editor/svg-editor.html
http://advanced.aviary.com/tools/image-editor
http://www.maschek.hu/imagemap/imgmap
http://www.famfamfam.com/lab/icons/flags
观看此脚本的实际演示
使用SVG路径创建HTML5交互式地图
使用多边形创建HTML5交互式地图