I'd like to perform a pan and zoom effect from one marker to another. For example if the current view is {lat:m1.lat, lng:m1.lng, zoom:13}, I would do something like this:
//Zoom out to initial position
map.setView([center.lat, center.lng], 13, { animate: true });
and at the end of transition...
//Zoom in to new marker
map.setView([m2.lat,m2.lon],18,{animate:true});
Unfortunately, the zoom effect is too fast. So, can I get a smooth zoom?
Use flyTo, available in Leaflet 1.0.0-rc1.
Related
I have a leaflet map with a few layers on it.
Whenever layers are not in the viewport, they are hidden untill panning has completed:
Regular view with layers:
Panning right, to show layers outside viewport:
Panning stopped:
As illustrated above, the layers will first become visible once panning has stopped and mouse(finger) released.
I have tried the following, which didn't work
var map = L.map('map',{ bounceAtZoomLimits: false, removeOutsideVisibleBounds: false}).setView([40, 0], 2);
L.geoJson(mapData).addTo(map);
Seems the solution was right in front of me
Adding the following will render the entire map:
var map = new L.Map('map');
map.getRenderer(map).options.padding = 100;
Solution found here
I have created a map using OpenLayers3. I can succesfully zoom to a layer on the map using the following code:
map.getView().fit(extent, map.getSize());
However I woulld like something similiar in an animated way.
I know about the following animations:
ol.animation.pan
ol.animation.zoom
By using these I can't zoom to a layer, using ol.animation.pan I can only pan to a point (and not to a boundingbox) and using ol.animation.zoom I can zoom to a resolution (and not to a boundingbox). So what I am looking for is an animated .fit so I can zoom animated to an extent.
Any suggestions on how I can achieve that would be appreciated :)
Starting with v3.20.0, OpenLayers has a new duration option on ol.View#fit(). To get a 1 second animation to the fit extent, set it to 1000:
// OpenLayers v3.20.x
view.fit(extent, size, {duration: 1000});
Also note that starting with v3.21.0, the API for ol.View#fit() is simplified - it no longer requires a size to be set (unless there is more than one map on the page):
// OpenLayers >= v3.21.0
view.fit(extent, {duration: 1000});
i just solved this way
var view = map.getView()
var pan = ol.animation.pan({ source: view.getCenter() });
var zoom = ol.animation.zoom({ resolution: view.getResolution() });
map.beforeRender(pan, zoom);
view.fit(extent, map.getSize())
I would like to be able to fitBounds to a feature when you click on it, but when it zooms in I'd like it to take into account a control layer that will appear once zoomed in, and zoom in but just about 150px to the left. Currently I can accomplish this with the following code, but unfortunately it's not a smooth zoom because my current method will zoom using fitBounds and then once zoomed it uses panBy to pan 150px to the left. This wouldn't be so bad if the panning was smooth, perhaps maybe after a 250ms wait. Ideally I would like to be able to do some math on the bounds passed to the fitBounds method to simply account for the 150px shift to the left.
Here is an example of what I currently have working.
Here is a simplified version of the code I'm using: (you may click here for a fully working version with all of the source code)
when you click
function clickFeature(e) {
var layer = e.target;
map.fitBounds(layer.getBounds());
}
map on zoomEnd:
map.on({
zoomend: function() {
map.panBy([150, 0]);
}
});
So, I've achieved the desired function, but it's just not smooth.
Is there a way to just do some math on the bounds that we're getting for the clicked feature so that when we zoom we zoom into an already modified coordinate, thus eliminating the two-step animation process?
First of all, you can control the animation using pan options. This could help you make the transition smoother.
You can see those here.
Second, you can calculate the offset that you need by using the conversion functions. These can be seen here.
For example, you could do something like (off the top of my head) use getBoundsZoom for the map object on the polygon bounds to figure out your future zoom, then use that zoom in the project function with the polygon and create a new LatLngBound from the polygon bound that is slightly offset.
Hope this helps!
I had this same issue, and if was easier than I had thought!
You can set padding on the fitBounds method (and all the pan/zoom methods for that matter)
http://leafletjs.com/reference.html#map-fitboundsoptions
so:
map.fitBounds(layer.getBounds(),{paddingBottomRight:[150,0]});
In my google maps application I have a follow method which follows a moving marker. When it is following I want to allow zooming through all the usual methods (dblclick, dblleftclick, mousewheel and touch events) and I want to disable panning of any kind. The problem is that on zoom with mousewheel and dblclick the map gets panned to the position of the mouse. I can disable everything just fine but I want to allow zooming. I have solved the mousewheel problem by using the jquery mousewheel plugin and using the delta to change the zoom.
Is there some easy way to do this or do I have to write a listener for all the different touch and mouse events?
EDIT
I have already disable double click, mousewheel zooming and dragging but I want to have the double click functionality still there. I also want the touch events there but I want to have them zoom from the centre rather than from where the event happened. The real problem is replicating the events which google already handle but change the functionality a bit
var options = {
disableDoubleClickZoom: true,
draggable: false,
scrollwheel: false,
panControl: false
};
this.map = new google.maps.Map(document.getElementById('map'), options);
My ideal solution would be if there was a disableDoubleClickPan and disableScrollwheelPan or the draggable option actual prevents all dragging of any kind
EDIT
This is for all devices, desktop and mobile.
Here is how I did it:
var options = {
draggable: false,
scrollwheel: false,
panControl: false,
maxZoom: Zoom,
minZoom: Zoom,
zoom: Zoom,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
As you can see, setting maxZoom and minZoom to the same value helps block user's double click event.
I have ended up going with a combination of options. Firstly I had to override desktop events which occurred to get my achieved result (touch, double click, double left click, and mouse wheel).
On a touch screen devise I paused all updates to the markers when there were more than two touches. this meant that any pinch event was not jumping around when the zoom operating.
On a normal web desktop device I disabled the zoom and double click events on the map and rewrote my own event handlers.
To distinquish between them I checked for the ontouchstart event in the window object.
function setDraggable(draggable) {
if ("ontouchend" in document) {
return;
}
var options = {
draggable: draggable,
panControl: draggable,
scrollwheel: draggable
};
this.map.setOptions(options);
},
The zoom_changed or idle events where not really an option for a few reasons:
The idle event only gets called when the map is idle and with the amount of animation I was doing this never got called.
The animation at each step recentered the map on the followed markers so the zoom_changed event would be recalling the recenter before an animation frame.
due to the amount of animation the idea of not panning to the center is to reduce animation frames and improve performance.
While it's possible to argue that double-clicking the map or wheel-zooming the map need not take account of the mouse location (because you are acting on the map object rather than a location on the map), pinch-to-zoom is always location-dependent because you physically stretch or squash the map around a location. To alter that behaviour would be distinctly unintuitive.
In this case you should listen for zoom_changed or idle and then pan the map to recentre it, so the user can see what's going on.
You could even use those events to handle the default double-click or mousewheel behaviour so that it's obvious you are changing the level of control the user normally has.
I have a Google V3 map which uses steetView and some map markers.
The little yellow streetView pegman sits on the map on top of the markers.
Is there a way to change the z-indexes so that my markers will be above the pegman
(so that they can be easlly clicked on without having to zoom in)?
In case anything is not clear, here is a fiddle....
http://jsfiddle.net/spiderplant0/BRkCA/
After a bit of experimenting I came up with this...
$("#map_canvas img[src*=cb_scout]").parent("div").css({'zIndex': -200});
$($("#map_canvas img[src*=cb_scout]")[1]).parent("div").parent("div").css({'zIndex': -200});
This forces the pegman to sit beneath the markers but now the pegman is no longer dragable and each time the map is moved etc, the pegman jumps above the markers again.
To keep the pegman under your markers you can watch for the pov_changed event and reset the z-index after a short delay
$google.maps.event.addListener(panorama, 'pov_changed', function() {
var func=function(){
$("#map_canvas img[src*=cb_scout]").parent("div").css({'zIndex': -200});
}
setTimeout(func,1000);
}
});
You will also need to change the depth of the pegman after the maps moves, which can be accomplished with the following snippet
google.maps.event.addListener(map, 'idle', function() {
google.maps.event.trigger(panorama, 'pov_changed');
})
If you want to be able to drag the pegman, you must first place it above the markers by having a toggle button swap the pegman's depth and add an exception to the pov_changed event handler preventing the pagman from dropping depths when the toggle button is active.
Okay, this may be a bit hacky... (and I hope I understood what you were doing)
1) Disable street view control
2) Make another control with a lower zIndex than the marker you have.
3) Update street view control with the position of the fake street view marker.
http://jsfiddle.net/z7Lp8/
You can set the zIndex of the marker above google.maps.Marker.MAX_ZINDEX in order for the pegman to remain under the marker. MAX_ZINDEX is the maximum default z-index that the API will assign to a marker. Marker z-indexes only work when optimizations are turned off on all markers on the map.
Forked fiddle from question to illustrate: http://jsfiddle.net/brendaz/t4v8nhoq/
var marker1 = new google.maps.Marker({
position: new google.maps.LatLng(54.975, -2.020),
map: map,
zIndex: google.maps.Marker.MAX_ZINDEX + 1,
optimized: false
});