I have CSS3 transition for reducing width of map element. I have to trigger map.resize() when changing map block width to update map width programmatically. It jumps to new width, without transition (what is expected)
Is there any way to implement animation of map block width transition?
Except changing map block width by JS and triggering resize on each frame.
Another way is to create block where map will be rendered covering full width, and then shrink that block with overflow:hidden and use offset to translate map center point a bit. But in that case we get wide map, and tiles will be loaded in the background (even that part of block is hidden) i suppose.
Related
I'm using leafletJS to display a map (with 500px height and dynamic width). I'm using map.fitWorld(); and noWrap property to show the entire world map (without repetition).
is there a way to fill out the gray space (automatically) by zooming in just how much ever is required?
To fit the map we use mapbox.fitBounds() and to set we do mapbox.setMaxBounds(), which avoid panning. This work's perfectly well on first load.
But on Window resize map get cropped and take the bounds reference from initially set maxbounds. I am trying to fit the map in viewport using setTimeout, so that map first fit on screen and then getting map bounds from mapbox.getBounds() set the value in mapbox.setMaxBounds(). But this is just an hack.
Is there any correct way to do so?
Please help... and thank you..
Hope you are all well...
After many days of struggle, we are able to find the perfect solution, for my own question posted...
Firstly,
mapbox.fitBounds() is the method on passing given bounds as args, will fit the geometry(polygon etc..), making the center point in the middle. But the only thing it does not disallow panning.
However, we can disallow panning using mapbox.setMaxBounds() which allow us to constrained to passed bounds.
But on window resize, somehow mapbox Map change the bounds as per internal logic, which will no longer be the same as passed bounds initially...
In order to fit the geometry on the viewport, at the same time disallow panning on window resize, we use Resize Observer to observe map's container, and in its callback, we just wrote, three lines
Set map.setMaxBounds(null) //to null
set fitbounds(bounds). //bounds of geometry that u have
Get bounds from viewport using
let bnds = mapbox.getBounds();
and finally set in map.setMaxBounds(bnds);
Note to pass the 3. point in requestAnimationFrame instead of setTimeout
UPDATED Code
MaxBounds and custom asymmetric padding in Mapbox GL
Hope this will help...
Thank you.
(pretty new to Mapbox and JS, so I'm in a bit over my head)
I'm working on a page where the user needs to adjust the size of map container. It needs to be able to get accurate bounds and center point of the resized map (via map.getBounds and map.getCenter).
When I use JS to adjust the size of the container div, the center and bounds are not adjusted.
Fiddle: http://jsfiddle.net/xcow63sm/3/
Panning/zooming results in updated center and bounds. Browser window resize (if you have width or height set to 100%) works too. I would expect changing the container dimensions would adjust center and bounds.
However, if you use the form fields to adjust the height/width of the container div, the center and bounds do not. I've tried (with increasing desperation):
function resize (){
var inputwidth = document.getElementsByName("mapwidth")[0].value;
var inputheight = document.getElementsByName("mapheight")[0].value;
var mapDiv = document.getElementById('map');
var mapcenter = map.getCenter();
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.updateSize();
map.update();
map.resize();
map.invalidateSize();
document.getElementById("mapcenter").value = mapcenter;
Edit: this seems to apply but I can't make sense of it: Resizing a leaflet map on container resize
If I understand you, you have two issues: you don't like how the map is positioned after its size changes, and you're getting white space.
Map positioning after resize
There are at least three valid options for how a map should update if, say, its width and height are suddenly doubled:
keep the same northern and western bound, extend the eastern and southern bounds. (Expanding the viewing area right and down)
move all four bounds outwards (keeping the centre of the map in the same place)
leave all four bounds where they are are, but change the zoom, so the same geographic area is displayed, but in more detail.
I think your issue is that Mapbox is choosing option 1, but you want one of the other two options. The solution, as I think you've discovered, is simply to do your own maths and set the bounds how you want them.
Map failing to repaint correctly
Your second issue is that when you resize, calling map.resize() isn't updating the internal size of the map properly, and you're left with white space. The reason for this is you're using animated CSS properties. So when you do this:
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.resize();
This doesn't work because the map's size hasn't actually transitioned to the new size yet. You can work around it like this:
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
window.setTimeout(()=>map.resize(), 500);
There's probably a better event you can listen to, to keep updating as the map area expands.
Updated fiddle here: http://jsfiddle.net/xcow63sm/11/
Btw you should consult the documentation here. I'm not sure where you got map.updateSize() from but that's not Mapbox-GL-JS :)
I'm using OpenLayers 3 and OpenStreetMap to print maps on paper, and for this I'd need to render the maps with more details and higher DPI than are shown on the screen. I'm using CSS to set the size of ol.Map's target in centimeters to the desired size for the printout (.map { width: 7cm; height: 6.3cm; }).
By default OpenLayers shows one of my maps like this, which is too low detail for my needs:
By changing the map size with map.setSize(map.getSize().map(function (x) { return x*2; })); I'm able to increase the detail closer to what I need:
But the problem with this hack is that when the window is resized, the size is reset and it will look wrong like this:
How would I be able to control the OSM zoom level and map DPI independently of the map's size on screen to achieve the desired outcome (the second picture) reliably?
A solution I've found is to put the map inside two nested divs. The inner one has, for example, width: 200%; height: 200%, and the outer one would have transform: scale(.5) translate(-50%,-50%);. This would double the resolution the user sees.
This approach changes the pixel zoom level relative to the zoom level on screen. However, it needs to be recalculated and updated whenever the user zooms the map.
Leafletjs has a function pad(x) for increasing the latLng bounds. How do I shrink it? I've tried putting a negative number in there with little success.
I'm basically trying to see if a marker is within the current view, and if not center on that marker. But some markers can be plotted right on the edge of view and still be classed as in view. I'm trying to add inner padding on the current viewport bounds to avoid this.
if(!map.getBounds().pad(-1.5).contains(marker.getLatLng()))
You can use the paddingTopLeft, paddingBottomRight or padding options of L.Map's fitBounds method:
Sets the amount of padding in the top left corner of a map container that shouldn't be accounted for when setting the view to fit bounds. Useful if you have some control overlays on the map like a sidebar and you don't want them to obscure objects you're zooming to.
http://leafletjs.com/reference.html#map-paddingtopleft
map.fitBounds(layer, {'padding': [n, n]})
The negative value range for pad() is 0 to -0.5.
https://github.com/Leaflet/Leaflet/issues/5741
edit: link basically states that pad takes in a ratio of 1 not a typical percentage value. So to decrease the bounds by 50% (which would visually make it 0, because the left bounds would go in 50% to the middle, and the right bounds would also go in 50% to the middle, etc) the parameter value would be pad(-0.5) NOT pad(-50)
to increase add a positive ratio.