Last active
November 29, 2017 07:02
-
-
Save up209d/770753d2af9dadc6fb2b9c702fb39243 to your computer and use it in GitHub Desktop.
Leaflet Hack for Center Point with Offset X/Y (Top/Left)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Change the center of map with offset value, | |
// useful for some cases such as | |
// a Menu/Sidebar sit on top of the map | |
// a Footer sit on top of the map | |
// This hack covers zoom/pan and tileLoading working correctly to the new center (with offset) point | |
(function(global){ | |
global.Map.prototype._getNewPixelOrigin = function (center, zoom) { | |
var viewHalf = this.getSize()._divideBy(2); | |
if (this.options.offset) { | |
viewHalf.x += this.options.offset.x / 2; | |
viewHalf.y += this.options.offset.y / 2; | |
} | |
return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round(); | |
}; | |
global.Map.prototype._getCenterLayerPoint = function () { | |
var viewHalf = this.getSize()._divideBy(2); | |
if (this.options.offset) { | |
viewHalf.x += this.options.offset.x / 2; | |
viewHalf.y += this.options.offset.y / 2; | |
} | |
return this.containerPointToLayerPoint(viewHalf); | |
}; | |
global.Map.prototype.setZoomAround = function (latlng, zoom, options) { | |
var scale = this.getZoomScale(zoom), | |
viewHalf = this.getSize().divideBy(2); | |
if (this.options.offset) { | |
viewHalf.x += this.options.offset.x / 2; | |
viewHalf.y += this.options.offset.y / 2; | |
} | |
var containerPoint = latlng instanceof global.Point ? latlng : this.latLngToContainerPoint(latlng); | |
var centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale); | |
var newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset)); | |
return this.setView(newCenter, zoom, {zoom: options}); | |
}; | |
global.Map.prototype._limitCenter = function (center, zoom, bounds) { | |
if (!bounds) { | |
return center; | |
} | |
var centerPoint = this.project(center, zoom), | |
viewHalf = this.getSize().divideBy(2); | |
if (this.options.offset) { | |
viewHalf.x += this.options.offset.x / 2; | |
viewHalf.y += this.options.offset.y / 2; | |
} | |
var viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)), | |
offset = this._getBoundsOffset(viewBounds, bounds, zoom); | |
// If offset is less than a pixel, ignore. | |
// This prevents unstable projections from getting into | |
// an infinite loop of tiny offsets. | |
if (offset.round().equals([0, 0])) { | |
return center; | |
} | |
return this.unproject(centerPoint.add(offset), zoom); | |
}; | |
global.Map.Drag.prototype._onZoomEnd = function () { | |
var pxCenter = this._map.getSize().divideBy(2); | |
if (this.options.offset) { | |
pxCenter.x += this.options.offset.x / 2; | |
pxCenter.y += this.options.offset.y / 2; | |
} | |
var pxWorldCenter = this._map.latLngToLayerPoint([0, 0]); | |
this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x; | |
this._worldWidth = this._map.getPixelWorldBounds().getSize().x; | |
}; | |
global.Map.prototype.shiftOffset = function (offset) { | |
this.options.offset.x = offset.x; | |
this.options.offset.y = offset.y; | |
this.invalidateSize(); | |
}; | |
global.GridLayer.prototype._getTiledPixelBounds = function (center) { | |
var map = this._map, | |
mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(), | |
scale = map.getZoomScale(mapZoom, this._tileZoom), | |
pixelCenter = map.project(center, this._tileZoom).floor(), | |
halfSize = map.getSize().divideBy(scale * 2); | |
if (map.options.offset) { | |
halfSize.x += map.options.offset.x / (scale * 2); | |
halfSize.y += map.options.offset.y / (scale * 2); | |
} | |
return new global.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize)); | |
}; | |
var any3d = !window.L_DISABLE_3D && (L.Browser.ie3d || L.Browser.webkit3d || L.Browser.gecko3d) && !L.Browser.opera12 && !L.Browser.phantom; | |
global.Renderer.prototype._updateTransform = function (center, zoom) { | |
var scale = this._map.getZoomScale(zoom, this._zoom); | |
var position = getPosition(this._container); | |
var viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding); | |
if (this._map.options.offset) { | |
viewHalf.x += this._map.options.offset.x*(0.5); | |
viewHalf.y += this._map.options.offset.y*(0.5); | |
} | |
var currentCenterPoint = this._map.project(this._center, zoom); | |
var destCenterPoint = this._map.project(center, zoom); | |
var centerOffset = destCenterPoint.subtract(currentCenterPoint); | |
var topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset); | |
if (any3d) { | |
setTransform(this._container, topLeftOffset, scale); | |
console.log('RENDERER: ',topLeftOffset) | |
} else { | |
setPosition(this._container, topLeftOffset); | |
} | |
}; | |
function getPosition(el) { | |
// this method is only used for elements previously positioned using setPosition, | |
// so it's safe to cache the position for performance | |
return el._leaflet_pos || new Point(0, 0); | |
} | |
function setPosition(el, point) { | |
/*eslint-disable */ | |
el._leaflet_pos = point; | |
/*eslint-enable */ | |
if (any3d) { | |
setTransform(el, point); | |
} else { | |
el.style.left = point.x + 'px'; | |
el.style.top = point.y + 'px'; | |
} | |
} | |
var TRANSFORM = testProp( | |
['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform']); | |
function setTransform(el, offset, scale) { | |
var pos = offset || new L.Point(0, 0); | |
el.style[TRANSFORM] = | |
(L.Browser.ie3d ? | |
'translate(' + pos.x + 'px,' + pos.y + 'px)' : | |
'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') + | |
(scale ? ' scale(' + scale + ')' : ''); | |
} | |
function testProp(props) { | |
var style = document.documentElement.style; | |
for (var i = 0; i < props.length; i++) { | |
if (props[i] in style) { | |
return props[i]; | |
} | |
} | |
return false; | |
} | |
})(L); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TO USE THE PLUGIN
Create Map with offset value in options
Create Map Tile as normal
Change to new Center offset