Openlayers 卷帘功能
卷帘

“卷帘”功能可以分为两部分:
- 控件元素的拖动。这里控件仿照ArcGIS for JS上的样式。
- 地图图层渲染流程的控制,对上层图层进行裁剪。
首先我们需要一个DOM组件作为拖动的“卷帘”,将其放在map容器内部,避免影响页面其他要素。
<div id="map" class="map"><div id="swipeContainer"><div id="swipeDiv"><div class="handle">div>div>div>
div>
在设置样式时,将map元素设为相对定位,则其内部的子元素的绝对定位将参考map元素的位置,即“卷帘”的拖动位置将参考map元素进行。根据“卷帘”组件拖动的位置,利用地图渲染相关的事件,对图层进行处理实现卷帘效果。
地图渲染相关的事件:
precompose:未渲染,layers或layer被渲染前触发postcompose:layer图层渲染后触发,可以在事件源中获取用于渲染图层的上下文context,也可以得到canvas元素。图层的渲染其实就是将从数据源中请求得到的矢量数据,通过计算转换绘制在content上下文中或将请求得到的图片嵌入到上下文中相应的位置postrender:map被渲染完成后触发
当初始化map实例时,会先触发map的precompose事件,再依次触发layers集合中每个图层的precompose事件和postcompose事件,在所有layer都渲染完成后,才会触发map的postrender事件。
卷帘实现原理:在客户端监听上层图层的postcompose事件,获取渲染的上下文content,对其进行裁剪,让下层图层数据可见。
<html lang="en">
<head><meta charset="utf-8"><link rel="stylesheet" href="css/ol.css" type="text/css"><style>.map {height: 400px;width: 100%;position: relative;}#swipeContainer {position: absolute;opacity: 0.8;width: 0.625rem;height: 100%;/* margin: 0 auto; */top: 0;left: 50%;background-color: rgba(50, 50, 50, 0.75);cursor: col-resize;z-index: 2;}#swipeContainer:hover {opacity: 0.5;}#swipeDiv {border: solid 0.5px #ffffff;height: 100%;width: 0px;margin: 0 auto;}#swipeDiv .handle {width: 51px;height: 24px;margin-top: -12px;margin-left: -20px;top: 50%;left: 0;position: absolute;z-index: 30;font-family: "CalciteWebCoreIcons";speak: none;font-size: 12px;font-style: normal;font-weight: normal;font-variant: normal;text-transform: none;text-indent: 0;line-height: 1;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;background-color: black;color: white;opacity: 0.6;}*,*:before,*:after {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.handle:before {margin: 0 18px 0 5px;content: "\0399\0399\0399";width: 20px;height: 24px;line-height: 2;}.handle:after {content: "\0399\0399\0399";width: 20px;height: 24px;line-height: 2;}style><script src="lib/ol.js">script><title>卷帘title>
head>
<body>
<h2>卷帘(裁剪图层)h2>
<div id="map" class="map"><div id="swipeContainer"><div id="swipeDiv"><div class="handle">div>div>div>
div>
<script type="text/javascript">window.onload = function () {var map = initMap();initSwipeDom(map);swipeLayer(map);}function initMap() {var bingKey = 'AmosL5A0GtVryl4sXNZm6U5EQMD6brAd5E8AJPGJf8AUU1saDYXDkb5CwQFijans';var roadLayer = new ol.layer.Tile({id:'road',source: new ol.source.BingMaps({key: bingKey, imagerySet: 'Road'}),name: "Bing道路图层"});var imageLayer = new ol.layer.Tile({id:'aerial',source: new ol.source.BingMaps({key: bingKey, imagerySet: 'Aerial'}),name: "Bing影像图层"});var map = new ol.Map({view: new ol.View({center: [12614553, 2648165],zoom: 12,minzoom: 6,maxzoom: 15,}),layers: [roadLayer,imageLayer],target: "map"});return map;}function initSwipeDom(map) {var swipe = document.getElementById("swipeContainer");var obj = {};swipe.onmousedown = function(event) {var e = event || window.event; // 鼠标点击元素那一刻相对于元素左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离obj.diffX = e.clientX - this.offsetLeft;document.onmousemove = function(event) {var e = event || window.event;var moveX = e.clientX - obj.diffX;if (moveX < 0) {moveX = 0} else if (moveX > window.innerWidth - swipe.offsetWidth) {moveX = window.innerWidth - swipe.offsetWidth}swipe.style.left = moveX + 'px';//重新渲染图层map.render();};document.onmouseup = function() {this.onmousemove = null;this.onmouseup = null;}};}function swipeLayer(map) {var layers = map.getLayers();var topLayer = layers.item(layers.getLength() - 1);topLayer.on('precompose', function(event) {var swipe = document.getElementById("swipeContainer");var ctx = event.context;//计算图层在canvas画布上需要显示的范围var mapSize = map.getSize();var height = event.context.canvas.height;var width = event.context.canvas.width;var swipeWidth = swipe.offsetLeft*width/mapSize[0];var tl = [swipeWidth,0];var tr = [width,0];var bl = [swipeWidth,height];var br = [width,height];ctx.save();//绘制裁剪路径ctx.beginPath();ctx.moveTo(tl[0], tl[1]);ctx.lineTo(bl[0], bl[1]);ctx.lineTo(br[0], br[1]);ctx.lineTo(tr[0], tr[1]);ctx.closePath();//裁剪,裁剪路径以外的部分不会绘制在canvas上下文中ctx.clip();});topLayer.on('postcompose', function(event) {var ctx = event.context;ctx.restore();});}
script>
body>
html>
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
