Skip to content

Commit

Permalink
Merge pull request #834 from OpenGeoscience/text-feature-rendered-zone
Browse files Browse the repository at this point in the history
Add a parameter to the text feature to limit what gets rendered.
  • Loading branch information
manthey authored Jun 29, 2018
2 parents 4ae535d + 95f10c9 commit e8b5062
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/canvas/textFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,13 @@ var canvas_textFeature = function (arg) {
this._renderOnCanvas = function (context2d, map) {
var data = m_this.data(),
posFunc = m_this.style.get('position'),
renderThreshold = m_this.style.get('renderThreshold')(data),
textFunc = m_this.style.get('text'),
mapRotation = map.rotation(),
mapZoom = map.zoom(),
fontFromSubValues, text, pos, visible, color, blur, stroke, width,
rotation, rotateWithMap, scale, offset,
mapSize = map.size(),
fontFromSubValues, text, posArray, pos, visible, color, blur, stroke,
width, rotation, rotateWithMap, scale, offset,
transform, lastTransform = util.mat3AsArray();

/* If any of the font styles other than `font` have values, then we need to
Expand All @@ -117,7 +119,17 @@ var canvas_textFeature = function (arg) {
});
/* Clear the canvas property buffer */
m_this._canvasProperty();
posArray = m_this.featureGcsToDisplay(data.map(posFunc));
data.forEach(function (d, i) {
/* If the position is far enough outside of the map viewport, don't
* render it, even if the offset of size would be sufficient to make it
* appear in the viewport. */
pos = posArray[i];
if (renderThreshold > 0 && (
pos.x < -renderThreshold || pos.x > mapSize.width + renderThreshold ||
pos.y < -renderThreshold || pos.y > mapSize.height + renderThreshold)) {
return;
}
visible = m_this.style.get('visible')(d, i);
if (!visible && visible !== undefined) {
return;
Expand All @@ -130,10 +142,6 @@ var canvas_textFeature = function (arg) {
return;
}
m_this._canvasProperty(context2d, 'fillStyle', util.convertColorToRGBA(color));
// TODO: get the position position without transform. If it is outside
// of the map to an extent that there is no chance of text showing,
// skip further processing.
pos = m_this.featureGcsToDisplay(posFunc(d, i));
text = textFunc(d, i);
m_this._canvasProperty(context2d, 'font', m_this.getFontFromStyles(fontFromSubValues, d, i));
m_this._canvasProperty(context2d, 'textAlign', m_this.style.get('textAlign')(d, i) || 'center');
Expand Down
6 changes: 6 additions & 0 deletions src/textFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ var feature = require('./feature');
* stroke color. May include opacity.
* @property {geo.geoColor|function} [style.textStrokeWidth=0] Text stroke
* width in pixels.
* @property {number|function} [style.renderThreshold] If this is a positive
* number, text elements may not be rendered if their base position
* (before offset and font effects are applied) is more than this distance
* in pixels outside of the current viewport. If it is known that such
* text elements cannot affect the current viewport, setting this can
* speed up rendering. This is computed once for the whole feature.
*/

/**
Expand Down
31 changes: 31 additions & 0 deletions tests/cases/textFeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,36 @@ describe('geo.textFeature', function () {
expect(text.getFontFromStyles(true, text.data()[3], 3)).toBe('italic small-caps bold condensed 40px/60px serif');
expect(text.getFontFromStyles(true, text.data()[11], 11)).toBe('bold 16px/60px sans-serif');
});
it('renderThreshold', function () {
mockAnimationFrame();
logCanvas2D();
map = createMap();
layer = map.createLayer('feature', {renderer: 'canvas'});
text = layer.createFeature('text').data(testText);
text.draw();
stepAnimationFrame();
var count1 = $.extend({}, window._canvasLog.counts).fillText;
text.style({renderThreshold: 0});
text.draw();
stepAnimationFrame();
var count2 = $.extend({}, window._canvasLog.counts).fillText;
expect(count2 - count1).toBe(14);
text.style({renderThreshold: 1});
text.draw();
stepAnimationFrame();
var count3 = $.extend({}, window._canvasLog.counts).fillText;
expect(count3 - count2).toBe(6);
text.style({renderThreshold: 20});
text.draw();
stepAnimationFrame();
var count4 = $.extend({}, window._canvasLog.counts).fillText;
expect(count4 - count3).toBe(8);
text.style({renderThreshold: 0});
text.draw();
stepAnimationFrame();
var count5 = $.extend({}, window._canvasLog.counts).fillText;
expect(count5 - count4).toBe(14);
unmockAnimationFrame();
});
});
});

0 comments on commit e8b5062

Please sign in to comment.