概述
卷帘对比是webgis中常见的一种对比方式,本文讲述一下如何在mapboxGL
中实现卷帘对比。
效果
实现思路
- 通过
input[range]
实现卷帘的操作; - 通过地图的事件实现两个地图的联动操作。
实现代码
代码语言:javascript复制<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>mapboxGL卷帘</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css' rel='stylesheet' />
<style>
html, body, .map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.map {
position: absolute;
left: 0;
top: 0;
font-size: 32px;
color: white;
padding: 100px 0;
}
.swipe input[type=range] {
margin: 0;
padding: 0;
width: 100%;
position: absolute;
top: calc(50% - 18px);
left: 0;
z-index: 9;
outline: none;
-webkit-appearance: none;
height: 0;
background-color: white;
}
.swipe input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
height:36px;
width: 36px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABhklEQVRoQ 2XPU7EMBCFvyk4AAU3oOAMFJyKrXYRLAIa9lycgYIbUFAjCq9CAgpZO2PHTFDEuHX8PN97/ouw8CYLrx8H OsEPQFPoNIBX0KVBlYP9wSqLawU8AQqDawe7glUW1gp8H8SCHANHAlsKk0bHR7gDvgQ2ObMk5VAgEvgsRPcCaxyxEu/Ce0czVxNWwnsNA0VYFD8l95G4F4TL kPcAXcDsaoEKMAieJfgXOBl5ICtW8DnAJPwEkJRBJgpPgLgWetoCn9Ac46iONciChAoviimoSfv6sBQpHA4cfR5XQA8BvFN3MbAEQ3dgzghvbIrGpGAFuBpr7vllpC/eNsEogBQPT4HtvEMYi37gSaexMn7x7tGI1BzH2Mjl6cORdZDGIt8DBpbSUGBVjTPiP6Tb31VYBGbXDFq6JTwabMkwXQg3if4TH3 ebKfW9lA0x11XqcA1g7rOl7AppD1v2egLXDmr4noDlk3e8JWDus6XsCmkPW/Z6AtcOaviegOWTdv/gE9iihUjF faiWAAAAAElFTkSuQmCC);
background-size: 100%;
cursor: move;
}
.swipe .swipe-bar {
position: fixed;
width: 4px;
height: 100%;
content: ' ';
top: 0;
background: rgb(255, 0, 0);
z-index: 9;
}
</style>
</head>
<body>
<div class="swipe">
<input type="range" id="swipe"/>
<div class="swipe-bar" id="swipeBar"></div>
</div>
<div class="map" id="map1">map1</div>
<div class="map" id="map2">map2</div>
<script src='https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js'></script>
<script>
const style1 = {
"version": 8,
"name": "lzugis",
"sources": {
"nav": {
"type": "raster",
"tiles": ['https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'],
"tileSize": 256
}
},
"layers": [{
"id": "nav",
"type": "raster",
"source": "nav",
"minzoom": 0,
"maxzoom": 17
}]
}
const style2 = {
"version": 8,
"name": "lzugis",
"sources": {
"nav": {
"type": "raster",
"tiles": ['http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8'],
"tileSize": 256
}
},
"layers": [{
"id": "nav",
"type": "raster",
"source": "nav",
"minzoom": 0,
"maxzoom": 17
}]
}
const doms = document.getElementsByClassName('map')
const maps = []
const styles = [style1, style2]
for (let i = 0; i < doms.length; i ) {
const dom = doms[i];
maps.push(new mapboxgl.Map({
container: dom,
style: styles[i],
center: [103.081163, 37.1612],
zoom: 3.5,
minZoom: 2,
maxZoom: 18
}))
}
maps.forEach(map => {
const mapDom = map.getContainer().getAttribute('id')
// 鼠标进入的时候注册事件
map.on('mouseover', e => {
const mouseDom = e.target.getContainer().getAttribute('id')
if(mouseDom === mapDom) {
map.on('move', moveEvent)
} else {
map.off('move', moveEvent)
}
})
// 鼠标移除的时候关闭事件
map.on('mouseout', e => {
maps.forEach(map => {
map.off('move', moveEvent)
})
})
})
function moveEvent(e) {
const c = e.target.getCenter()
const d = e.target.getContainer().getAttribute('id')
const z = e.target.getZoom()
maps.forEach(map => {
if(d !== map.getContainer().getAttribute('id')) {
map.setCenter(c)
map.setZoom(z)
}
})
}
const map1 = document.getElementById('map1')
const map2 = document.getElementById('map2')
const WIDTH = map1.clientWidth
const HEIGHT = map1.clientHeight
const swipe = document.getElementById('swipe')
const MAX = 1000
swipe.setAttribute('min', 0)
swipe.setAttribute('max', MAX)
swipe.setAttribute('value', MAX / 2)
swipe.oninput = function(e) {
setStyle()
}
setStyle()
function setStyle() {
const v = swipe.value
const left = Math.ceil((v / MAX) * WIDTH)
map1.style.clip = `rect(0, ${left}px, ${HEIGHT}px, 0)`
map2.style.clip = `rect(0, ${WIDTH}px, ${HEIGHT}px, ${left}px)`
// 设置bar样式
const swipeBar = document.getElementById('swipeBar')
swipeBar.style.left = `${left - 2}px`
// 设置swipe样式
const hWIDTH = MAX / 2
const isLeft = v < hWIDTH
const offsetL = Math.abs(((hWIDTH - v) / hWIDTH) * 18)
swipe.style.left = isLeft ? `-${offsetL}px` : `${offsetL}px`
}
</script>
</body>
</html>