GeoffSchultz
GeoffSchultz

Reputation: 83

GoogleMaps loses mouseUp event if rectangle redrawn in mouseMove event

The following code sample has me baffled. It's the simplest version of a larger piece of code that I can use to demonstrate my problem. Basically I want the user to be able to draw a bounding box by holding down the mouse key and dragging it.

If I redraw the rectange using a setBounds in the mouseMove function, I never see the mouseUp event! If I disable the redrawing of the rectangle in the mouseMove function, I get the mouseUp event. I can partially work around this by drawing the rectangle in the mouseUp event, but then the user can't see the outline as they are dragging the box.

You can see this code sample in action at http://www.geoffschultz.org/Test/bounding_box.html

Here is the code:

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <style type="text/css">
            html { height: 100% }
            body { height: 100%; margin: 0; padding: 0 }
            #mapdiv { height: 100% }
        </style>
        <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript">
            var map, mouseDownPos, gribBoundingBox = "", mouseIsDown = 0;

        function display_map()
        {       
            var latlng = new google.maps.LatLng(42, -71);
            var myOptions = {zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
            map = new google.maps.Map(document.getElementById("mapdiv"), myOptions);

            google.maps.event.addListener(map,'mousemove',function(event) {mouseMove(event);}); 
            google.maps.event.addListener(map,'mousedown',function(event) {mouseDown(event);});
            google.maps.event.addListener(map,'mouseup',function(event) {mouseUp(event);}); 
        }

        function mouseMove(event)
        {
            if (mouseIsDown)
            {
            if (gribBoundingBox) // box exists
                {
                var bounds = new google.maps.LatLngBounds(gribBoundingBox.getBounds().getSouthWest(), event.latLng);
                gribBoundingBox.setBounds(bounds); // If this statement is enabled, I lose mouseUp events
                }
            else // create bounding box
                {
                var bounds = new google.maps.LatLngBounds(mouseDownPos, event.latLng);
                gribBoundingBox = new google.maps.Rectangle({map: map, bounds: bounds, fillOpacity: 0.05, strokeWeight: 1});
                }
            }
        }

        function mouseDown(event)
        {
            mouseIsDown = 1;
            mouseDownPos = event.latLng;
            map.setOptions({draggable: false});
        }

        function mouseUp(event)
        {
            if (mouseIsDown)
            {
                mouseIsDown = 0;
                map.setOptions({draggable: true});
        //      var bounds = new google.maps.LatLngBounds(mouseDownPos, event.latLng);
        //      gribBoundingBox.setBounds(bounds); // If used instead of above, box drawn properly
                gribBoundingBox.setEditable(true);
            }
        }
    </script>
</head>

<body onload="display_map()">
    <div id="mapdiv" style="width:100%; height:100%"></div>
</body>
</html>

Upvotes: 6

Views: 2271

Answers (3)

JJ-connect
JJ-connect

Reputation: 23

If GoogleMaps intermittently loses mouseUp events when drawing (e.g. a rectangle) with a mouseMove event, it could be the Points Of Interest (POI) intercepting the mouseUp event.

This can be fixed by making POIs not clickable (can be set in the MapOptions)

const mapOptions: google.maps.MapOptions = {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        minZoom: 1,
        clickableIcons: false
    };

This worked for me but if you need/want POIs then you could look into disabling them on mouseDown or look at intercepting their mouseUp events and firing your intended mouseUp for finishing drawing.

Upvotes: 0

justGoscha
justGoscha

Reputation: 24145

One can also try to register a mouseup event on the document, if the other solution is not working.

document.addEventListener('mouseup', function(evt){
    stopDraw(evt);
});

Upvotes: 0

Tomik
Tomik

Reputation: 23977

If you update the rectangle bounds, the mouseup event is consumed by the rectangle (it's because the mouse cursor is now positioned within the rectangle). There are two solutions to this:

  1. Set clickable property of the rectangle object to false. The rectangle won't consume the event then.

    gribBoundingBox = new google.maps.Rectangle({map: map, bounds: bounds, fillOpacity: 0.05, strokeWeight: 1, clickable: false});

  2. Add mouseup event listener to the rectangle object. This way the event is consumed and handled by the rectangle. In your example you can use the same listener function.

    google.maps.event.addListener(gribBoundingBox,'mouseup',function(event) {mouseUp(event);});

Upvotes: 2

Related Questions