OpenLayers3 - Animated .fit to a specific extent - javascript

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())

Related

LeafLet pan and zoom behavior

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.

Mouse movement parallax on Google Map?

Is it possible to add something like this to Google Maps?
This demo has parallax with multiple layers, I would need only one
for map itself.
I don't nessessarily need the code because there are few tutorials how to achieve mouse movement parallax. Im more interested how to apply this to Google Maps.
My current ideas / questions?
Would it be somehow possible to move map tiles in the background without moving Google logo?
If not, how to make map bigger (out of browser viewport) without messing up tiles so that I could move whole map and use overflow { hidden; }?
Don't worry about hiding Google's credentials or messing up controls, I could add all the divs, controls and logo myself via JS.
I would be very grateful if you used my provided jsFiddle example to make your point.
You can do this using the panTo() function. I gave it some default numbers for the scroll effect that you can change to meet your needs.
$( "#map-cover" ).on( "mousemove", function( event ) {
var newLatlng = new google.maps.LatLng(
myLatlng.lat() + event.pageY / 1000,
myLatlng.lng() + event.pageX / 1000)
map.panTo(newLatlng);
});
Make sure to add a div above the map and disable the controls on the map
Updated JSFiddle
Upon, getting additional clarification, you can add a listener to check if the map is being dragged.
map.addListener("drag", function() {
dragging = true;
});
map.addListener("dragend", function() {
dragging = false;
});
Draggable map with mouse scroll

How to dynamically adjust zoom in Heatmap.js in OpenLayers

Consider the following code:
heatmap = new OpenLayers.Layer.Heatmap( "Heatmap Layer", map, osm,
{visible: true, radius: radiusForScale[zoom], legend: {position: 'br',title: 'title'}},
{isBaseLayer: false, opacity: 0.3, projection: new OpenLayers.Projection("EPSG:4326")}
);
Background: heatmap.js is great for displaying population densities and such... however, I do not want heatmap.js to control the radius of my points. Instead, I wish to dynamically updated the radius based on a custom zoom function I have created, without having to destroy the heatmap and recreate it every time the zoom changes. Now, this is possible if you add the heatmap to a div as follows:
var config = {
element: document.getElementById("heatmapArea"),
radius: 30,
opacity: 50
};
//creates and initializes the heatmap
var heatmap = h337.create(config);
In this example, it's as simple as updating the JSON object and updating the display. However, this in only a static display assigned to a div, and therefore renders the vector layer useless. Has anyone had any success with this in OpenLayers??
On a side note: I've browsed through all the keys in the heatmap JSON string and there doesn't seem to be a way to change the zoom variable.
Figured it out... this isn't advertised in the documentation or anywhere on the internet that I could find.. however, here's how you control the radius in OpenLayers for those of you who need it. Let's keep it simple..
// create our heatmap layer
var heatmap = new OpenLayers.Layer.Heatmap(
"Heatmap Layer", map, osm, {visible: true, radius:50},
{isBaseLayer: false, opacity: 0.3, projection: new OpenLayers.Projection("EPSG:4326")}
);
map.addLayers([heatmap]);
Now add the data:
heatmap.setDataSet(data);
Here's the key. You can do pretty much anything with this list of commands:
this.set("radius",value); //****this one solved my problem
this.set("element",value);
this.set("visible",value); //deceiving! You have to access the canvas subclass to get it to work
this.set("max",value);
this.set("gradient",value);
this.set("opacity",value);
this.set("width",value);
this.set("height",value);
this.set("debug",value);
So, for example, create a zoom event so the radius changes based on your radius function. For me, it was as simple as scaling the radius based on the ratio screen width(pixels)/screen width(meters). So now in your click event:
on zoom change: //pseudocode
canvas = heatmap.heatmap.get('canvas'); //this is the subclass I spoke of above
if the zoom is above a certain value //pseudocode
then
canvas.style.display = 'block'; //show the heatmap... you can also use heatmap.toggle() but this gives you more control
heatmap.heatmap.set('radius',zoomfunction[map.zoom]); //this dynamically updates the radius!!
heatmap.updateLayer();
else
canvas.style.display = 'none';
heatmap.updateLayer();
I hope this helps someone 'cause it drove me crazy!

is there a way to resize marker icons depending on zoom level in leaflet?

I'm making a project for the school and I need to resize the marker icons depending on zoom level in a leaflet map, Is there an easy way to accomplish this? Any tutorial on the web? Thanks in advance for the help!!!
In order to change the size of the markers when you zoom in/out, you'll need to handle the event.
map.on('zoomend', function() { });
The zoomend event will be called whenever the map has finished zooming in or out. See the API here.
Now, inside this function, you can call your custom code in order to change the size of the markers. For example, let's say you wanted to take a simple approach and set the size of a circle marker equal to the size of the maps zoom level. See the API for a CircleMarker here
// Create some marker that will be resized on the map zooming
var myMarker = new L.CircleMarker([10,10], { /* Options */ });
map.on('zoomend', function() {
var currentZoom = map.getZoom();
myMarker.setRadius(currentZoom);
});
Now whenever the map zooms in or out, the size of the marker will change.
I'm not sure what Stophace is referring to regarding circleMarkers not changing size, but, adding to the approved answer... if you want to resize circleMakers or change any other styling options (I find it helpful to change the weight along with radius), you can use the following approach:
map.on('zoomend', function() {
var currentZoom = map.getZoom();
var myRadius = currentZoom*(1/2); //or whatever ratio you prefer
var myWeight = currentZoom*(1/5); //or whatever ratio you prefer
layername.setStyle({radius: myRadius, weight: setWeight});
});
layername will be replaced with the name of whatever layer you have which contains circleMarkers... and of course you can change the fractions to your liking to suit your needs.
I'm guessing the OP's school project is finished, but I hope this helps others who have the same question!

leaflet.js Zoom to Clicked Feature and then Pan to the Right

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]});

Categories

Resources