Last active
February 8, 2017 00:28
-
-
Save sammoore/eb1f6122098c38bff6ac9eed3843353d to your computer and use it in GitHub Desktop.
An "immutable" OverlayView for Google Maps v3 that simply displays a TextNode in a <div>, anchored at the specified position. Minimal && YMMV.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global _, google */ | |
(function amdWeb(root, factory) { | |
/* eslint-disable */ | |
if (typeof define == 'function' && define.amd) { | |
define(['lodash', 'googlemaps!'], factory); | |
/* eslint-enable */ | |
} else { | |
root.TextOverlay = factory(_, (google || {}).maps); | |
} | |
}(this, function factory(_, gmaps) { | |
'use strict'; | |
// FIXME: If google.maps is undefined at time of loading, | |
// return the factory for the consumer to mount themselves. | |
if (typeof gmaps == 'undefined') { | |
return factory; | |
} | |
var LatLng = gmaps.LatLng; | |
/** @name latLng | |
* @desc creates LatLng from GeoJSON array, a LatLngLiteral, or LatLng. | |
* @param value {GeoJSONCoordinateArray|LatLng|LatLngLiteral} | |
*/ | |
var latLng = function latLng(value) { | |
// eslint-disable-next-line | |
if (LatLng.prototype.isPrototypeOf(value)) { | |
return value; | |
} | |
if (Array.isArray(value)) { | |
return new LatLng({ lat: value[1], lng: value[0] }); | |
} | |
return new LatLng(value); | |
}; | |
/** @name TextOverlayOptions | |
* @desc Represents valid options for the TextOverlay class. | |
* @property position {GeoJSONCoordinateArray|LatLng|LatLngLiteral} | |
* @property style {Object|null} where each key is a CSS property in DOM notation | |
* @property text {String|null} the text content to be displayed in the overlay. | |
* | |
* Note this can be an object literal; this function simply forms the literal. | |
*/ | |
var TextOverlayOptions = function (position, style, text) { | |
return { | |
position: position, | |
style: style, | |
text: text | |
}; | |
}; | |
TextOverlayOptions.DEFAULTS = { | |
position: [0, 0], | |
style: {}, | |
text: '' | |
}; | |
var TextOverlay = function (options) { | |
if (!(this instanceof TextOverlay)) return new TextOverlay(options); | |
gmaps.OverlayView.call(this); | |
var options = _.assign({}, TextOverlayOptions.DEFAULTS, options); | |
this.position_ = latLng(options.position); | |
this.style_ = options.style; | |
this.text_ = options.text; | |
this.div_ = null; | |
}; | |
TextOverlay.prototype = new gmaps.OverlayView(); | |
// TextOverlay.defineKVOProperty = MVCDefineKVOProp(TextOverlay.prototype); | |
_.assign(TextOverlay, { | |
createDiv: function createDiv(text, style) { | |
var div = document.createElement('div'); | |
var textNode = document.createTextNode(text); | |
var style = _.assign({ position: 'absolute' }, style); | |
_.each(style, function (value, key) { | |
div.style.setProperty(key, value); | |
}); | |
div.appendChild(textNode); | |
return div; | |
}, | |
positionForDiv: function positionForDiv(projection, anchor, div) { | |
if (!projection.fromLatLngToDivPixel) { | |
throw new TypeError('projection is not a MapCanvasProjection'); | |
} | |
var point = projection.fromLatLngToDivPixel(latLng(anchor)); | |
var computedWidth = div.getBoundingClientRect().width || 0; | |
return { | |
top: point.y + 'px', | |
left: (point.x - (computedWidth / 2)) + 'px' | |
}; | |
} | |
}); | |
_.assign(TextOverlay.prototype, { | |
getPosition: function getPosition() { | |
return this.position_; | |
}, | |
getStyle: function getStyle() { | |
return this.style_; | |
}, | |
getText: function getText() { | |
return this.text_; | |
} | |
}, { | |
onAdd: function onAdd() { | |
var div = this.div_ = TextOverlay.createDiv(this.text_, this.style_); | |
this.getPanes().overlayLayer.appendChild(div); | |
}, | |
draw: function draw() { | |
var div = this.div_; | |
var anchor = this.position_; | |
var projection = this.getProjection(); | |
var positionStyles = TextOverlay.positionForDiv(projection, anchor, div); | |
_.assign(div.style, positionStyles); | |
}, | |
onRemove: function onRemove() { | |
this.div_.parentNode.removeChild(this.div_); | |
this.div_ = null; | |
} | |
}); | |
return TextOverlay; | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment