leaflet上下卷帘
2023-12-27 17:42:31
leaflet上下卷帘
1.功能背景
本功能来自一个产品经理的奇怪需求,要求左右、上下可以切换的卷帘对比。
2.前置条件
Leaflet开源插件中,有一个卷帘插件
Github地址:https://github.com/digidem/leaflet-side-by-side
具体使用方法都又详细说明和示例,不在赘述,但是这个插件只有左右卷帘,下载代码后发现可以根据他的方法来修改为上下卷帘
3.功能开发
3.1.修改_updateClip
打开leaflet-side-by-side.js,搜索_updateClip方法,可以看到左右卷帘实现的方法。
_updateClip: function () {
var map = this._map
var nw = map.containerPointToLayerPoint([0, 0])
var se = map.containerPointToLayerPoint(map.getSize())
var clipX = nw.x + this.getPosition()
var dividerX = this.getPosition()
this._divider.style.left = dividerX + 'px'
this.fire('dividermove', {x: dividerX})
var clipLeft = 'rect(' + [nw.y, clipX, se.y, nw.x].join('px,') + 'px)'
var clipRight = 'rect(' + [nw.y, se.x, se.y, clipX].join('px,') + 'px)'
if (this._leftLayer) {
this._leftLayer.getContainer().style.clip = clipLeft
}
if (this._rightLayer) {
this._rightLayer.getContainer().style.clip = clipRight
}
},
左右卷帘原理是通过获取地图容器大小,然后根据中心点去切割两个图层的dom。原理并不难理解,根据源码拓展上下卷帘,修改后的代码:
_updateClip: function () {
var map = this._map
var nw = map.containerPointToLayerPoint([0, 0])
var se = map.containerPointToLayerPoint(map.getSize())
this.fire('dividermove', {x: dividerX})
if (this.mod === "leftright") {
var dividerX = this.getPosition()
this._divider.style.left = dividerX + 'px'
var clipX = nw.x + this.getPosition()
var clipLeft = 'rect(' + [nw.y, clipX, se.y, nw.x].join('px,') + 'px)'
var clipRight = 'rect(' + [nw.y, se.x, se.y, clipX].join('px,') + 'px)'
} else if (this.mod === "topbottom"){
var dividerY = this.getPositionY()
this._divider.style.top = dividerY + 'px'
var clipY = nw.y + this.getPositionY()
var clipLeft = 'rect(' + [nw.y, se.x,clipY, nw.x].join('px,') + 'px)'
var clipRight = 'rect(' + [clipY, se.x,se.y, nw.x].join('px,') + 'px)'
}
if (this._leftLayer) {
this._leftLayer.getContainer().style.clip = clipLeft
}
if (this._rightLayer) {
this._rightLayer.getContainer().style.clip = clipRight
}
},
我加了一个mod参数用于切换上下和左右卷帘。leftright为左右,topbottom为上下。
3.2.添加getPositionY方法
找到getPosition方法,这个方法是在拖动卷帘时计算左右卷帘裁剪像素的参数,我们可以根据该方法,添加一个拖动卷帘计算上下裁剪裁剪像素的参数的方法。
getPositionY: function () {
var rangeValue = this._range.value
var offset = (0.5 - rangeValue) * (2 * this.options.padding + this.options.thumbSize)
return this._map.getSize().y * rangeValue + offset
},
3.3.添加上下卷帘range和divider
功能实现,还需要在添加一个横向的按钮和横线,用于拖动和分割上下图层。
找到addTo方法,可以看到相关方法。
addTo: function (map) {
this.remove()
this._map = map
var container = this._container = L.DomUtil.create('div', 'leaflet-sbs', map._controlContainer)
this._divider = L.DomUtil.create('div', 'leaflet-sbs-divider', container)
var range = this._range = L.DomUtil.create('input', 'leaflet-sbs-range', container)
range.type = 'range'
range.min = 0
range.max = 1
range.step = 'any'
range.value = 0.5
range.style.paddingLeft = range.style.paddingRight = this.options.padding + 'px'
this._addEvents()
this._updateLayers()
return this
},
根据该方法,修改为下面代码。
addTo: function (map) {
this.remove()
this._map = map
var container = this._container = L.DomUtil.create('div', 'leaflet-sbs', map._controlContainer)
this._divider = L.DomUtil.create('div', 'leaflet-sbs-divider', container)
var range = this._range = L.DomUtil.create('input', 'leaflet-sbs-range', container)
range.type = 'range'
range.min = 0
range.max = 1
range.step = 'any'
range.value = 0.5
range.style.paddingLeft = range.style.paddingRight = this.options.padding + 'px'
this._addEvents()
this._updateLayers()
var clientWidth = document.getElementById('map').clientWidth
var clientHeight = document.getElementById('map').clientHeight
if (this.mod === "topbottom"){
document.getElementsByClassName('leaflet-sbs-range')[0].style.transform = "rotate(90deg)"
document.getElementsByClassName('leaflet-sbs-range')[0].style.width = clientHeight + 'px'
document.getElementsByClassName('leaflet-sbs-range')[0].style.margin = '0 ' + (clientWidth - clientHeight)/2 + 'px'
document.getElementsByClassName('leaflet-sbs-divider')[0].style.width = "100%"
document.getElementsByClassName('leaflet-sbs-divider')[0].style.height = '4px'
document.getElementsByClassName('leaflet-sbs-divider')[0].style.left = '0'
this._map.on("resize", ()=>{
clientWidth = document.getElementById('map').clientWidth
clientHeight = document.getElementById('map').clientHeight
document.getElementsByClassName('leaflet-sbs-range')[0].style.width = clientHeight + 'px'
document.getElementsByClassName('leaflet-sbs-range')[0].style.margin = '0 ' + (clientWidth - clientHeight)/2 + 'px'
})
} else {
clientWidth = this._map.getSize().x
document.getElementsByClassName('leaflet-sbs-range')[0].style.width = clientWidth + 'px'
this._map.on("resize", ()=>{
clientWidth = this._map.getSize().x
document.getElementsByClassName('leaflet-sbs-range')[0].style.width = clientWidth + 'px'
})
}
return this
},
其中也是踩了不少坑,最后的效果还可以。最后把改好的js和示例代码放在这里,如果有bug可以在评论区里面说一下。
示例下载链接 https://download.csdn.net/download/weixin_42066016/88669339
文章来源:https://blog.csdn.net/weixin_42066016/article/details/135244480
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!