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.
Related
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);
}
});
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).
I am trying to make tabs using js to have more data on the site.
Please view: http://dev.ateo.dk/officelab-konferencecenter/
The two tabs at the top ("Billeder" and "kort") are made using js.
If i go into the tap called "kort", the google maps will not load completely - however if i right-click and choose "Inspect Element (Q)" using firefox, the map suddenly loads.
Also, the map is not centered. on the specific location - the location is in the top left corner.
You may notice a blank square below the tab div. This is the exact same code as used within the js tab. If i comment out the in js tab, the square which is blank, will work perfectly. So it somehow seems that the js tab combined with the js google maps are not working. Can this be the case, and if so, how is it fixed?
Below i am showing the code which will init the google maps and the taps on the page:
if($('body.single-konferencested').length > 0)
{
tabs();
}
if($('body.single-konferencested').length > 0)
{
$(document).ready(function() {
function initialize() {
var myLatlng = new google.maps.LatLng(place_lat,place_lng);
var mapOptions = {
zoom: 9,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('gmap'), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
clickable : true
});
var pinIcon = new google.maps.MarkerImage(
"http://dev.ateo.dk/wp-content/themes/ateo/img/pin_marker.png",
null, /* size is determined at runtime */
null, /* origin is 0,0 */
null, /* anchor is bottom center of the scaled image */
new google.maps.Size(24, 40)
);
marker.setIcon(pinIcon);
var content_string = '<div id="gmap_info">'+
'<div id="siteNotice">'+
'</div>'+
'<h3 id="firstHeading" class="firstHeading">'+place_title+'</h3>'+
'<div id="bodyContent">'+
'<p>'+place_address+'<br />'+place_city_zip+'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: content_string
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
});
}
This following is the html showing the DOM for the "Kort" tab:
<div class="tabContent" id="kort" style="padding: 5px 10px;">
<h2>Kort</h2>
<div id="gmap" style="width: 600px; height: 400px;"></div>
<h2>test</h2>
</div>
Best regards
Patrick
If the div in which the map is going to live is not visible on page load the map will not load correctly. You should fire a resize once the div has come into view.
google.maps.event.trigger(map, 'resize');
You should bind this to the first click of the map tab.
It looks like the map is commented out of the second tab currently. If you could uncomment it it would be easier to help you more specifically!
EDIT:
to bind the function once, try this:
var tab = jQuery('ul#tabs li')[1]
jQuery(tab).one('click', function(){
google.maps.event.trigger(map, 'resize');
});
In order for the resize to work you will need access to the map variable from your init function.
It would also be easier to select the correct tab if you drop a class on it. That would be more reliable then getting the 2nd li in the tabs ul.
EDIT 2:
try adding the click function in your initialize code. Something similar to the following
var mapOptions = {
zoom: 9,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('gmap'), mapOptions);
//add the code here, after the map variable has been instantiated
var tab = jQuery('ul#tabs li')[1]
jQuery(tab).one('click', function(){
google.maps.event.trigger(map, 'resize');
//fire a center event after the resize, this is also useful
// if bound to a window resize
map.setCenter(myLatlng)
});
//end of new code
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
clickable : true
});
It can be solved easily by re-initialize the Google Map on Tab click.
$('#kort').click(function(e) {
initialize();
resetMap(map);
});
This simple solution has found from here - How to Display Google Map Inside of a Hidden Div
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
});
}
});
}
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.