UNPKG

googlemaps-v3-utility-library

Version:
207 lines (175 loc) 4.98 kB
/** * @license * * Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @fileoverview Map Label. * * @author Luke Mahe (lukem@google.com), * Chris Broadfoot (cbro@google.com) */ /** * Creates a new Map Label * @constructor * @extends google.maps.OverlayView * @param {Object.<string, *>=} opt_options Optional properties to set. */ function MapLabel(opt_options) { this.set('fontFamily', 'sans-serif'); this.set('fontSize', 12); this.set('fontColor', '#000000'); this.set('strokeWeight', 4); this.set('strokeColor', '#ffffff'); this.set('align', 'center'); this.set('zIndex', 1e3); this.setValues(opt_options); } MapLabel.prototype = new google.maps.OverlayView; window['MapLabel'] = MapLabel; /** @inheritDoc */ MapLabel.prototype.changed = function(prop) { switch (prop) { case 'fontFamily': case 'fontSize': case 'fontColor': case 'strokeWeight': case 'strokeColor': case 'align': case 'text': return this.drawCanvas_(); case 'maxZoom': case 'minZoom': case 'position': return this.draw(); } }; /** * Draws the label to the canvas 2d context. * @private */ MapLabel.prototype.drawCanvas_ = function() { var canvas = this.canvas_; if (!canvas) return; var style = canvas.style; style.zIndex = /** @type number */(this.get('zIndex')); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.strokeStyle = this.get('strokeColor'); ctx.fillStyle = this.get('fontColor'); ctx.font = this.get('fontSize') + 'px ' + this.get('fontFamily'); var strokeWeight = Number(this.get('strokeWeight')); var text = this.get('text'); if (text) { if (strokeWeight) { ctx.lineWidth = strokeWeight; ctx.strokeText(text, strokeWeight, strokeWeight); } ctx.fillText(text, strokeWeight, strokeWeight); var textMeasure = ctx.measureText(text); var textWidth = textMeasure.width + strokeWeight; style.marginLeft = this.getMarginLeft_(textWidth) + 'px'; // Bring actual text top in line with desired latitude. // Cheaper than calculating height of text. style.marginTop = '-0.4em'; } }; /** * @inheritDoc */ MapLabel.prototype.onAdd = function() { var canvas = this.canvas_ = document.createElement('canvas'); var style = canvas.style; style.position = 'absolute'; var ctx = canvas.getContext('2d'); ctx.lineJoin = 'round'; ctx.textBaseline = 'top'; this.drawCanvas_(); var panes = this.getPanes(); if (panes) { panes.mapPane.appendChild(canvas); } }; MapLabel.prototype['onAdd'] = MapLabel.prototype.onAdd; /** * Gets the appropriate margin-left for the canvas. * @private * @param {number} textWidth the width of the text, in pixels. * @return {number} the margin-left, in pixels. */ MapLabel.prototype.getMarginLeft_ = function(textWidth) { switch (this.get('align')) { case 'left': return 0; case 'right': return -textWidth; } return textWidth / -2; }; /** * @inheritDoc */ MapLabel.prototype.draw = function() { var projection = this.getProjection(); if (!projection) { // The map projection is not ready yet so do nothing return; } if (!this.canvas_) { // onAdd has not been called yet. return; } var latLng = /** @type {google.maps.LatLng} */ (this.get('position')); if (!latLng) { return; } var pos = projection.fromLatLngToDivPixel(latLng); var style = this.canvas_.style; style['top'] = pos.y + 'px'; style['left'] = pos.x + 'px'; style['visibility'] = this.getVisible_(); }; MapLabel.prototype['draw'] = MapLabel.prototype.draw; /** * Get the visibility of the label. * @private * @return {string} blank string if visible, 'hidden' if invisible. */ MapLabel.prototype.getVisible_ = function() { var minZoom = /** @type number */(this.get('minZoom')); var maxZoom = /** @type number */(this.get('maxZoom')); if (minZoom === undefined && maxZoom === undefined) { return ''; } var map = this.getMap(); if (!map) { return ''; } var mapZoom = map.getZoom(); if (mapZoom < minZoom || mapZoom > maxZoom) { return 'hidden'; } return ''; }; /** * @inheritDoc */ MapLabel.prototype.onRemove = function() { var canvas = this.canvas_; if (canvas && canvas.parentNode) { canvas.parentNode.removeChild(canvas); } }; MapLabel.prototype['onRemove'] = MapLabel.prototype.onRemove;