| Issue 1651: | mousemove / mouseover / mouseout for map canvas | |
| 37 people starred this issue and may be notified of changes. | Back to list |
Please add:
mousemove
mouseover
mouseout
events for the map canvas for independent mouse tracking.
Sep 3, 2009
I have tried but my event handlers conflict with yours. The pixel arithmetic is messy. It requires an additional OverlayView for the "fromPixelToLatLon" conversion. You already have the same information for "click" & "dblclick" event handlers. The browsers measure pixel offsets differently. Internet Explorer measures pixel offsets relative to the parent DIV. Firefox measures pixel offsets relative to the DIV containing the corresponding tile. An extra DIV is required in order to simplify the Firefox arithmetic. Unfortunately, it covers your click layer which causes it to fail.
Sep 4, 2009
OK, we'll consider it. Thanks!
Status:
Acknowledged
Labels: Internal-2101808
Sep 30, 2009
The pixel arithmetic is not trivial. Browser differences must be accommodated.
Look at:
http://www.polyarc.us/polycluster/event.html
It is a lot of work just to track mouse coordinates. It is incompatable with your
event listeners.
Oct 9, 2009
Please include the following Events in the v3 API that were present in v2 - loaded - moveend
Oct 13, 2009
@5 Have you tried using the 'idle' event? This should replicate the events you named.
Oct 13, 2009
Berry, I starred this request; I also implemented an event handler that seems not to have some of the issues you listed in your post: http://notebook.kulchenko.com/maps/gridmove. The pixel arithmetic is still not trivial, but it seems like you and I would still need to do our own calculations as it's unlikely that the API will report pixel coordinates we both need to support canvas tiles. Paul (http://notebook.kulchenko.com/maps/)
Oct 14, 2009
Hi Paul, Both you & I are doing way too much work for what was trivial with the old API. I will be happy with a browser independent way to obtain "mousemove" Lat/Lon coordinates without adding an OverlayView. Conversion back to pixels is easy. I am trying to avoid extracting information directly from the DOM which might change. Berry
Oct 14, 2009
Berry, I agree; this would be sufficient and would simplify the code. Paul.
Oct 24, 2009
Ben / Pamela, What is the status ? Anything on the horizon ? Both Paul K & I have had to kludge something together. The pixel arithmetic is nasty. Browser dependencies cannot be avoided. An OverlayView is required just to obtain the the tile offsets. It is difficult to coexist with your other event handlers.
Nov 20, 2009
We're rewriting our app for V3 for our new version launch. We make constant use of the mousemove event, and it is pretty much the main reason we cannot bring the system fully into the V3 API. Does anyone have any idea of the timeframe for this (and other) events to be implemented into the API? Also, I can't help wondering: Why were they taken off in the first place?
Dec 1, 2009
No need to get the offset from the browser and do pixel conversions, just draw a
transparent polygon over your map and use the mousemove listener on the polygon. Each
time the idle event occurs on the map, redraw your polygon. The only limitation is
that you can't zoom out beyond level 3 unless you add some functionality for drawing
polygons that span 180+ degrees (which wouldn't be too difficult).
=================================================
Code:
=================================================
var map = new google.maps.Map();
var mapPolygonOverlay = null;
google.maps.event.addListener(map, 'idle', function()
{
// Delete the previous mapPolygonOverlay if it exists
if (mapPolygonOverlay != null)
{
var mapPolygonOverlayVertices = mapPolygonOverlay.getPath();
// Remove all the points from the polygon
for (var i = mapPolygonOverlayVertices.length; i >= 0; i--)
{
mapPolygonOverlayVertices.removeAt(i);
}
}
// Draw a polygon that is the map bounds
var mapBounds = map.getBounds();
var NE = mapBounds.getNorthEast();
var SW = mapBounds.getSouthWest();
var NW = new google.maps.LatLng(SW.lat(), NE.lng());
var SE = new google.maps.LatLng(NE.lat(), SW.lng());
var mapPolygonOverlayPaths = [NE, NW, SW, SE];
mapPolygonOverlay = new google.maps.Polygon({
paths: mapPolygonOverlayPaths,
strokeColor: '#000000',
strokeOpacity: 0.0,
strokeWeight: 0,
fillColor: '#000000',
fillOpacity: 0.0
});
mapPolygonOverlay.setMap(map);
// Add mousemove listener to polygon
google.maps.event.addListener(mapPolygonOverlay, 'mousemove', function(event)
{
updateMouseLocation(event.latLng);
});
});
google.maps.event.addListener(map, 'zoom_changed', function()
{
if(map.getZoom() < 3)
map.setZoom(3);
});
Dec 1, 2009
For anyone interested, here is the code to allow for zooming out all the way. Just
add it right before you create your new google.maps.Polygon().
=================================================
Code:
=================================================
if(map.getZoom() == 2)
{
var NC = new google.maps.LatLng(NW.lat(), map.getCenter().lng());
var SC = new google.maps.LatLng(SW.lat(), map.getCenter().lng());
mapPolygonOverlayPaths = [NW, NC, NE, SE, SC, SW];
}
else if(map.getZoom() == 1)
{
NW = new google.maps.LatLng(NW.lat(), -180.0);
NE = new google.maps.LatLng(NE.lat(), 180.0);
SW = new google.maps.LatLng(SW.lat(), -180.0);
SE = new google.maps.LatLng(SE.lat(), 180.0);
var NC = new google.maps.LatLng(NW.lat(), 0.0);
var SC = new google.maps.LatLng(SW.lat(), 0.0);
mapPolygonOverlayPaths = [NE, NC, NW, SW, SC, SE];
}
Dec 2, 2009
A am looking for a REAL mousemove event handler returning Lat/Lon coordinates, not some pathetic kludge.
Dec 2, 2009
Amen, brother!
Dec 2, 2009
Berry, I'd like an official Map event handler from Google as well, but for now, mine is the best solution. You might call it pathetic kludge, but at least it works in all browsers--yours does not. I'd say mine is the only non-pathetic kludge on this page.
Dec 2, 2009
Easy now, gentlemen, easy now. No need for kludge calling.
Dec 2, 2009
Sorry - tlc. I realize mine is a kludge. I called it such in comment #10. I was
not aware it did not work in some browsers.
Please tell me in which browsers it fails:
http://www.polyarc.us/polycluster/event.html
Thanks very much.
Dec 3, 2009
The mouse location does not work in Google Chrome or Safari. Yours is dependent on the mouse's location from the left and top of the browser so when you stretch the window horizontally, you will notice that the longitude values are further and further away from what they are supposed to be. Or, if you scroll down the page slightly, you will notice the latitude values are further and further away from what they should be. This is due to the extra space between your mouse and the left/top of the browser window. Additionally, your map does not seem to pan correctly in any browser (IE7, Google Chrome, Opera, Safari or Firefox) when using the mouse drag. I'm not sure if this is due to some div you have placed over the map, but it is interfering with that in a big way. Hopefully, the next API v3 release update will include the map events we're looking for.
Dec 3, 2009
I'm using a similar approach, although I calculate the position differently. I wonder if my solution suffers from the same issues: http://notebook.kulchenko.com/maps/gridmove
Dec 3, 2009
Thanks very much TLC & Paul. I know my mouse events are incompatable with Google's. Double click & drag will both fail. Single click will center the map without changing the zoom level which is deliberate. It is easy enough to zoom. Doing it automatically on every double click is really annoying. I was not aware of the Chrome / Safari issues. I have neither installed. Your approach is a good band-aid solution but Google ought not to dismiss the issue. I prefer not to load the poly support JS files if I do not have to. I have my own poly facilities which lack the bells & whistles of Google's polys but which improve on performance (both size & speed). If you have other polys, I believe you will have to be careful to establish the zIndex order correctly to prevent chaos. I trust Google is listening. Three experienced developers are struggling to implement a very trivial V2 feature in V3. It ought to be a half day development effort for Google. It is very frustrating not to have such a basic capability available.
Dec 3, 2009
Paul, Indeed it does suffer the same issues. I tore yours apart and re-built it myself to see if your solution would work for me and the effects of stretching the browser and scrolling down were very much prevalent. Yours works if the map spans the entirety of the browser, but my application places a much smaller map on a page full of other information and controls. Thus, my map is not at the top left of the window, its location changes depending on browser width, you can scroll up and down, moving the location of the map in relation to the top of the window, and the content around the map grows/shrinks, modifying the map's location; therefore, coordinates were quite a ways off from what they should have been. I could have written an offset handler to grab the scroll value and measure where the map div is at any given time, but it seemed like a lot of extra work and a lot more possibilities where a slight change in the way a browser handles padding and margins would destroy the whole system. I've tested my solution in Google Chrome 3.0.195.33, IE 7-8, Firefox 3.5.5, and Safari 4.0.4. It works exactly as it should in all of them. The only one it does not work in is Opera 10.10 (though this is a problem with Google Maps itself -- e.g. https://code.google.com/apis/maps/documentation/v3/examples/polygon-simple.html -- because Google Maps uses JavaScript code that is not W3C-compliant and Opera is all about being W3C-compliant). I believe my solution _would_ work in Opera 10.10 if Google Maps itself worked in Opera 10.10. Thus, I submit my solution as the best answer to this problem until Google officially releases the functionality. Hopefully it can help you guys until such a day comes. Good luck!
Dec 3, 2009
Berry, I agree Google should provide these map events. It is definitely frustrating upgrading to v3 to find that something so trivial was lost. I do actually draw additional polygons in my application (using them to define search criteria for satellite imagery). The polygons all draw perfectly and all mouse events occur exactly as they should without any hacking of z-index or the like. The only thing I had to do was add a mousemove event listener to any additional polygons the user draws on top to make sure that while their mouse is over said polygons, the mouse location is still being updated. This was simple, however. It was 1 line of code--literally just adding a listener.
Dec 5, 2009
Hi Paul, I believe both you & I are failing to make adjustments for the map being resized. If you & I replace our "idle" event listeners with "bounds_changed" event listeners, it ought to help. I have another little suggestion. If you add the diameter of your dot in pixels to the "style.width" & "style.height" of each CANVAS element & subtract the radius of your dot in pixels from the "style.top" & "style.left" of each CANVAS element, the dot will not be clipped at the edge of the CANVAS element. Your tiles will overlap but will be transparent except for the dots. Each dot will be contained in exactly one tile rather than split across adjacent tiles. Also, you can add your own properties to your DIV elements containing your CANVAS elements. If you do, you will not have to extract browser dependent offsets from Google's DIV elements. If you have just one dot, it might make sense to abandon the use of tiles. Instead, the dot can reside in its own CANVAS element which you can reposition. For what it is worth, a map "mousemove" event listener must be REALLY FAST. I am reluctant to build anything relying on a poly "mousemove" event listener which requires several tiled CANVAS or SVG or VML elements plus a large JS support file.
Jan 14, 2010
Hi TLC I've got a thing with your sample up and working pretty well. Now my problem is that events on the mapPolygonOverlay, are not registrered when i am at/over a marker. I need to track lat/lng of the mouse position, even when i move the mouse over a marker. I guess mapPolygonOverlay is at a lower z-index than the marker, but i can't find a way to change this. Do you have any ideas for a work around or am i missing something? Thanks.
Jan 16, 2010
You could add a 'mouseover' event listener to the marker itself and return the LatLng of the marker when it fires. If that does not suffice, the Marker class does have a method setZIndex(zIndex:number) that you may want to look at. I'm not entirely sure it will allow you to place your marker behind the polygon, though.
Jan 16, 2010
yeah, i did look into that, but it only fires once, so it doesn't continously update the lat-lng position. I've also tried playing around with the setZIndex of the marker, but with no luck, which makes sence when i look at the map pane documentation here: https://code.google.com/apis/maps/documentation/v3/reference.html#MapPanes What is interesting is how mousemove would work if they added it for the map canvas as this issue suggests. I haven't played around with v2, but does anyone know if the mousemove event on the map canvas there returns anything when a marker is hovered?
Jan 17, 2010
I do. The mousemove event on the canvas does return the LatLng even when over a marker (though I've only tested it with non-clickable markers). You may want to look in to using v2 for now until Google can implement this in v3. But you should ask yourself, is the tiny area underneath the marker that important to update the LatLng on?
Jan 29, 2010
Please put this feature back. It would save a lot of headache.
Feb 2, 2010
We've held off implementing this so far because we were concerned that projecting pixel coordinates to LatLng (and creating LatLng objects) on mouseover would bog down slow browsers. But clearly this is highly desired so we're looking into it now. Ben
Feb 2, 2010
Sorry, I meant mousemove not mouseover. I've seen a browser fire mousemove *multiple times per pixel* that the mouse moves over, and that same browser bogged down when I created 1 object per mousemove. We may compromise by throttling the mousemove events.
Feb 3, 2010
If the coordinates have not changed since previous "mousemove", do nothing. If the user has not registered an event listener for "mousemove", do nothing.
Feb 6, 2010
I am rather disappointed that the "mousemove" event returning a LatLng in not available. Its was in v2 ;-)))))))))))))))))))))))))))) I want to upgrade.
Feb 6, 2010
Please do not throttle the "mousemove" event handler unless you also provide an option to disable the throttle. The purpose of the "mousemove" event handler is to provide quick feedback for changing the cursor, for tool tips, for other uses requiring instantaneous feedback. If each mouse movement must be approved by some black box timing mechanism, it is essentially worthless. If you must constrain it, I will implement my own. Abandoned function closures cause memory leakage. A well constructed event handler can run all day without memory leakage.
Feb 6, 2010
Clearly V2 is able to implement a "mousemove" event handler without throttling. If V3 must impose an arbitrary throttle, I will not use it. Wasteful function closures are the issue, not the number of times the function is called. By the way, functions closures are a horrible way to implement any event listener.
Feb 6, 2010
If others agree throttling is a mistake, please let your opinions be known. Otherwise, you will be stuck with an unresponsive "mousemove" event handler which will be essentially worthless.
Feb 8, 2010
I don't seem to see your point about the throttling @[email protected]. Do you realize how small a pixel is? It is the smallest unit of measurement that your monitor can display. No matter what you are doing, you shouldn't be requiring events to fire multiple times on a single pixel because there will be no change. If the issue is tool tips, it will be more common for tool tips to be done on markers, polygons, and other DOM objects being displayed on the map. The most common use of these events are to display the coordinates of where the mouse is located on the map, not some complex tool tip. The developers at Google should be more concerned about meeting the needs of the majority of developers because if they accommodated every request nothing would get done. If they choose to implement throttling and you don't like that, maybe once some more of the core functionality comes out you can request the option for an event that doesn't use throttling. But for now let's just let them come out with something...however they decide to implement it. At this point the concern is simply getting something out there so we can get our apps ported over.
Feb 26, 2010
(No comment was entered for this change.)
Status:
Fixed
Labels: Fixed-29
Nov 15, 2013
How was it fixed? How to get notiifed when these events are thrown? |
|
| ► Sign in to add a comment |
Can you track these events by assigning event listeners on the map container? For example: google.maps.event.addDomListener('map_canvas', 'mousemove', function(e) { // code here }); Granted, it'll take a bit more code on your end to determine whether the mouse is within map container boundaries, but this seems like a feature you can add yourself.