加入右键菜单,首先我们要监听鼠标右键点击的操作,我们知道鼠标右键事件名是 contextmenu。当鼠标在 html 元素之上,点击鼠标右键,便会触发 contextmenu 事件,在 contextmenu 事件的回调函数中实现对应的显示菜单功能就可以。

那么在 openlayers 中。在地图中加入这个事件,我们从哪里下手呢?首先我们得了解 openlayers 的初始化页面的过程。

openlayers 初始化页面过程

openlayers 也是一个前端库,那么它肯定离不开 html 的运用,比方,我们首先须要在页面放置一个显示地图的 html 元素,一个 div 元素(如果其 id 属性设置为 “map”。后面简称为 map div),然后在地图初始化的时候指定这个元素,openlayers 会首先在这个元素中创建一个 class 为 ol-viewport 的 div 元素,其尺寸保持与 map div 同样,然后在 ol-viewport div 中创建一个 canvas 元素。在这个 canvas 元素中渲染请求到的地图。其次。还会加入一个 class 为 ol-overlaycontainer 的 div 元素,用来放置 overlay。最后,加入一个 class 为 ol-overlaycontainer-stopevent 的 div 元素,主要是放置 openlayers 的控件,上一篇加入 自己定义扩展控件 的文章开篇有讲过。这里不是重点。我们不详细介绍了。

最后形成的 html dom 结构例如以下图:



图1 形成的DOM结构

我们会想到在这个 map div 元素加入事件。然后右键弹出菜单。这个想法非常自然,也确实能够实现,然而我们要想到后面的事情。至少对事情有一个全局的认识再下手,我们显示出菜单后。往往是要依据对应的地图所在位置进行一定的操作,那么我们的 contextmenu 的事件对象包括发生点击的屏幕坐标,可是怎样依据屏幕坐标获得地图中的对应坐标系下的坐标将会比較困难。

困难在哪里呢?主要有以下的三点:

  • 首先,事件对象所含的坐标是相对于整个浏览器的视口、页面或者整个屏幕的。
  • 其次。而显示地图的元素往往又是任意的大小和位置。
  • 最后,屏幕的坐标系和地图的坐标系又往往全然不同,怎样将相对与地图元素的坐标再转化为地图坐标系下的坐标?

首先。我们须要获得事件坐标相对于 map div (包括地图的元素)的坐标,然后将相对于 map div 的坐标转化为地图中的实际坐标。

第一步中,我们能够通过计算获得,可是第二步必须通过 openlayers 来完毕,由于仅仅有 openlayers 对地图的坐标系最清楚。这在 openlayers 中也有相关的功能。庆幸的是。openlayers 中我们能够一步完毕上述操作。仅仅须要一个函数:map.getEventCoordinate(event),在以下的详细实现中,我会详细说到这个函数。

以下我们看看详细怎样实现吧。

鼠标右键菜单详细实现


  • 为了方便,文章中的代码使用了 JQuery。
  • 文章中的实例完整代码能够到我的 GitHub 中查看或者下载。实用的话别忘了点一下 star。


以下我们一步一步地加入右键菜单功能,我们分为三步:

  1. 对 html 元素加入 contextmenu 事件;
  2. 获取地图对应的点击坐标;
  3. 地图对应位置加入菜单 。

对 html 元素加入 contextmenu 事件

html 元素的鼠标右键事件名为 contextmenu,这个事件全部主流浏览器都支持,这里不要混淆 html 新增的属性 contextmenu,这个属性眼下仅仅有 firefox 支持。我们仅仅是使用 oncontextmenu 这个事件。

对包括地图的不论什么 html 元素绑定这个事件都能够,openlayers 会处理坐标转换这些问题。例如以下,map.getViewport() 会返回 openlayers 初始化页面时创建的 class 为 ol-viewport 的 div 元素。也就是直接包括地图的元素。由于浏览器都有默认的右键菜单。所以我们要取消默认的菜单,仅仅要调用 e.preventDefault(); 就可以:

$(map.getViewport()).on("contextmenu", function(event){
e.preventDefault();
// 书写事件触发后的函数
});

获取地图对应的点击坐标

获取地图对应的点击坐标仅仅须要一句就可以。例如以下。

var coordinate = map.getEventCoordinate(event);

函数參数是 oncontextmenu 对应的事件对象。该函数包括对 map.getCoordinateFromPixel() 的调用。map.getCoordinateFromPixel() 參数为 ol.pixel,是一个坐标。数组格式[x, y],事实上现中又调用了 ol.vec.Mat4.multVec2(),该函数完毕处理坐标转换的实际工作。

地图对应位置加入菜单

这里我们结合 overlay 加入菜单,之前的文章介绍过 overlay。这里就不再详细展开了。

首先,我们在 html 页面加入一个文件夹,详细的 css 样式能够自己设定,想看完整源代码的能够到我的 GitHub 中查看或者下载完整的代码:

<div id="contextmenu_container" class="contextmenu">
<ul>
<li><a href="#">设置中心</a></li>
<li><a href="#">加入地标</a></li>
<li><a href="#">距离丈量</a></li>
</ul>
</div>

使用这个 html 元素初始化一个 overlay,并将 overlay 加入到地图中:

var menu_overlay = new ol.Overlay({
element: document.getElementById("contextmenu_container"),
positioning: 'center-center'
});
menu_overlay.setMap(map);

接下来,我们就能够在鼠标右键菜单的事件回调函数中,依据获取的地图坐标位置,设置 overlay 的显示位置:

menu_overlay.setPosition(coordinate);

菜单隐藏

当我们鼠标点击右键,菜单出现,可是我们不能让菜单总是显示在地图中,这时我们能够加入鼠标左键单击,菜单消失功能。或者当选择某项功能时。菜单消失。这个比較easy实现,仅仅要一句便能够实现,放在鼠标左键事件的回调函数或者菜单功能运行函数中就可以。例如以下:

menu_overlay.setPosition(undefined);

总结

这篇文章中,主要讲了 openlayers 初始化页面地图元素的过程,并介绍了在地图上实现“鼠标右键菜单功能”。和隐藏菜单的实现。我们并没有对菜单中的条目绑定事件,由于我们的重点在于实现右键菜单,对于菜单的条目要绑定什么功能,和普通的 javascript 事件绑定并无二致,所以没有展开。

好的,就写到这里,有什么问题,能够在文章以下留言或者给我发邮件。


文章中的实例完整代码能够到我的 GitHub 中查看或者下载,实用的话别忘了点一下 star。


OpenLayers 3 之 加入地图鼠标右键菜单的更多相关文章

  1. jQuery自定义Web页面鼠标右键菜单

    jQuery自定义Web页面鼠标右键菜单 右键菜单是固定的,很多时候,我们需要自定义web页面自定义菜单,指定相应的功能. 自定义的原理是:jQuery封装了鼠标右键的点击事件(“contextmen ...

  2. Qt creator 创建鼠标右键菜单 (不新建类)

    界面 步骤 打开你的界面文件并选中你要添加右键的控件,选择“CustomContextMenu” 右键选择“转到槽...” -> customContextMenuRequested 插入下面代 ...

  3. 如何在C#添加鼠标右键菜单

    C#添加鼠标右键方法步骤: 1 选中要添加右键功能的Form或者控件,打开控件的设计页面. 2 从工具箱中找到ContextMenuStrip控件,将这个控件拖曳到Form或者控件的设计页面上.这时系 ...

  4. 将EmEditor加入到鼠标右键菜单

    在清理系统的时候,无意中将EmEditor的鼠标右键功能给清理掉了,在EmEditor的配置中又没有找到如何加入到鼠标右键菜单的方法,只好使用导入注册表功能了,以下的代码,拷贝到记事本中,保存为EmE ...

  5. JAVA GUI学习 - JPopupMenu鼠标右键菜单组件学习

    public class JPopmenuKnow { public void test() { //为表格添加鼠标右键菜单 JMenuItem jMenuItemFileInfo = new JMe ...

  6. WinForm -- 为TextBox文本框添加鼠标右键菜单

    WinForm -- 为TextBox文本框添加鼠标右键菜单 1. 新建一个WinForm项目,放置一个TextBox控件 2. 从工具箱拖进来一个ContextMenuStrip 3. 将TextB ...

  7. Qt532.【转】Qt创建鼠标右键菜单

    ZC:可以通过 设置  (QWebView*)->setContextMenuPolicy(NoContextMenu); 来关闭 QWebView的默认右键菜单 Qt创建鼠标右键菜单_疯华正茂 ...

  8. Jquery如何禁止鼠标右键菜单

    jquery中使用contextmenu事件,如果返回true,则允许右键菜单:如果返回false,则禁止右键菜单 导入文件 <script type="text/javascript ...

  9. 将Sublime Text 添加到鼠标右键菜单的教程方法

    安装notepad++软件,在菜单右键自动会添加“edit with notepad++"的选项,那么怎么将Sublime Text 添加到鼠标右键菜单呢?下面是我的操作过程,希望有帮助! ...

随机推荐

  1. Guava源码学习(二)Ordering

    基于版本:Guava 22.0 Wiki:Ordering 0. Ordering简介 Guava的Ordering提供了链式风格的比较器的实现,我们可以用Ordering轻松构建复杂的比较器. 1. ...

  2. Codeforces 839 B. Game of the Rows-贪心

    最近太zz了,老是忘记带脑子... 补的以前的cf,发现脑子不好使...   B. Game of the Rows   time limit per test 1 second memory lim ...

  3. 洛谷 P1049 装箱问题【正难则反/01背包】

    题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱内,使箱子的剩余 ...

  4. Codeforces 908D New Year and Arbitrary Arrangement(概率DP,边界条件处理)

    题目链接  Goodbye 2017 Problem D 题意  一个字符串开始,每次有$\frac{pa}{pa+pb}$的概率在后面加一个a,$\frac{pb}{pa+pb}$的概率在后面加一个 ...

  5. 【bzoj1087】【互不侵犯King】状压dp裸题(浅尝ACM-D)

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=54329606 向大(hei)佬(e)势力学(di ...

  6. (转)Unity3d使用心得(1):ModelImporter的使用、在代码中添加动画片段。

    在使用 Unity3d 倒入Fbx模型的时候,动画的动画片段需要自己手动添加模型多了以后会是一个不小的工作量. Unity3d支持 编辑器脚本来控制资源导入的过程.添加一个 AssetPostproc ...

  7. cf 546C Soldier and Cards

    题目链接:C. Soldier and Cards Two bored soldiers are playing card war. Their card deck consists of exact ...

  8. Hadoop 2.2.0 Job源代码阅读笔记

    本文所有涉及的内容均为2.2.0版本中呈现. 概述: Job在创建Job并且提交的人的眼中,可以在创建的时候通过配置Job的内容,控制Job的执行,以及查询Job的运行状态.一旦Job提交以后,将不能 ...

  9. ASIHTTPRequest框架使用总结系列之阿堂教程5(上传数据)

    在上篇文章中,阿堂和网友们分享了如何用ASIHTTPRequest框架下载数据的实例,本篇阿堂将数据介绍如何用ASIHTTPRequest框架上传数据的应用实例.       数据上传是通过ASIHT ...

  10. DOM系统学习-基础

    DOM介绍  DOM介绍: D 网页文档 O 对象,可以调用属性和方法 M 网页文档的树型结构  节点: DOM将树型结构理解为由节点组成.     节点种类: 元素节点.文本节点.属性节点等 查找元 ...