From 2da40474fc95f4b5578f6c930b0e660218709894 Mon Sep 17 00:00:00 2001 From: Robert Conner Howell Date: Wed, 9 Aug 2017 22:01:36 -0700 Subject: [PATCH 1/2] Add background option for map label --- CONTRIBUTORS | 1 + docs/reference.html | 25 ++++++++ examples/maplabel-background.html | 88 +++++++++++++++++++++++++++ examples/maplabel.html | 2 +- src/maplabel.js | 99 +++++++++++++++++++++++++------ 5 files changed, 196 insertions(+), 19 deletions(-) create mode 100644 examples/maplabel-background.html diff --git a/CONTRIBUTORS b/CONTRIBUTORS index e67aadb..ddabad9 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -12,3 +12,4 @@ Luke Mahé Chris Broadfoot Brendan Kenny +Robert Howell diff --git a/docs/reference.html b/docs/reference.html index 2d99198..c319df4 100755 --- a/docs/reference.html +++ b/docs/reference.html @@ -195,6 +195,31 @@

MapLabelOptions object specification

number The zIndex of the label. Default is 1000. + + backgroundColor + number + The zIndex of the label. Default is 1000. + + + backgroundStrokeWeight + number + The zIndex of the label. Default is 1000. + + + backgroundStrokeColor + number + The zIndex of the label. Default is 1000. + + + borderRadius + number + The zIndex of the label. Default is 1000. + + + padding + number + The zIndex of the label. Default is 1000. + diff --git a/examples/maplabel-background.html b/examples/maplabel-background.html new file mode 100644 index 0000000..7b5d840 --- /dev/null +++ b/examples/maplabel-background.html @@ -0,0 +1,88 @@ + + + + + + Map Label Utility Library Example With Background + + + + + + + + +

Map Label Utility Library - With Background

+
+
+
+ + +
+ + + + + + diff --git a/examples/maplabel.html b/examples/maplabel.html index 4d48361..a883b26 100755 --- a/examples/maplabel.html +++ b/examples/maplabel.html @@ -133,4 +133,4 @@

Map Label Utility Library

- + \ No newline at end of file diff --git a/src/maplabel.js b/src/maplabel.js index 71c88ca..af666f2 100755 --- a/src/maplabel.js +++ b/src/maplabel.js @@ -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); @@ -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); }; /** @@ -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(); + } +} From 082627fd0c5f03dd9730149a84b05213d93a6e54 Mon Sep 17 00:00:00 2001 From: Robert Conner Howell Date: Wed, 9 Aug 2017 22:06:37 -0700 Subject: [PATCH 2/2] Include defaults and update reference.html with additions --- docs/reference.html | 14 +++++++------- src/maplabel.js | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/reference.html b/docs/reference.html index c319df4..576c1f5 100755 --- a/docs/reference.html +++ b/docs/reference.html @@ -197,28 +197,28 @@

MapLabelOptions object specification

backgroundColor - number - The zIndex of the label. Default is 1000. + string + The background color. All CSS3 colors are supported. No background unless backgroundColor is specified. backgroundStrokeWeight number - The zIndex of the label. Default is 1000. + The background stroke width. Default is 1. backgroundStrokeColor - number - The zIndex of the label. Default is 1000. + string + The background stroke color. All CSS3 colors are supported. Default is #FFFFFF. borderRadius number - The zIndex of the label. Default is 1000. + The border radius on all corners of the background. Default is 0. padding number - The zIndex of the label. Default is 1000. + The padding on all sides between the text and the background. Default is 0. diff --git a/src/maplabel.js b/src/maplabel.js index af666f2..707f03d 100755 --- a/src/maplabel.js +++ b/src/maplabel.js @@ -40,6 +40,7 @@ function MapLabel(opt_options) { 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);