My favorites | Sign in
Project Home Issues
New issue   Search
for
  Advanced search   Search tips   Subscriptions
Issue 1651: mousemove / mouseover / mouseout for map canvas
37 people starred this issue and may be notified of changes. Back to list
Status:  Fixed
Owner:  ----
Closed:  Feb 2010


Sign in to add a comment
 
Reported by [email protected], Sep 2, 2009
Please add:

    mousemove
    mouseover
    mouseout

events for the map canvas for independent mouse tracking.

Sep 2, 2009
#1 d.l%[email protected]
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.
Status: NeedsMoreInfo
Sep 3, 2009
#2 [email protected]
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
#3 d.l%[email protected]
OK, we'll consider it.

Thanks!
Status: Acknowledged
Labels: Internal-2101808
Sep 30, 2009
#4 [email protected]
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
#5 [email protected]
Please include the following Events in the v3 API that were present in v2

- loaded
- moveend
Oct 13, 2009
#6 d.l%[email protected]
@5

Have you tried using the 'idle' event?  This should replicate the events you named.
Oct 13, 2009
#7 [email protected]
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
#8 [email protected]
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
#9 [email protected]
Berry, I agree; this would be sufficient and would simplify the code.

Paul.
Oct 24, 2009
#10 [email protected]
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
#11 andre.tannus
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
#13 [email protected]
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
#14 [email protected]
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
#15 [email protected]
A am looking for a REAL mousemove event handler returning Lat/Lon coordinates, not
some pathetic kludge.

Dec 2, 2009
#16 [email protected]
Amen, brother!
Dec 2, 2009
#17 [email protected]
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
#18 [email protected]
Easy now, gentlemen, easy now.  No need for kludge calling.
Dec 2, 2009
#19 [email protected]
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
#20 [email protected]
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
#21 [email protected]
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
#22 [email protected]
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
#23 [email protected]
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
#24 [email protected]
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
#25 [email protected]
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
#26 [email protected]
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
#27 [email protected]
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
#28 [email protected]
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
#29 [email protected]
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
#30 [email protected]
Please put this feature back. It would save a lot of headache.
Feb 2, 2010
#31 [email protected]
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
#32 [email protected]
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
#33 [email protected]
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
#34 [email protected]
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
#35 [email protected]
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
#36 [email protected]
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
#37 [email protected]
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
#38 [email protected]
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
Project Member #39 [email protected]
(No comment was entered for this change.)
Status: Fixed
Labels: Fixed-29
Nov 15, 2013
#40 [email protected]
How was it fixed? How to get notiifed when these events are thrown?
Sign in to add a comment

Powered by Google Project Hosting