Skip to content

Instantly share code, notes, and snippets.

@sammoore
Last active February 8, 2017 00:28
Show Gist options
  • Save sammoore/eb1f6122098c38bff6ac9eed3843353d to your computer and use it in GitHub Desktop.
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.
/* 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