Closed nvkelso closed 4 years ago
A cheap way to do this may be to draw a rectangle behind the text when it's being rasterized on canvas. This would depend on getting the metrics right with letter-spacing etc applied so the border around the text is consistent. It would also mean the background cannot have an alpha independent of the text, but that seems like an acceptable compromise.
Example screen:
Funny, I was looking at exactly this last night too (re-familiarizing myself with the text rendering code thinking about vertical CJK text, and remembered this issue).
I agree the Canvas background box approach is a good tradeoff for this (and we use a similar approach for texture/collision box debug rendering already). It's not the most optimized (would increase the label atlas size for different color background boxes that otherwise share the same label text + font), but that is unlikely to happen frequently and it's a low code footprint to implement. It is less straightforward for curved labels though, due to order issues with the background boxes overlapping nearby segments, so limiting it to point labels -- which I believe is the main use case -- would also make for an easier initial implementation.
I've pushed my work on this here: https://github.com/tangrams/tangram/compare/text-box
Note that while it does apply the recently added alpha
parameter in the font
block (#740) to both the fill
and background
when it is present, it is also possible to set a different alpha for the two directly, e.g.:
font:
fill: [1, 1, 1, 0.75] # white text w/75% opacity
background: [1, 0.5, 0, 0.5] # orange background w/50% opacity
...
@nvkelso how does this look to you?
This is a much better implementation than mine :)
https://github.com/bdon/tangram/commit/570f9c3fdae3bf38fba209f09728a12cc33accc7
I was thinking maybe even:
font:
fill: [1, 1, 1, 0.75] # white text w/75% opacity
background:
fill: [1, 0.5, 0, 0.5]
stroke: black
strokeWidth: 2px
which would call strokeRect in the rasterization code. it may act funny with strokeWidths more than a couple px though? worth experimenting.
💯 Loving this! Most often I see this in print maps as solid background, but I do see it sometimes with a stroke as well so like @bdon's proposal.
(If more than one background is used sometimes the color is varied, but if it's to emphasize a slight information difference then the graphic stroke is applied.)
https://github.com/tangrams/tangram/compare/text-box#diff-696dc4f88f682e93455a7a17a688f0bcR52
This excludes "points" draw styles applied to line geometries. A use case may be very basic sprite-free highway shields like I posted above, so I think it should be changed.
This excludes "points" draw styles applied to line geometries. A use case may be very basic sprite-free highway shields like I posted above, so I think it should be changed.
Oh, yep that was an oversight, I agree this should apply to any point label, regardless of underlying geometry.
Just a quick note here to say I haven't forgotten this :)
Ran into some apparent issues with collision detection that need to be addressed. The addition of border stroke also adds potential complexity there... all the result of pushing this to be more of a "real" feature vs. a quick hack. Not a bad thing though, just takes a bit more time. Have been busy elsewhere but hoping to look at it soon.
Fixed collision issues for background box in the branch: https://github.com/tangrams/tangram/compare/text-box
I'll see if adding the stroke is straightforward, and if not, maybe we start with just the background (or with a stroke of fixed width).
released in v0.21.0
Similar to https://github.com/tangrams/tangram/issues/723 which proposes text underlines, I'd like to a new text treatment to callout country and regional capitals in map styles. We adding better support for both in the new v1.8 Tilezen schema, but right now the only way to call them out visually is to change the color. Another common technique in cartography (especially in Europe) is to "highlight" the text with a yellow or orange box shape behind the text.
There are two options for the shape – if there is letter spacing (or spaces) the highlight should optionally continue as one shape... but the default is usually to only do it behind word blocks.