Handle visibility between layers sharing a webgl renderer.
MODIFY
src/layer.js
src/layer.js
@@ -254,7 +254,7 @@ var layer = function (arg) {
* receive native mouse events.
*
* @param {boolean} [arg] If specified, the new `active` value.
- * @returns {boolean|object}
+ * @returns {boolean|this}
*/
this.active = function (arg) {
if (arg === undefined) {
@@ -457,7 +457,7 @@ var layer = function (arg) {
}
if (m_visible !== val) {
m_visible = val;
- m_node.css('display', m_visible ? '' : 'none');
+ m_node.toggleClass('hidden', !m_visible);
m_this.modified();
}
return m_this;
@@ -584,6 +584,8 @@ var layer = function (arg) {
/**
* Get or set the current layer opacity. The opacity is in the range [0-1].
+ * An opacity of 0 is not the same as setting `visible(false)`, as
+ * interactions can still occurr with the layer.
*
* @param {number} [opacity] If specified, set the opacity. Otherwise,
* return the opacity.
@@ -601,6 +603,7 @@ var layer = function (arg) {
// Create top level div for the layer
m_node = $(document.createElement('div'));
m_node.addClass('geojs-layer');
+ m_node.attr('renderer', m_rendererName);
if (m_name) {
m_node.attr('id', m_name);
}

MODIFY
src/main.styl
src/main.styl
left 0
top 0
pointer-events none
- &.active
+ &.active:not(.hidden)
> *
pointer-events auto
+ &.hidden
+ display none
+ &.hidden[renderer="webgl"]
+ display inherit
.geo-tile-layer
transform-origin 0px 0px

MODIFY
src/webgl/layer.js
src/webgl/layer.js
@@ -4,8 +4,30 @@ var webgl_layer = function () {
'use strict';
var m_this = this,
+ s_visible = this.visible,
s_zIndex = this.zIndex;
+ /**
+ * Get/Set visibility of the layer.
+ *
+ * @param {boolean} [val] If specified, change the visibility. Otherwise,
+ * get it.
+ * @returns {boolean|this} either the visibility (if getting) or the layer
+ * (if setting).
+ */
+ this.visible = function (val) {
+ if (val === undefined) {
+ return s_visible();
+ }
+ var origVal = s_visible(),
+ result = s_visible.apply(m_this, arguments);
+ if (origVal !== val && m_this.initialized()) {
+ m_this.map().scheduleAnimationFrame(m_this._update, true);
+ m_this.renderer()._render();
+ }
+ return result;
+ };
+
/**
* Get or set the z-index of the layer. The z-index controls the display
* order of the layers in much the same way as the CSS z-index property.
@@ -19,7 +41,7 @@ var webgl_layer = function () {
*/
this.zIndex = function (zIndex, allowDuplicate) {
var result = s_zIndex.apply(m_this, arguments);
- if (zIndex !== undefined) {
+ if (zIndex !== undefined && m_this.initialized()) {
/* If the z-index has changed, schedule rerendering the layer. */
m_this.map().scheduleAnimationFrame(m_this._update, true);
m_this.renderer()._render();

MODIFY
src/webgl/object.js
src/webgl/object.js
@@ -38,8 +38,24 @@ var webgl_object = function (arg) {
if (this.bin) {
var s_bin = this.bin;
+ /**
+ * Get/Set bin of the feature. The bin number is used to determine the
+ * order of multiple features on the same layer. It has no effect except
+ * on the webgl renderer. A negative value hides the feature without
+ * stopping interaction with it. Otherwise, features with higher bin
+ * numbers are drawn above those with lower bin numbers. If two features
+ * have the same bin number, their order relative to one another is
+ * indeterminate and may be unstable.
+ *
+ * @param {number} [val] The new bin number. If `undefined`, return the
+ * current bin number. If `null`, the bin is dynamically computed based
+ * on order within the parent. If children are nested, this may not be
+ * what is desired.
+ * @param {boolean} [actualValue] If truthy and `val` is undefined, return
+ * the actual value of bin, rather than the dynamically computed value.
+ * @returns {number|this} The current bin number or a reference to `this`.
+ */
this.bin = function (val, actualValue) {
-
if (val === undefined && !actualValue && s_bin(undefined, true) === null) {
var layer = m_this.layer && m_this.layer(),
map = layer && layer.map && layer.map(),

MODIFY
src/webgl/quadFeature.js
src/webgl/quadFeature.js
@@ -411,11 +411,11 @@ var webgl_quadFeature = function (arg) {
m_this._build();
}
if (m_actor_color) {
- m_actor_color.setVisible(m_this.visible(undefined, true));
+ m_actor_color.setVisible(m_this.visible());
m_actor_color.material().setBinNumber(m_this.bin());
}
if (m_actor_image) {
- m_actor_image.setVisible(m_this.visible(undefined, true));
+ m_actor_image.setVisible(m_this.visible());
m_actor_image.material().setBinNumber(m_this.bin());
}
m_this.updateTime().modified();

MODIFY
src/webgl/tileLayer.js
src/webgl/tileLayer.js
@@ -6,6 +6,8 @@ var webgl_tileLayer = function () {
var m_this = this,
s_init = this._init,
s_exit = this._exit,
+ s_update = this._update,
+ s_visible = this.visible,
s_zIndex = this.zIndex,
m_quadFeature,
m_nextTileId = 0,
@@ -97,6 +99,26 @@ var webgl_tileLayer = function () {
}
};
+ /**
+ * Get/Set visibility of the layer.
+ *
+ * @param {boolean} [val] If specified, change the visibility, otherwise
+ * return it.
+ * @returns {boolean|this} The current visibility or the layer.
+ */
+ this.visible = function (val) {
+ if (val === undefined) {
+ return s_visible();
+ }
+ if (m_this.visible() !== val) {
+ s_visible(val);
+ if (m_quadFeature) {
+ m_quadFeature.visible(m_quadFeature.visible(undefined, true), true);
+ }
+ }
+ return m_this;
+ };
+
/**
* Get or set the z-index of the layer. The z-index controls the display
* order of the layers in much the same way as the CSS z-index property.
@@ -120,6 +142,20 @@ var webgl_tileLayer = function () {
return s_zIndex.apply(m_this, arguments);
};
+ /**
+ * Update layer.
+ *
+ * @param {object} request A value to pass to the parent class.
+ * @returns {this}
+ */
+ this._update = function (request) {
+ s_update.call(m_this, request);
+ if (m_quadFeature) {
+ m_quadFeature._update();
+ }
+ return m_this;
+ };
+
/**
* Clean up the layer.
*/

MODIFY
tests/cases/osmLayer.js
tests/cases/osmLayer.js
@@ -438,6 +438,27 @@ describe('geo.core.osmLayer', function () {
vgl.mockCounts().uniform2fv >= (glCounts.uniform2fv || 0) + 9);
});
+ it('test that tiles aren\'t loaded when not visible', function () {
+ glCounts = $.extend({}, vgl.mockCounts());
+ layer.visible(false);
+ });
+ waitForIt('map to draw after visible false', function () {
+ return vgl.mockCounts().clear >= glCounts.clear;
+ });
+ it('zoom in', function () {
+ glCounts = $.extend({}, vgl.mockCounts());
+ map.zoom(5);
+ });
+ waitForIt('map to draw after zoom', function () {
+ return vgl.mockCounts().clear >= glCounts.clear;
+ });
+ it('test that tiles load when visibility returns', function () {
+ expect(Object.keys(layer.activeTiles).length).toBe(21);
+ layer.visible(true);
+ });
+ waitForIt('map to draw after visible true', function () {
+ return Object.keys(layer.activeTiles).length === 25;
+ });
it('destroy', destroy_map);
});
});

Handle visibility between layers sharing a webgl renderer.