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.
Related
I've rendered a d3 map that has pan and zoom enabled, but when scrolling down the viewport either on desktop or mobile, the window gets stuck zooming in the map.
Is there a way to temporarily disable d3.zoom, while the window is scrolling?
I've seen ways of toggling the zoom/pan using a button as seen here: http://jsfiddle.net/0xncswrk/, but I wanted to know if it's possible without having to add a button. Here's my current zoom logic.
Thanks!
this.zoom = d3.zoom()
.scaleExtent([1, 8])
.on('zoom', () => {
this.svg.attr('transform', d3.event.transform);
});
this.svg = d3.select(this.el).append('svg')
.attr('width', '100%')
.attr('height', this.height)
.attr('class', 'bubble-map__svg-us')
.call(this.zoom)
.append('g');
EDIT: Wow old answer but never saw your comment. Sorry about that. Yeah sorry I forgot to consider mobile zooming.
In the documentation, perhaps this is new, but they recommend having more granular control of what zoom you allow by using zoom.filter. For touch related events, they also support zoom.touchable.
As specified in the d3-zoom documentation
To disable just wheel-driven zooming (say to not interfere with native scrolling), you can remove the zoom behavior’s wheel event listener after applying the zoom behavior to the selection:
selection
.call(zoom)
.on("wheel.zoom", null);
You can also consider just setting the scaleExtent to be [1,1] especially if it's just temporary so it locks the zoom to only one possible scale but preferably you opt for what the documentation says :P
Got here because I was dealing with a similar problem. Perhaps for anyone coming after this, a simple way to deal with this might be to use the filter() method that a zoom() instance provides. That will allow you to toggle between applying or ignoring zoom events altogether. It works a little better than temporarily setting null to watchers because - at least in my experience - the events then still get recorded and stacked. As a consequence, you would zoom in or out in unexpected leaps once you re-enabled the handler. The filter actually really ignores what's going on, it seems. To implement:
let isZooming = true; // Use controls to set to true or false
zoom()
// Make sure we only apply zoom events if zooming is enabled by the user
.filter(() => isZooming)
.on('zoom', event => {
// Specify whatever you want to do with the event
});
Doc: https://github.com/d3/d3-zoom#zoom_filter
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
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
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]});
I want to create a jqPlot line chart which has the ability to change orientation between vertical and horizontal orientation. I was able to achieve this using CSS rules, by rotating the div element containing the chart.
My work up to now: http://jsfiddle.net/GayashanNA/A4V4y/14/
But the problem is I also want to track the mouse-pointer and mouse clicks on points on chart after the orientation is flipped because i want to annotate those points. I am unable to do this when the chart is in vertical orientation. Can anyone suggest a method to do this? Or am i approaching the problem in a wrong way?
(Note: I am able to do this in horizontal orientation, you can observe it if you try to click on a point on the above chart.)
Thanks and help is much appreciated.
I've never used jqPlot, but I guess your problem is trying to use css rotate(), since the cursor plugin is using the mouse position to determine where to draw the lines, and element's size doesn't change when transformed by rotate(), it still have the same width and height values.
If you take a look at the code, you will see:
if (c.showVerticalLine) {
c.shapeRenderer.draw(ctx, [[gridpos.x, 0], [gridpos.x, ctx.canvas.height]]);
}
if (c.showHorizontalLine) {
c.shapeRenderer.draw(ctx, [[0, gridpos.y], [ctx.canvas.width, gridpos.y]]);
}
So it seems like the library is always drawing the lines based on mouse position over the original element, which of course, won't match the position after being transformed by rotate(), and XY coordinates are going to be transformed to YX after rotate().
I would try to change the size of your original element, though I don't know if the library lets you specify in which sides are the labels going to be drawn.
I finally found a solution for the problem. But i had to change jqPlot library to achieve this. To help anyone else who run in to the same problem, i'll put my solution here.
First i had to insert the following code in to the jqPlot class of the jquery.jqplot.js file, which is the core library.
function jqPlot() {
//add the following code segment
var verticallyOriented = false;
this.setVertical = function(state){
verticallyOriented = state;
}
//don't change other code that isn't mentioned here
//now you have to change the logic in the getEventPosition function
//to make sure the new orientation is detected
function getEventPosition(ev) {
//change the line starting with var gridPos = ...
//to the following code segment
//depending on the orientation the event position calculating algorithm is changed
if(verticallyOriented){
var gridPos = {x:ev.pageY - go.top , y:plot.eventCanvas._elem.height() - ev.pageX + go.left};
} else {
var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top};
}
//no change to other code is needed
}
}
You can view a working example here: http://jsfiddle.net/GayashanNA/yZwxu/
Gist for the changed library file: https://gist.github.com/3755694
Please correct me if i have done something wrong.
Thanks.