I have put a Leaflet map in JavaFX. There is a problem with the zoom speed. If I zoom in one step, it zooms all the way in to the size of Iceland:
The correct behaviour would be, if it zooms only a little bit in:
If I open the exact same html/js file directly in my browser the zoom works correctly. So the problem has to be in the JavaFX import.
I have included the Leaflet map in JavaFX the following way:
Does any of you know why there is a difference in the zoom level? Can I change my wheel delta somewhere?
I solved the problem by manually zooming in and out after the user touched the mouse zoom:
var handleScroll = function(evt){
if (!evt) evt = event;
var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;
// Use the value as you will
if(direction > 0) map.zoomIn(1);
else map.zoomIn(-1);
};
document.getElementById("map").addEventListener('DOMMouseScroll',handleScroll,false); // for Firefox
document.getElementById("map").addEventListener('mousewheel', handleScroll,false); // for everyone else
Related
I am trying to enable smooth pinch to zoom on mobile devices on my fabric.js canvas. I have a solution that technically works, the problem is that it is very stuttery, the zoom happens in distinct stages, almost frame by frame, so it is not a good experience. It also seems to get worse as time goes on. Is there any way I can make it stutter less and scale more smoothly? I am testing on a good smartphone.
Here is the code:
canvas.on('touch:gesture',function(event) {
if (event.e.touches && event.e.touches.length == 2) {
if (event.self.state == "start") {
zoomStartScale = self.canvas.getZoom();
}
// Calculate delta from start scale
var delta = zoomStartScale * event.self.scale;
// Zoom to pinch point
self.canvas.setZoom(delta);
}
})
I've been trying different tactics with leaflet map to zoom ignoring the default fixed zooming steps of the library, but without any luck so far. Through the following function:
window.addEventListener('mousewheel', function(e){
if (!e) e = event;
var direction = (e.detail<0 || e.wheelDelta>0) ? 1 : -1;
},
false);
I would like to achieve a smooth zooming effect like the one in Google Maps, which tracks the zoom based on deltaY and mouse scroll event. Do you know how to solve this issue or do you know a reference I could look at?
Thanks in advance for your replies!
Set the zoomSnap option of the map to zero. See also the wheelPxPerZoomLevel option.
Please note that fractional zoom is a feature introduced in Leaflet 1.0.0. This means that previous versions are not able to use non-integer zoom levels at all.
I'm currently building a Phonegap app along with Google's Map JS API.
I have a map that you can drag to select your dropoff location. This is accomplished by collecting the map's center geolocation on the "dragend" event. I then set a pin on top of the map (outside of the JS map) so that you know where the center point is.
Everything works fine until you pinch to zoom and the pin is then displaced. This is due to you zooming and dragging the map at the same time when pinching the screen.
Is there any way to prevent dragging on zoom in order to hold the map at its center point?
Please view the JSfiddle here.
var map;
google.maps.event.addDomListener(window, 'load', onMapReady);
function onMapReady() {
var center = new google.maps.LatLng(30.267153, -97.743061);
var mapOptions = {
center: center,
zoom: 13,
styles: [{"featureType": "poi", "stylers": [{ "visibility": "off" }]},{"featureType": "transit","stylers": [{ "visibility": "off" }]}],
disableDefaultUI: true,
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
google.maps.event.addListener(map, 'dragend', function() {
center = map.getCenter();
$('#log').html('Lat: ' + center.lat() + ' Lng: ' + center.lng());
});
}
There are two possible solutions for this issue , from what i have read that you have tried using native marker but it is lagging , which itself is another issue that i have a suggestion for :
use crosswalk for building your app , this will extremely boost your app performance , i have experienced it myself , and was really satisified with results ( iam using intel xdk but i believe this will work for phonegap as well ).
use the UX solution : you feel the marker is lagging because after all it is visible !! i would suggest hiding the marker on drag event start , then showin it back on drag event end.
Third solution which makes sense , is using a pinch detector library like this , this , or even solutions mentioned here , and here , pick whatever works best for you , as performance is a point of concern , and previous solution have to be tried , however once you have detected the pinch gesture , you set the map drag to false , set it back again to true after pinch ends .
I dont usually provide much coding in my solution but rather the correct algorithm to help solving the specified issue.
EDIT: ProllyGeek is right, the zoom_changed event fires after the drag has already happened. You can detect if the touch event was near the center of the map (over your marker) and re-center the map after zooming:
google.maps.event.addListener(map, 'dragend', function() {
if (center && center != map.getCenter()) {
map.setCenter(center);
center = null;
}
});
//we should recenter the map if the click/mousedown was within the centerRadius of the center of the map
google.maps.event.addListener(map, 'mousedown', function(clickMouseEvent) {
var mapDiv = document.getElementById('map');
if (pointInCircle(clickMouseEvent.pixel.x,
clickMouseEvent.pixel.y,
mapDiv.offsetWidth/2,
mapDiv.offsetHeight/2,
centerRadius)) {
//map.setOptions({draggable: false}); //disables zoom and dragging
center = map.getCenter(); //save the current center point so we can recenter later.
}
});
//handy function to see if a x,y coordinate is within z radius of another x,y coordinate
//from https://stackoverflow.com/a/16819053/1861459
function pointInCircle(x, y, cx, cy, radius) {
var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
return distancesquared <= radius * radius;
}
http://jsfiddle.net/bxfn499f/11/
Original Answer:
Did you try setting draggable to false on the map when the zoom event is fired?
google.maps.event.addListener(map, 'zoom_changed', function() {
map.setOptions({draggable: false});
//heavy handed re-enabling of draggable
//setTimeout(function() { map.setOptions({draggable: true}); }, 5000); //cant drag for five seconds
});
You can programmatically re-enable dragging with the mouseup event (which should fire in lieu of the touchend event) or whatever makes sense in your use case (map.setOptions({draggable: true});). For example:
google.maps.event.addListener(map, 'mouseup', function() {
map.setOptions({draggable: true});
});
http://jsfiddle.net/bxfn499f/6/ I tested from a desktop, so I tweaked the fiddle slightly as the map wasn't loading for me - assuming this was due to the window.load not being fired after $(document).ready(function() { ... }. You'll have to see how this behaves if the drag stars before the zoom event.
I have a solution which might work. Assuming you want the map to center back to the pin.
Add custom control div in your map object. The example is here. Instead of the "center map" div in the example, make your pin the controlling div. Listen to dragend event and set the center at pin's position.
Haven't really tested the solution but seems like it will do the trick.
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!
I'm using the latest version of MarkerClusterer with Google Maps API v3 and I think I've found a bug!
My google map minZoom is set to 1. Zooming from level 1 down to any level and back up to 1 is just fine. The bug is seen when I try to zoom out from level 1 to level 0.
When I click to zoom out from level 1 to level 0, the gMap UI doesn't allow the zoom, as intended, but all my markerClusters disappear, they re-appear when I go down to zoom level 2 and come back to level 1.
I've posted this on the Google Group page for Google Maps API v3, but no response so far (been over a week as of today).
Any help is much appreciated!
It's more a bug in the Maps-API than a bug in markerClusterer, but you can fix it in markerClusterer.js
I'm not sure where you click on when you(try to) set the zoom to 0(the issue for me doesn't occur when I use the zoom-control), but it happens when I set the zoom using map.setZoom(0)
The issue: the API reports a zoom of 0, but this is incorrect, because the zoom will be set to 1(the minZoom).
Fix:
Replace this part of marcerclusterer.js:
// Add the map event listeners
var that = this;
google.maps.event.addListener(this.map_, 'zoom_changed', function() {
var zoom = that.map_.getZoom();
if (that.prevZoom_ != zoom) {
that.prevZoom_ = zoom;
that.resetViewport();
}
});
...with that:
// Add the map event listeners
var that = this;
google.maps.event.addListener(this.map_, 'zoom_changed', function() {
var zoom = that.map_.getZoom(),
minZoom=that.map_.minZoom||0,
maxZoom=Math.min(that.map_.maxZoom||100,
that.map_.mapTypes[that.map_.getMapTypeId()].maxZoom);
zoom=Math.min(Math.max(zoom,minZoom),maxZoom);
if (that.prevZoom_ != zoom) {
that.prevZoom_ = zoom;
that.resetViewport();
}
});