diff --git a/js/highlight.js b/js/highlight.js index 8d38c6989d8d3a0f12d5171b181ce231209ddd55..74642b60fa2fa77d23e03f59ce4eac487c8b10fe 100644 --- a/js/highlight.js +++ b/js/highlight.js @@ -8,74 +8,182 @@ * Highlights marker on rollover. * Removes highlight on previous marker. * - * Creates a "circle" using 20-sided GPolygon at the given point - * Circle polygon object is global variable as there is only one highlighted marker at a time + * Creates a "circle" at the given point + * Circle is global variable as there is only one highlighted marker at a time * and we want to remove the previously placed polygon before placing a new one. - * + * * Original code "Google Maps JavaScript API Example" + * JN201304: + * converted rpolygons to circles (not using the shapes.js API, should we be?) + * move marker highlight events to custom handler here, to handle radius in pixels (note behavior.radiusInMeters to skip geodesic calcs) + * removed google.events and moved events to gmaps binds + * added overlay object for creating a shape based on pixels instead of meters (seems to be the use case?) + * added gmaps binds for marker higlights, and general highlights. + * + * You can add highlights to a map with: + * obj.change('addHighlight',-1, {latitude:#, longitude:#} ); + * You can highlight a marker with: + * obj.change('markerHighlight',-1, marker); + * marker: that marker object used when creating the marker. It can have options set at marker.highlight + * + * A Highlight object has to have either a <LatLng>Position or a <Number>latitude and <Number>longitude + * Note the new highlight options = { + * radius: 10, // radius in pixels + * color: '#777777', + * weight: 2, + * opacity: 0.7, + * behavior: { + * draggable: false, + * editable: false, + * } + * opts: { actual google.maps.Circle opts can be put here for super custom cases } + * } */ -highlightMarker = function (gmap, currentMarker, highlightID, color) { - - var map = gmap.map; - - var markerPoint = currentMarker.marker.getPosition(); - var polyPoints = Array(); - var mapNormalProj = gmap.highlight.overlay.getProjection(); +Drupal.gmap.factory.highlight = function(options) { + return new google.maps.Circle(options); +} - var mapZoom = map.getZoom(); - var clickedPixel = mapNormalProj.fromLatLngToDivPixel(markerPoint, mapZoom); +Drupal.gmap.addHandler('gmap', function (elem) { + var obj = this; + obj.highlights = {}; - var polySmallRadius = 20; - var polyNumSides = 20; - var polySideLength = 18; + var overlayHandler = function(map, highlight) { + this.setMap(map); + this.highlight = highlight; + } + overlayHandler.prototype = new google.maps.OverlayView(); + overlayHandler.prototype.onAdd = function() { + var highlight = this.highlight; + if ( !highlight.opts ) { highlight.opts = {}; } // sanity + if ( !highlight.behavior ) { highlight.behavior = {}; } // sanity + if ( !highlight.position ) { highlight.position = new google.maps.LatLng( highlight.latitude, highlight.longitude ); } // if you have a pos already then use it, otherwise gimme a lat/lon + + $.each({ // collect the options from either the highligh.opts object, from the passed target value, as a behavior or a default value + radius: {target:'radius',default:10}, // radius in pixels + strokeColor: {target:'border',default:'#777777'}, + strokeWeight: {target:'weight',default:2}, + strokeOpacity: {target:'opacity',default:0.7}, + fillColor: {target:'color',default:'#777777'}, + fillOpacity: {target:'opacity',default:0.7}, + draggable: {behavior:'draggable',default:false}, + editable: {behavior:'editable',default:false}, + }, function( key , config ) { + if ( highlight.opts[key] ) { // options was passed in + return true; + } + else if (config.target && highlight[ config.target ]) { // highight.target should have a value + highlight.opts[key] = highlight[ config.target ]; + } + else if ( config.behavior && highlight.behavior && highlight.behavior[ config.behavior ] ) { // value is a behaviour + highlight.opts[key] = highlight.behavior[ config.behavior ]; + } + else if (config.default) { // default valuee + highlight.opts[key] = config.default; + } + }); + + highlight.opts.map = this.map; + highlight.opts.center = highlight.position; - for (var a = 0; a < (polyNumSides + 1); a++) { - var aRad = polySideLength * a * (Math.PI/180); - var polyRadius = polySmallRadius; - var pixelX = clickedPixel.x + polyRadius * Math.cos(aRad); - var pixelY = clickedPixel.y + polyRadius * Math.sin(aRad); - var polyPixel = new google.maps.Point(pixelX, pixelY); - var polyPoint = mapNormalProj.fromDivPixelToLatLng(polyPixel, mapZoom); - polyPoints.push(polyPoint); } - // Using GPolygon(points, strokeColor?, strokeWeight?, strokeOpacity?, fillColor?, fillOpacity?) - gmap.highlight.polygon = new google.maps.Polygon( { - paths: polyPoints, - strokeColor: color, - strokeWeight: 2, - strokeOpacity: 0, - fillColor: color, - fillOpacity: 0.5 - } ); - gmap.highlight.polygon.setMap( map ); - -}; - -unHighlightMarker = function (gmap, currentMarker, highlightID) { - if (gmap.highlight.polygon) { - gmap.highlight.polygon.setMap( null ); - delete gmap.highlight.polygon; + overlayHandler.prototype.draw = function() { + var highlight = this.highlight; + if ( !this.highlight.behavior.radiusInMeters ) { + var projection = this.getProjection(); + var mapZoom = this.map.getZoom(); + var center = projection.fromLatLngToDivPixel(highlight.opts.center, mapZoom); + var radius = highlight.opts.radius; + var radial = projection.fromDivPixelToLatLng(new google.maps.Point(center.x, center.y+radius), mapZoom); // find a point that is the radius distance away in pixels + highlight.opts.radius = google.maps.geometry.spherical.computeDistanceBetween (highlight.opts.center, radial); + highlight.behavior.radiusInMeters = true; + } + highlight.highlight = Drupal.gmap.factory.highlight(highlight.opts); + } + overlayHandler.prototype.onRemove = function() { + if ( this.highlight.highlight ) { + this.highlight.highlight.setMap( null ); + } } -}; - -Drupal.gmap.addHandler('gmap', function (elem) { - - var obj = this; - - function HighlightOverlay(m) { this.setMap(m); } - HighlightOverlay.prototype = new google.maps.OverlayView(); + Drupal.gmap.highlight = function (highlight) { + new overlayHandler(obj.map, highlight); // all actions happen in an overlayview, so that we can input pixels for radius instead of meters and positions + }; + Drupal.gmap.unhighlight = function( highlight ) { // this can take an object that has a highlight, or a highlight/circle object + if ( highlight.highlight && highlight.highlight.setMap ) { + highlight.highlight.setMap( null ); + } + else if ( highlight.setMap ) { + highlight.setMap( null ); + } + } - HighlightOverlay.prototype.onAdd = function() { } - HighlightOverlay.prototype.onRemove = function() { } - HighlightOverlay.prototype.draw = function() { } + // set and remove map highlights - obj.bind('init', function () { + obj.bind('addHighlight', function(highlight) { + Drupal.gmap.highlight( highlight ); + }); + obj.bind('removeHighlight', function(highlight) { + Drupal.gmap.unhighlight( highlight ); + }); - obj.highlight = {}; - obj.highlight.overlay = new HighlightOverlay( obj.map ); + // Marker specific code: + var activeMarker; // remember that last marker activated. In the default case we only allow one highlighted marker at a time + obj.bind('markerHighlight', function (marker) { + if ( activeMarker && !obj.vars.behavior.allowMultipleMarkerHighlight ) { obj.change('markerUnHighlight',-1, activeMarker); } // deactivate the active marker + + // If the highlight arg option is used in views highlight the marker. + if ( !marker.highlight ) { marker.highlight = {} } + if ( !marker.highlight.color && obj.vars.styles.highlight_color ) { marker.highlight.color = '#' + obj.vars.styles.highlight_color; } + marker.highlight.position = marker.marker.getPosition(); + Drupal.gmap.highlight( marker.highlight ); + activeMarker = marker; + }); + obj.bind('markerUnHighlight', function(marker) { + if ( !marker ) { marker = activeMarker; } // remove the active marker if no marker is passed in + if ( activeMarker === marker ) { activeMarker = null; } + if ( marker.highlight ) { + Drupal.gmap.unhighlight(marker.highlight); + } + }); + /** + * Marker Binds + * + * Marker highlight code has been moved to this file from the marker.js + * + * Note that we rely on the obj.vars.behavior.highlight var to + * decide if should highlight markers on events. + * This decision could be made as an outer if conditional, instead + * of repeated inside each bind, but this arrangement allows for + * the behaviour to change, at a small cost. + */ + + obj.bind('addmarker', function (marker) { + if (obj.vars.behavior.highlight) { + google.maps.event.addListener(marker.marker, 'mouseover', function () { + obj.change('markerHighlight',-1,marker); + }); + google.maps.event.addListener(marker.marker, 'mouseout', function () { + obj.change('markerUnHighlight',-1,marker); + }); + } + // If the highlight arg option is used in views highlight the marker. + if (marker.opts.highlight == 1) { + obj.change('markerHighlight',-1,marker); + } }); -} ); \ No newline at end of file +// Originally I moved mouse highlights to the extra event binds before I realized that there is likely a usecase for highlights without enabling extra events +// obj.bind('mouseovermarker', function(marker) { +// if (obj.vars.behavior.highlight && marker) { +// obj.change('markerHighlight',-1,marker); +// } +// }); +// obj.bind('mouseoutmarker', function(marker) { +// if (obj.vars.behavior.highlight && marker) { +// obj.change('markerUnHighlight',-1,marker); +// } +// }); + +}); diff --git a/js/marker.js b/js/marker.js index 1f58e06c9e4405e34201d76063c86f830f19a521..a6eb17ec8123c354c58f4346c39a7e94deb3a6d9 100644 --- a/js/marker.js +++ b/js/marker.js @@ -26,15 +26,6 @@ Drupal.gmap.addHandler('gmap', function (elem) { google.maps.event.addListener(m, 'click', function () { obj.change('clickmarker', -1, marker); }); - if (obj.vars.behavior.highlight) { - google.maps.event.addListener(m, 'mouseover', function () { - var highlightColor = '#' + obj.vars.styles.highlight_color; - highlightMarker(obj, marker, 'hoverHighlight', highlightColor); - }); - google.maps.event.addListener(m, 'mouseout', function () { - unHighlightMarker(obj, marker, 'hoverHighlight'); - }); - } if (obj.vars.behavior.extramarkerevents) { google.maps.event.addListener(m, 'mouseover', function () { obj.change('mouseovermarker', -1, marker); @@ -55,12 +46,6 @@ Drupal.gmap.addHandler('gmap', function (elem) { if (obj.vars.behavior.autozoom) { obj.bounds.extend(new google.maps.LatLng(marker.latitude, marker.longitude)); } - // If the highlight arg option is used in views highlight the marker. - if (marker.opts.highlight == 1) { - google.maps.event.addListener( obj.mm, 'loaded', function() { - highlightMarker(obj, marker, 'viewHighlight', marker.opts.highlightcolor); - } ); - } }); // Default marker actions. @@ -116,7 +101,7 @@ Drupal.gmap.addHandler('gmap', function (elem) { // Tabbed content else if (marker.tabs) { var data = ""; - //tabs in an infowindow is no longer supported in API ver3. + //tabs in an infowindow is no longer supported in API ver3. for (var m in marker.tabs) { data += marker.tabs[m]; } @@ -137,8 +122,8 @@ Drupal.gmap.addHandler('gmap', function (elem) { var listener = google.maps.event.addListener(obj.map, "idle", function() { if (obj.vars.maxzoom) { var maxzoom = parseInt(obj.vars.maxzoom) - if (obj.map.getZoom() > maxzoom) obj.map.setZoom(maxzoom); - google.maps.event.removeListener(listener); + if (obj.map.getZoom() > maxzoom) obj.map.setZoom(maxzoom); + google.maps.event.removeListener(listener); } }); }