美文网首页GIS加油站
mapboxGL卷帘实现

mapboxGL卷帘实现

作者: 牛老师讲webgis | 来源:发表于2021-05-07 18:55 被阅读0次

    概述

    卷帘对比是webgis中常见的一种对比方式,本文讲述一下如何在mapboxGL中实现卷帘对比。

    效果

    效果

    实现思路

    1. 通过input[range]实现卷帘的操作;
    2. 通过地图的事件实现两个地图的联动操作。

    实现代码

    <!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>
    

    相关文章

      网友评论

        本文标题:mapboxGL卷帘实现

        本文链接:https://www.haomeiwen.com/subject/sejedltx.html