Enable scrollwheel zooming on a map upon click using Google Maps API - javascript

I am using the Google Maps API, and wanted to be able to scroll past the map on a mobile device and not have the map zoom when scrolling down a webpage using the scrollwheel.
Here's my code:
var mapOptions = {
center: new google.maps.LatLng(51.605139, -2.918567),
zoom: 15,
scrollwheel: false,
draggable: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
This is fine but what I would like to achieve is to enable scrollwheel zooming only when the map was clicked.
(So on a webpage, when I click the map, I can zoom on it, or a mobile device, when I tap the screen on, then I can pinch and zoom/drag the map around.)
Can I add an event listener to activate draggable only upon double click or single click?
Is it possible using the API?
EDIT
I have tried the following code, but it doesn't seem to work:
google.maps.event.addListener(map, 'click', function (event) {
var mapOptions = {
draggable: true,
};
});

This should work:
google.maps.event.addListener(map, 'click', function(event){
this.setOptions({scrollwheel:true});
});

google.maps.event.addListener(map, 'mouseout', function(event){
this.setOptions({scrollwheel:false});
});
this is a handy little consideration in addition to Dr.Molle's answer.
just as it appears, this will re-disable scrollwheel zooming when the mouse leaves the map.

This is what I generally do:
User interacts with the map (mousedown) -> set zoomable
Mouse rests on the map for over 1 second -> set zoomable
Mouse goes out of the map -> set not zoomable
This usually gets the work done. When the user is in the mindset of scrolling the page, the map follows.
When the user wants to zoom in/out they need to interact with it or have the pointer there for a short while.
The source code:
google.maps.event.addListener(map, 'mousedown', function(event){
this.setOptions({scrollwheel:true});
});
google.maps.event.addListener(map, 'mouseover', function(event){
self = this;
timer = setTimeout(function() {
self.setOptions({scrollwheel:true});
}, 1000);
});
google.maps.event.addListener(map, 'mouseout', function(event){
this.setOptions({scrollwheel:false});
clearTimeout(timer);
});

I found a solution and gathered complete code for disabling scroll on load and enable scroll zoom on click.
Disable scroll on load: scrollwheel: false,
Listen to click event on map and enable scrollwheel: true,
map.addListener('click', function() {
map.set('scrollwheel', true);
});
Please find the code in my blog: http://anasthecoder.blogspot.ae/

According to official google documentation, to make it work perfectly fine for mobile and website use this:
var map = new google.maps.Map(document.getElementById(mapid), {
gestureHandling: 'greedy',
});

This is my example and it works for me. When page loads, google map (wheel scroll) is off, when you click on map (wheel scroll) turned on.
var map = new google.maps.Map(document.getElementById('map-id'), {
scrollwheel: false,
});
google.maps.event.addListener(map, 'mouseout', function(){
this.setOptions({scrollwheel:false});
});
map.addListener('click', function() {
map.set('scrollwheel', true);
});

this will set map, on click of map if the scrollwheel value is false it will make it true, & if true will make false.
function initMap() {
var florida = {
lat: 27.5814346,
lng: -81.0534459
};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: florida,
scrollwheel: false
});
google.maps.event.addListener(map, 'click', function(event) {
if (this.scrollwheel == false) {
this.setOptions({
scrollwheel: true
});
} else {
this.setOptions({
scrollwheel: false
});
}
});
}

Related

Google Maps losses mousemove Event Listener after simultaneous dragstart and dragend events

I am working over a Google Map API application, but I got into a bug where mousemove event listener is lost after a mousedown event. It restores activity if the map is dragged or zoomed. Please check this simple example here, where the problem can be replicated after you click on the map for a while:
https://jsfiddle.net/dninov81/95ybk1wt/31/
let map;
let marker;
const textField = document.getElementById('text')
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {
lat: 52.50871874907,
lng: 6.2503252411254
},
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 15,
})
map.addListener( 'mousemove', onDrawMove);
map.addListener( 'mousedown', onDrawDown);
}
initialize();
function onDrawMove(e) {
textField.innerHTML = e.latLng
}
function onDrawDown(e) {
textField.innerHTML = e.latLng
if(marker) {
marker.setMap(null)
}
marker = new google.maps.Marker({
position: e.latLng,
map: map
});
marker.setMap(map);
}
Here is a record of the problem, where when mouseover listener is active we can see the coordinates are correctly displayed in the text field and once it stops, only the mousedown event is registered. After a zoom change the mouseover event resumes.
https://youtu.be/gb3A83g4Qt0
If anyone experience similar behavior I would like to know why is this?
UPDATE:
We managed to isolate the problem and it accurses when dragstart and dragend events are fired simultaneously due to fast clicking sometimes. Still the problem persist it also occurs in google official event handling tool here:
https://developers.google.com/maps/documentation/javascript/events
It turns out it is a known bug and here is the solution from the issue tracker:
var dragStartCenter = null;
google.maps.event.addListener(map, "dragstart", function() {
dragStartCenter = map.getCenter();
});
google.maps.event.addListener(map, "dragend", function() {
if (dragStartCenter && dragStartCenter.equals(map.getCenter())) {
// execute panBy() if the map has not been moved during dragging.
map.panBy(0, 0);
}
});

Why have I click twice on a marker on FireFox? [duplicate]

I have a map, and I draw a rectangle on it. Here is what I want: whenever my mouse enter that rectangle, open an infowindow, when my mouse leave, close the infowindow.
I have successfully created a map and drawn a rectangle. Here is my code:
var map;
function initialize() {
// Init map
var mapOptions = {
center: { lat: ***, lng: *** },
zoom: 13,
draggable: false,
scrollwheel: false,
zoomControl: false,
streetViewControl: false,
mapTypeControl: false,
disableDoubleClickZoom: true
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
drawGrid();
});
} // end initialize
function drawGrid() {
var rectangle = new google.maps.Rectangle({
strokeColor: '#000',
strokeWeight: 2,
fillOpacity: 0,
map: map,
bounds: new google.maps.LatLngBounds(sw1, ne1) //sw1 and ne1 is my variable
});
var infowindow = new google.maps.InfoWindow({
content: "Hello",
position: rectangle.getBounds().getCenter()
});
google.maps.event.addListener(rectangle, 'mouseover', function () {
infowindow.open(map);
});
google.maps.event.addListener(rectangle, 'mouseout', function () {
infowindow.close();
});
}
google.maps.event.addDomListener(window, 'load', initialize);
You can see the result below. The rectangle is the black one.
Now, the problems are:
Mouseover event is fired only when I let my mouse follow the green arrows.
Mouseout event is fired only when my mouse follow the green arrows (yes, from out to in, not in to out as expected), and it's fired twice.
Why do I encounter those problems? What did I do wrong? How to solve this problem? Thank you so much for your help.
There was a change to the way Firefox 39.0 handles mouse events. See issue 8278 in the issue tracker
Project Member #4 enoch...#google.com
Thanks for reporting this issue. Indeed, it appears that Firefox 39 has made changes to its mouse event, which is causing the API to behave incorrectly.
Status: Accepted
Owner: enoch...#google.com
Labels: Internal-20820906
Note that users have reported that v=3 (the release version) is working correctly and this issue only appears in v=3.exp (the "experimental" version).

Google maps - keep center when zooming

In Google Maps, I would like to be able to keep the center of the map on a marker on my location when I'm zooming in or out. It's something that Ingress does, it doesn't matter where you double tap (or double click) or where you pinch, the map remains centered on your marker. So it's possible...
The best I came up with for now is :
google.maps.event.addListener(mymap, 'zoom_changed', function() {
mymap.setCenter({lat: myLoc.lat, lng: myLoc.lon});
})
But it's far from perfect, it just re-center the map after the user already zoomed...
Thanks a lot !
[EDIT] absolutely nothing helps in the API ref... Or elsewhere I'm blind and missed it !
Purely using Javascript
First you disable scroll zoom function by default of google map by scrollwheel=false,
Next create custom scroll zoom function by capture mouse event and set zoom level for google map
Check my sample code: Fiddle URL: https://jsfiddle.net/vh3gqop0/17/
var map, i = 12;
function initialize() {
var myLatlng = new google.maps.LatLng(46.769603, 23.589957);
var mapOptions = {
center: myLatlng,
zoom: i,
scrollwheel: false,
disableDoubleClickZoom: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Any Title'
});
}
google.maps.event.addDomListener(window, 'load', initialize);
$( document ).ready(function() {
$('#map_canvas').on("wheel", function(evt){
// console.log(evt.originalEvent.deltaY);
if(evt.originalEvent.deltaY > 0){
map.setZoom(++i);
}else {
map.setZoom(--i);
}
});
});
#map_canvas{
height:400px;
width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<div id="map_canvas"></div>
I have no idea why you tagged this question as both Javascript and Android. On Android you need to wrap your MapView inside another view and detect Double Tap motion inside onInterceptTouchEvent which you can override if your class can override FrameLayout for example. Then return true to prevent the map from handling this event and you handle it instead.
For full code please see my answer here: https://stackoverflow.com/a/30118649/764897
Unfortunately Google Maps Api does not provide this behaviour.
The following example doesn't require jQuery and supports double-click and mouse scrolling, but you can add more events if you want.
View in Codepen
Disable:
Double-clickin
Scrolling
Panning
Add dblclick and zoom_changed events on the map and a mousewheel event on the canvas.
I have commented the code, hopefully this works for your case. Keep in mind that you need to normalize mousewheel speed for all browsers and devices. Hammer.js is a good library for that.
var map, zoom;
function initialize() {
// The white house!
var myLatLng = new google.maps.LatLng(38.8977, -77.0365);
// Default zoom level
zoom = 17;
// Keep a reference for evens
var $map = document.getElementById("map");
// Disable scrolling + double-click + dragging
map = new google.maps.Map($map, {
zoom: zoom,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
disableDoubleClickZoom: true,
//draggable: false
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map
});
// EVENTS
// Double Click: event zoom by 1
map.addListener('dblclick', function(e) {
zoomHandler(e.latLng, 1);
});
// Zoom changed: update current zoom level
map.addListener('zoom_changed', function(e) {
// Using a timeout because `getZoom()` does not return a promise.
setTimeout(function() {
zoom = map.getZoom();
}, 50);
});
// Dom event: On mousewheel
$map.addEventListener('mousewheel', wheelEvent, true);
}
// Mouse Scrolling event
function wheelEvent(event) {
if (event.deltaY > 1)
zoomHandler(event, -1);
else
zoomHandler(event, 1);
}
// Zoom in/out
function zoomHandler(event, zoomin) {
zoom += zoomin;
map.setZoom(zoom);
}
google.maps.event.addDomListener(window, 'load', initialize);
#map {
width: 100%;
height: 240px;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC9d3jaUX6Qdr0Uzvq6fQXVmZ1PBuHEVAQ"></script>
You should try the center_changed event with panTo function.
google.maps.event.addListener(mymap, 'center_changed', function() {
mymap.panTo({lat: myLoc.lat, lng: myLoc.lon});
})
You can see an example about it here and documentation about panTo function here.
Becareful, it should mess up all the draggable thing.

Google Maps in Bootstrap Modal. Pan/zoom mouse gestures not working

I recently had the need to place a map in a bootstrap modal, which works fine except for the ability to pan and zoon with mouse interaction. Panning by clicking and dragging the mouse, and zooming by using the mouse wheel does not seem to work.
I have put up an example of the problem. (I have only tested it in Chromium and Firefox, on Kubuntu)
http://jsfiddle.net/nG9nu/
$("#myModal").on(
'shown.bs.modal',
function () {
var pos = new google.maps.LatLng(63.43, 10.39);
var mapProp = {
center: pos,
zoom: 14,
draggable: false,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("mapCanvas"),
mapProp);
google.maps.event.trigger(map, "resize");
});
Any ideas what stops the mouse events to reach google maps? Or how to fix this particular problem?
I am very thankfull for all the help I can get :)
var mapProp = {
center: pos,
zoom: 14,
draggable: false,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
I can see
scrollWheel => false
draggable => false
Of course it won't work : set them to 'true'
See this fiddle :http://jsfiddle.net/nG9nu/1/

Adding Event Listener causes Google Map to freeze

I am attempting to create a google map with markers on my page. I have an unordered list where each item has data attributes for latitude, longitude and title. Using JQuery I pull these values and produce a marker on the map for each item in the list. Everything seems to work OK except google maps will not load tiles as you pan around the map.
This is how I initialize the map:
var map;
// initialize google map
$(function () {
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(CoordinatesLat, CoordinatesLong),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
}
// initiate map
map = new google.maps.Map($("#map")[0], myOptions);
// when map is loaded, add events and behaviors to it
google.maps.event.addListenerOnce(map, 'tilesloaded', addEventsToMap(".event")); //commenting this line prevents GMAP problems
});
FYI - before I was using maps.event.addListener() and the map would work momentarily and then become completely unresponsive. Changing it to maps.event.addListenerOnce() stopped the freezing but still has the tile loading problem.
And this is the callback, where evidently I've done something wrong:
//add events from event list to map. add behavior to events ie. mouseover
function addEventsToMap(selector) {
$(selector).each(function (i, $e) {
$e = $($e);
var latlng;
if ($e.attr("data-geo-lat") && $e.attr("data-geo-long")) {
latlng = new google.maps.LatLng($e.attr("data-geo-lat"), $e.attr("data-geo-long"));
$e.marker = new google.maps.Marker({
position: latlng,
map: map,
title: $e.attr("data-title")
});
google.maps.event.addListener($e.marker, 'click', function () { window.location = $e.attr("data-href"); });
google.maps.event.addListener($e.marker, 'mouseover', function () { $e.addClass("event-hover"); });
google.maps.event.addListener($e.marker, 'mouseout', function () { $e.removeClass("event-hover"); });
//when mouse hovers over item in list, center map on it's marker
$e.mouseenter(function () {
map.panTo(latlng);
});
}
});
}
Any idea what could be causing this?
I see a problem, though I'm not sure if it's the issue here. If you examine this line:
google.maps.event.addListenerOnce(map, 'tilesloaded', addEventsToMap(".event"));
What you are intending to do is call your 'addEventsToMap' once the map is loaded, but instead what you are doing is calling the function and then assigning the return value of that as a listener.
You need this instead, and I think it shouldn't crash anymore.
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
addEventsToMap(".event");
});
If that doesn't work, I would recommend looking at the Javascript Console of whatever browser you are using, to see what error is happening to make the map crash.

Categories

Resources