如何为OpenLayers的range控件添加纵向分割线实现图层滑动
实现带纵向分割线的OpenLayers图层滑动控件
我目前使用OpenLayers实现了图层滑动控件,现在想要改成带有贯穿地图的纵向分割线的同款功能。现有实现代码如下,需要调整以添加分割线效果:
现有代码
HTML部分
<input id="swipe" type="range" style="width: 100%;">
TypeScript部分
const imagery = new TileLayer({ source: new XYZ({ url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + '19eciGimIzBlp29oJUJO', maxZoom: 20, }), }); map.addLayer(imagery); const swipe = <HTMLInputElement> document.getElementById('swipe'); imagery.on('prerender', function (event) { const gl = <WebGLRenderingContext> event.context; gl.clear(gl.COLOR_BUFFER_BIT); gl.enable(gl.SCISSOR_TEST); const mapSize = map.getSize(); // [width, height] in CSS pixels // get render coordinates and dimensions given CSS coordinates const bottomLeft = getRenderPixel(event, [0, mapSize[1]]); const topRight = getRenderPixel(event, [mapSize[0], 0]); const width = (topRight[0] - bottomLeft[0]) * (Number(swipe.value) / 100); const height = topRight[1] - bottomLeft[1]; gl.scissor(bottomLeft[0], bottomLeft[1], width, height); }); imagery.on('postrender', function (event) { const gl = <WebGLRenderingContext> event.context; gl.disable(gl.SCISSOR_TEST); }); const listener = function () { map.render(); }; swipe.addEventListener('input', listener); swipe.addEventListener('change', listener);
修改方案:添加纵向分割线
要实现贯穿地图的纵向分割线,需要在postrender事件中绘制一条垂直直线,位置与滑动条的数值对应。修改后的代码如下:
修改后的TypeScript代码
const imagery = new TileLayer({ source: new XYZ({ url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + '19eciGimIzBlp29oJUJO', maxZoom: 20, }), }); map.addLayer(imagery); const swipe = <HTMLInputElement> document.getElementById('swipe'); imagery.on('prerender', function (event) { const gl = <WebGLRenderingContext> event.context; gl.clear(gl.COLOR_BUFFER_BIT); gl.enable(gl.SCISSOR_TEST); const mapSize = map.getSize(); const bottomLeft = getRenderPixel(event, [0, mapSize[1]]); const topRight = getRenderPixel(event, [mapSize[0], 0]); const width = (topRight[0] - bottomLeft[0]) * (Number(swipe.value) / 100); const height = topRight[1] - bottomLeft[1]; gl.scissor(bottomLeft[0], bottomLeft[1], width, height); }); imagery.on('postrender', function (event) { const gl = <WebGLRenderingContext> event.context; gl.disable(gl.SCISSOR_TEST); // 绘制纵向分割线 const mapSize = map.getSize(); const swipePositionX = (mapSize[0] * Number(swipe.value)) / 100; const bottomLeft = getRenderPixel(event, [swipePositionX, mapSize[1]]); const topRight = getRenderPixel(event, [swipePositionX, 0]); // 设置线条样式 gl.lineWidth(2); gl.strokeStyle = '#000'; gl.beginPath(); gl.moveTo(bottomLeft[0], bottomLeft[1]); gl.lineTo(topRight[0], topRight[1]); gl.stroke(); }); const listener = function () { map.render(); }; swipe.addEventListener('input', listener); swipe.addEventListener('change', listener);
关键修改说明
- 在
postrender事件中,计算滑动条对应的横向位置,转换为渲染坐标 - 使用WebGL的绘图API绘制垂直直线,可自定义线条宽度和颜色
- 确保在关闭裁剪测试后绘制线条,避免线条被原有裁剪逻辑影响
内容的提问来源于stack exchange,提问作者Funn_Bobby
相关产品推荐
相关产品推荐

