meface/docs/article/gis/openlayers/44customcontrol.md

387 lines
10 KiB
Markdown
Raw Normal View History

2023-11-17 10:54:23 +08:00
---
title: 自定义导航
date: 2020-10-29
author: ac
tags:
- OpenLayers
categories:
- GIS
---
## 自定义导航
来实现一个很久以前比较流行的自定义导航控件。
这需要了解`CSS`的定位`position`和`background`属性的知识,来学习构建这个组件,后续的事件交互就是通过`View`对象控制地图视图的操作。
<img src="./images/image-20201110173336191.png" alt="image-20201110173336191" />
材料:
[map_view.png](./images/map_view.png)
[toolbar_rbg.png](./images/toolbar_rbg.png)
完整代码:
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/ol.css" type="text/css">
<style>
.map {
position: relative;
height: 400px;
width: 100%;
}
/*自定义导航start*/
.map-toolbar {
position: absolute;
left: 20px;
top: 20px;
visibility: visible;
width: 52px;
overflow: visible;
z-index: 150;
}
.map-pancontrol {
position: relative;
display: block;
width: 52px;
height: 52px;
background: url("./img/map_view.png") 0 175px;
}
.map-pan-left, .map-pan-top, .map-pan-right, .map-pan-bottom {
position: absolute;
cursor: pointer
}
.map-pan-left, .map-pan-right {
width: 12px;
height: 18px;
top: 17px
}
.map-pan-top, .map-pan-bottom {
width: 18px;
height: 12px;
left: 17px
}
.map-pan-left {
left: 8px
}
.map-pan-right {
left: 32px
}
.map-pan-top {
top: 8px
}
.map-pan-bottom {
top: 31px
}
.map-pan-left:hover,
.map-pan-top:hover,
.map-pan-right:hover,
.map-pan-bottom:hover {
background: url(./img/map_view.png);
}
.map-pan-left:hover {
background-position: -52px -110px
}
.map-pan-top:hover {
background-position: -70px -112px
}
.map-pan-right:hover {
background-position: -61px -110px
}
.map-pan-bottom:hover {
background-position: -84px -110px
}
.map-zoomcontrol {
position: relative;
left: 14px;
width: 24px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none
}
.map-zoom-plus,
.map-zoom-minus,
.map-zoom-cursor {
background: url(./img/map_view.png);
cursor: pointer
}
.map-zoom-ruler,
.map-zoom-mask {
background: url(./img/toolbar_rbg.png);
cursor: pointer
}
.map-zoom-ruler {
overflow: visible
}
.map-zoom-plus,
.map-zoom-minus {
width: 24px;
height: 21px
}
.map-zoom-plus {
background-position: 0 -217px
}
.map-zoom-plus:hover {
background-position: 0 -194px
}
.map-zoom-minus {
background-position: -26px -224px
}
.map-zoom-minus:hover {
background-position: -26px -195px
}
.map-zoom-ruler {
display: block;
width: 12px;
height: 147px;
position: relative;
left: 6px;
background-position: 0 0
}
.map-zoom-mask,
.map-zoom-cursor {
position: absolute
}
.map-zoom-mask {
height: 45px;
width: 12px;
background-position: -14px 0
}
.map-zoom-cursor {
top: 45px;
width: 24px;
height: 20px;
left: -6px;
background-position: -127px -164px
}
.map-zoom-cursor:hover {
background-position: -127px -141px
}
.map-locate {
position: relative;
left: 17px;
display: block;
width: 18px;
height: 18px;
background: url(./img/map_view.png) -130px -185px;
cursor: pointer
}
.map-touch-toolbar .map-zoomcontrol {
position: absolute;
right: 4px;
bottom: -80px;
z-index: 500;
width: 35px;
background-color: white;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 3px;
border: 1px solid #ccc;
box-shadow: 1px 1px 10px 0 #ccc
}
.map-touch-toolbar .map-zoomcontrol:after {
position: absolute;
content: "";
height: 1px;
background: #ddd;
top: 48px;
width: 60%;
margin: auto;
left: 0;
right: 0
}
/*自定义导航end*/
</style>
<script src="lib/ol.js"></script>
<title>简单控件</title>
</head>
<body>
<h2>自定义导航</h2>
<div id="mouse_position"></div>
<div id="map" class="map">
<!--自定义导航start -->
<div class="map-toolbar">
<div class="map-pancontrol">
<div class="map-pan-left" onclick="handleClickPan('left')"></div>
<div class="map-pan-top" onclick="handleClickPan('top')"></div>
<div class="map-pan-right" onclick="handleClickPan('right')"></div>
<div class="map-pan-bottom" onclick="handleClickPan('bottom')"></div>
</div>
<div class="map-locate" onclick="reposition()"></div>
<div class="map-zoomcontrol">
<div class="map-zoom-plus" onclick="handleClickZoom('plus')"></div>
<div class="map-zoom-ruler">
<div class="map-zoom-mask"></div>
<div class="map-zoom-cursor"></div>
</div>
<div class="map-zoom-minus" onclick="handleClickZoom('minus')"></div>
</div>
</div>
<!--自定义导航end -->
</div>
<script type="text/javascript">
var shenzhen = ol.proj.fromLonLat([113.958334, 22.535640]);
var initZoom = 12;
var map = new ol.Map({
view: new ol.View({
center: shenzhen,
zoom: initZoom,
maxZoom: 20,
minZoom: 1
// rotation: Math.PI/6
}),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: "map",
controls: []//去除默认控件
});
var view = map.getView();
function handleClickPan(type) {
var oldExtent = view.calculateExtent();
var height = oldExtent[3] - oldExtent[1];
var width = oldExtent[2] - oldExtent[0];
var center = view.getCenter(), newCenter = null;
switch (type) {
case "left":
newCenter = [center[0] - width / 2, center[1]];
break;
case "top":
newCenter = [center[0], center[1] + height / 2];
break;
case "right":
newCenter = [center[0] + width / 2, center[1]];
break;
case "bottom":
newCenter = [center[0], center[1] - height / 2];
}
if (center) {
view.animate({center: newCenter});
}
}
function reposition() {
view.setCenter(shenzhen);
view.setZoom(initZoom);
}
function handleClickZoom(type) {
var initZoom = view.getZoom();
if (type == "plus") {
view.setZoom(initZoom + 1);
} else if (type == "minus") {
view.setZoom(initZoom - 1);
}
}
// ------------缩放条部分-------------
// 初始化缩放条
function getCalcMaskHeight() {
var zoomBarHeight = document.getElementsByClassName("map-zoom-ruler")[0].clientHeight;
var maskHeight = document.getElementsByClassName("map-zoom-cursor")[0].clientHeight;
var zoomSilderHeight = zoomBarHeight - maskHeight / 2;
var maxZoom = view.getMaxZoom();
var minZoom = view.getMinZoom();
var currZoom = view.getZoom();
return (currZoom - minZoom) / (maxZoom - minZoom) * zoomSilderHeight;
}
var initMaskHeight = getCalcMaskHeight()
document.getElementsByClassName("map-zoom-mask")[0].style.height = initMaskHeight + "px";
document.getElementsByClassName("map-zoom-cursor")[0].style.top = initMaskHeight + "px";
//缩放条的拖动
document.getElementsByClassName("map-zoom-cursor")[0].onmousedown = function (evt) {
var that = this;
var oEvent = evt || event;
var disY = oEvent.clientY - parseInt(that.style.top);
that.onmousemove = function (evt) { //实时改变目标元素obox的位置
var oEvent = evt || event;
var curY = oEvent.clientY - disY;
//修改移动cursor的位置
if (curY < 0) {
that.style.top = 1 + 'px';
} else if (curY > 135) {
that.style.top = 135 + 'px';
} else {
that.style.top = oEvent.clientY - disY + 'px';
}
//修改mask的位置
document.getElementsByClassName("map-zoom-mask")[0].style.height = that.style.top;
//设置地图
var zoomBarHeight = document.getElementsByClassName("map-zoom-ruler")[0].clientHeight;
var maxZoom = view.getMaxZoom();
var minZoom = view.getMinZoom();
var newZoom = minZoom + (maxZoom - minZoom) * (parseInt(that.style.top) / zoomBarHeight);
view.setZoom(newZoom);
};
//停止拖动
that.onmouseup = function () {
that.onmousemove = null;
that.onmouseup = null;
};
that.onmouseout = function () {
that.onmousemove = null;
that.onmouseout = null;
};
}
//绑定视图的缩放事件
view.on("change:resolution", function changeResolution(e) {
var maskHeight = getCalcMaskHeight();
document.getElementsByClassName("map-zoom-mask")[0].style.height = maskHeight + "px";
document.getElementsByClassName("map-zoom-cursor")[0].style.top = maskHeight + "px";
})
</script>
</body>
</html>
```