Skip to content
This repository was archived by the owner on Dec 15, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
Luke Mahé <lukem@google.com>
Chris Broadfoot <cbro@google.com>
Brendan Kenny <bckenny@google.com>
Robert Howell <rhowell2@nd.edu>
25 changes: 25 additions & 0 deletions docs/reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,31 @@ <h2 id="MapLabelOptions">MapLabelOptions object specification</h2>
<td><code><span class="type">number</span></code></td>
<td>The zIndex of the label. Default is <code>1000</code>.</td>
</tr>
<tr>
<td><code>backgroundColor</code></td>
<td><code><span class="type">string</span></code></td>
<td>The background color. All CSS3 colors are supported. No background unless backgroundColor is specified.</td>
</tr>
<tr>
<td><code>backgroundStrokeWeight</code></td>
<td><code><span class="type">number</span></code></td>
<td>The background stroke width. Default is <code>1</code>.</td>
</tr>
<tr>
<td><code>backgroundStrokeColor</code></td>
<td><code><span class="type">string</span></code></td>
<td>The background stroke color. All CSS3 colors are supported. Default is <code>#FFFFFF</code>.</td>
</tr>
<tr>
<td><code>borderRadius</code></td>
<td><code><span class="type">number</span></code></td>
<td>The border radius on all corners of the background. Default is <code>0</code>.</td>
</tr>
<tr>
<td><code>padding</code></td>
<td><code><span class="type">number</span></code></td>
<td>The padding on all sides between the text and the background. Default is <code>0</code>.</td>
</tr>
</tbody>
</table>
</body>
Expand Down
88 changes: 88 additions & 0 deletions examples/maplabel-background.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Map Label Utility Library Example With Background</title>
<style>
body {
font-family: sans-serif;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="../src/maplabel.js"></script>

<script>
function init() {
var myLatlng = new google.maps.LatLng(34.04, -118.24);
var myOptions = {
zoom: 13,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};

var map = new google.maps.Map(document.getElementById('map'), myOptions);

var mapLabel = new MapLabel({
text: 'Background!',
position: new google.maps.LatLng(34.03, -118.235),
map: map,
fontSize: 20,
fontColor: '#fff',
strokeWeight: 1.0,
strokeColor: '#01579B',
backgroundColor: '#0288D1',
borderRadius: 10,
padding: 10,
backgroundStrokeColor: '#01579B',
backgroundStrokeWeight: 3
});
mapLabel.set('position', new google.maps.LatLng(34.03, -118.235));

var marker = new google.maps.Marker();
marker.bindTo('map', mapLabel);
marker.bindTo('position', mapLabel);
marker.setDraggable(true);

var map2 = new google.maps.Map(document.getElementById('map2'), myOptions);

var changeText = document.getElementById('change-text');
google.maps.event.addDomListener(changeText, 'click', function() {
mapLabel.set('text', document.getElementById('text').value);
});


var move = document.getElementById('move');
google.maps.event.addDomListener(move, 'click', function() {
mapLabel.setMap(mapLabel.getMap() === map ? map2 : map);
});
}

google.maps.event.addDomListener(window, 'load', init);
</script>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12846745-20']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<h1>Map Label Utility Library - With Background</h1>
<div id="map" style="width: 500px; height: 500px; float: left"></div>
<div id="map2" style="width: 500px; height: 500px; float: left; margin-left: 20px;"></div>
<div style="clear: both; padding-top: 10px;">
<label>Map:</label>
<button id="move">Toggle Maps</button>
</div>
<label>Text:</label>
<input type="text" id="text" value="foo">
<button id="change-text">Change Text</button>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion examples/maplabel.html
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,4 @@ <h1>Map Label Utility Library</h1>
<button id="change-align">Align</button>
</div>
</body>
</html>
</html>
100 changes: 82 additions & 18 deletions src/maplabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ function MapLabel(opt_options) {
this.set('strokeColor', '#ffffff');
this.set('align', 'center');

this.set('padding', 0);
// Canvas sets lineWidth as 1.0 by default
this.set('backgroundStrokeWeight', 1);
this.set('backgroundStrokeColor', '#ffffff');
this.set('borderRadius', 0);

this.set('zIndex', 1e3);

this.setValues(opt_options);
Expand Down Expand Up @@ -77,28 +83,49 @@ MapLabel.prototype.drawCanvas_ = function() {

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);
}
if (!text) return;

ctx.fillText(text, strokeWeight, strokeWeight);
var fontSize = this.get('fontSize');
var textX = 0;
var textY = 0;
var strokeWeight = Number(this.get('strokeWeight'));
ctx.font = fontSize + 'px ' + this.get('fontFamily');
// Text must be measured after setting ctx.font for accurate results
var textMeasure = ctx.measureText(text);

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';
var backgroundColor = this.get('backgroundColor');
// Draw background (if specified) before text
if (backgroundColor) {
// Setup background dimensions
var padding = Number(this.get('padding'));
var bgStrokeWeight = Number(this.get('backgroundStrokeWeight'));
var rectWidth = (textMeasure.width + strokeWeight + bgStrokeWeight) + (2 * padding);
var rectHeight = (fontSize + strokeWeight + bgStrokeWeight) + (2 * padding);
var radius = this.get('borderRadius');
var bgStrokeColor = this.get('backgroundStrokeColor');
var offset = bgStrokeWeight;
console.log(offset, bgStrokeWeight);
// Draw rect.
roundRect(ctx, offset, rectWidth, rectHeight, radius, backgroundColor, bgStrokeColor, bgStrokeWeight);
// Prepare text to be centered in the background
// strokeWeight is include in rect dimensions, but is added later in all cases.
// remove strokeWeight so that it is not included twice in the text's x and y
textX = offset + (rectWidth / 2) - strokeWeight;
textY = offset + (rectHeight / 2) - strokeWeight;
// Alignment must be centered when using a background
ctx.textAlign="center";
ctx.textBaseline = "middle";
}

ctx.strokeStyle = this.get('strokeColor');
ctx.fillStyle = this.get('fontColor');
if (strokeWeight) {
ctx.lineWidth = strokeWeight;
ctx.strokeText(text, textX + strokeWeight, textY + strokeWeight);
}
ctx.fillText(text, textX + strokeWeight, textY + strokeWeight);
};

/**
Expand Down Expand Up @@ -204,3 +231,40 @@ MapLabel.prototype.onRemove = function() {
}
};
MapLabel.prototype['onRemove'] = MapLabel.prototype.onRemove;

/**
* Draws a rounded rectangle.
* TODO: Put this somewhere better?
*/
function roundRect(ctx, offset, width, height, radius, fill, stroke, strokeWeight) {
var x = offset;
var y = offset;
if (typeof radius === 'number') {
radius = {tl: radius, tr: radius, br: radius, bl: radius};
} else {
var defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
for (var side in defaultRadius) {
radius[side] = radius[side] || defaultRadius[side];
}
}
ctx.beginPath();
ctx.moveTo(x + radius.tl, y);
ctx.lineTo(x + width - radius.tr, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
ctx.lineTo(x + width, y + height - radius.br);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
ctx.lineTo(x + radius.bl, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
ctx.lineTo(x, y + radius.tl);
ctx.quadraticCurveTo(x, y, x + radius.tl, y);
ctx.closePath();
if (fill) {
ctx.fillStyle = fill;
ctx.fill();
}
if (stroke) {
ctx.strokeStyle = stroke;
ctx.lineWidth = strokeWeight;
ctx.stroke();
}
}