Skip to content
This repository has been archived by the owner on Dec 15, 2018. It is now read-only.

Commit

Permalink
Add background option for map label
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Conner Howell committed Aug 10, 2017
1 parent 9af421c commit 2da4047
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 19 deletions.
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é <[email protected]>
Chris Broadfoot <[email protected]>
Brendan Kenny <[email protected]>
Robert Howell <[email protected]>
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">number</span></code></td>
<td>The zIndex of the label. Default is <code>1000</code>.</td>
</tr>
<tr>
<td><code>backgroundStrokeWeight</code></td>
<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>backgroundStrokeColor</code></td>
<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>borderRadius</code></td>
<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>padding</code></td>
<td><code><span class="type">number</span></code></td>
<td>The zIndex of the label. Default is <code>1000</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>
99 changes: 81 additions & 18 deletions src/maplabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ 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('borderRadius', 0);

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

this.setValues(opt_options);
Expand Down Expand Up @@ -77,28 +82,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 +230,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();
}
}

0 comments on commit 2da4047

Please sign in to comment.