Add hue and saturation controls, thanks @evanw
This commit is contained in:
@@ -9,7 +9,9 @@ goog.require('ol.Store');
|
|||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
ol.LayerProperty = {
|
ol.LayerProperty = {
|
||||||
|
HUE: 'hue',
|
||||||
OPACITY: 'opacity',
|
OPACITY: 'opacity',
|
||||||
|
SATURATION: 'saturation',
|
||||||
VISIBLE: 'visible'
|
VISIBLE: 'visible'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -32,7 +34,9 @@ ol.Layer = function(store, opt_values) {
|
|||||||
this.store_ = store;
|
this.store_ = store;
|
||||||
|
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
|
this.setHue(0);
|
||||||
this.setOpacity(1);
|
this.setOpacity(1);
|
||||||
|
this.setSaturation(0);
|
||||||
|
|
||||||
if (goog.isDef(opt_values)) {
|
if (goog.isDef(opt_values)) {
|
||||||
this.setValues(opt_values);
|
this.setValues(opt_values);
|
||||||
@@ -42,6 +46,14 @@ ol.Layer = function(store, opt_values) {
|
|||||||
goog.inherits(ol.Layer, ol.Object);
|
goog.inherits(ol.Layer, ol.Object);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} Hue.
|
||||||
|
*/
|
||||||
|
ol.Layer.prototype.getHue = function() {
|
||||||
|
return /** @type {number} */ this.get(ol.LayerProperty.HUE);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {number} Opacity.
|
* @return {number} Opacity.
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +63,14 @@ ol.Layer.prototype.getOpacity = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} Saturation.
|
||||||
|
*/
|
||||||
|
ol.Layer.prototype.getSaturation = function() {
|
||||||
|
return /** @type {number} */ this.get(ol.LayerProperty.SATURATION);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {ol.Store} Store.
|
* @return {ol.Store} Store.
|
||||||
*/
|
*/
|
||||||
@@ -68,6 +88,14 @@ ol.Layer.prototype.getVisible = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} hue Hue.
|
||||||
|
*/
|
||||||
|
ol.Layer.prototype.setHue = function(hue) {
|
||||||
|
this.set(ol.LayerProperty.HUE, hue);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} opacity Opacity.
|
* @param {number} opacity Opacity.
|
||||||
*/
|
*/
|
||||||
@@ -76,6 +104,14 @@ ol.Layer.prototype.setOpacity = function(opacity) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} saturation Saturation.
|
||||||
|
*/
|
||||||
|
ol.Layer.prototype.setSaturation = function(saturation) {
|
||||||
|
this.set(ol.LayerProperty.SATURATION, saturation);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {boolean} visible Visible.
|
* @param {boolean} visible Visible.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -29,10 +29,18 @@ ol.LayerRenderer = function(map, layer) {
|
|||||||
*/
|
*/
|
||||||
this.layer_ = layer;
|
this.layer_ = layer;
|
||||||
|
|
||||||
|
goog.events.listen(this.layer_,
|
||||||
|
ol.Object.getChangedEventType(ol.LayerProperty.HUE),
|
||||||
|
this.handleLayerHueChange, false, this);
|
||||||
|
|
||||||
goog.events.listen(this.layer_,
|
goog.events.listen(this.layer_,
|
||||||
ol.Object.getChangedEventType(ol.LayerProperty.OPACITY),
|
ol.Object.getChangedEventType(ol.LayerProperty.OPACITY),
|
||||||
this.handleLayerOpacityChange, false, this);
|
this.handleLayerOpacityChange, false, this);
|
||||||
|
|
||||||
|
goog.events.listen(this.layer_,
|
||||||
|
ol.Object.getChangedEventType(ol.LayerProperty.SATURATION),
|
||||||
|
this.handleLayerSaturationChange, false, this);
|
||||||
|
|
||||||
goog.events.listen(this.layer_,
|
goog.events.listen(this.layer_,
|
||||||
ol.Object.getChangedEventType(ol.LayerProperty.VISIBLE),
|
ol.Object.getChangedEventType(ol.LayerProperty.VISIBLE),
|
||||||
this.handleLayerVisibleChange, false, this);
|
this.handleLayerVisibleChange, false, this);
|
||||||
@@ -57,12 +65,24 @@ ol.LayerRenderer.prototype.getMap = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
ol.LayerRenderer.prototype.handleLayerHueChange = goog.nullFunction;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
ol.LayerRenderer.prototype.handleLayerOpacityChange = goog.nullFunction;
|
ol.LayerRenderer.prototype.handleLayerOpacityChange = goog.nullFunction;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
ol.LayerRenderer.prototype.handleLayerSaturationChange = goog.nullFunction;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -56,6 +56,14 @@ ol.webgl.LayerRenderer.prototype.getMap = function() {
|
|||||||
ol.webgl.LayerRenderer.prototype.getMatrix = goog.abstractMethod;
|
ol.webgl.LayerRenderer.prototype.getMatrix = goog.abstractMethod;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.webgl.LayerRenderer.prototype.handleLayerHueChange = function() {
|
||||||
|
this.dispatchChangeEvent();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -64,6 +72,14 @@ ol.webgl.LayerRenderer.prototype.handleLayerOpacityChange = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.webgl.LayerRenderer.prototype.handleLayerSaturationChange = function() {
|
||||||
|
this.dispatchChangeEvent();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
+33
-3
@@ -34,22 +34,46 @@ ol.DEBUG_WEBGL = false;
|
|||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @extends {ol.webgl.shader.Fragment}
|
* @extends {ol.webgl.shader.Fragment}
|
||||||
|
* @see https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/huesaturation.js
|
||||||
*/
|
*/
|
||||||
ol.webgl.map.shader.Fragment = function() {
|
ol.webgl.map.shader.Fragment = function() {
|
||||||
goog.base(this, [
|
goog.base(this, [
|
||||||
'precision mediump float;',
|
'precision mediump float;',
|
||||||
'',
|
'',
|
||||||
'uniform mat4 uMatrix;',
|
'uniform mat4 uMatrix;',
|
||||||
|
'uniform float uHue;',
|
||||||
'uniform float uOpacity;',
|
'uniform float uOpacity;',
|
||||||
|
'uniform float uSaturation;',
|
||||||
'uniform sampler2D uTexture;',
|
'uniform sampler2D uTexture;',
|
||||||
'',
|
'',
|
||||||
'varying vec2 vTexCoord;',
|
'varying vec2 vTexCoord;',
|
||||||
'',
|
'',
|
||||||
'void main(void) {',
|
'void main(void) {',
|
||||||
' vec4 texCoord = uMatrix * vec4(vTexCoord, 0., 1.);',
|
' vec4 texCoord = uMatrix * vec4(vTexCoord, 0., 1.);',
|
||||||
' vec4 srcColor = texture2D(uTexture, texCoord.st);',
|
' vec4 color = texture2D(uTexture, texCoord.st);',
|
||||||
' gl_FragColor.rgb = srcColor.rgb;',
|
'',
|
||||||
' gl_FragColor.a = srcColor.a * uOpacity;',
|
' float angle = uHue * 3.14159265;',
|
||||||
|
' float s = sin(angle), c = cos(angle);',
|
||||||
|
' vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c)',
|
||||||
|
' + 1.0) / 3.0;',
|
||||||
|
' float len = length(color.rgb);',
|
||||||
|
' color.rgb = vec3(',
|
||||||
|
' dot(color.rgb, weights.xyz),',
|
||||||
|
' dot(color.rgb, weights.zxy),',
|
||||||
|
' dot(color.rgb, weights.yzx)',
|
||||||
|
' );',
|
||||||
|
' ',
|
||||||
|
' float average = (color.r + color.g + color.b) / 3.0;',
|
||||||
|
' if (uSaturation > 0.0) {',
|
||||||
|
' color.rgb += (average - color.rgb)',
|
||||||
|
' * (1.0 - 1.0 / (1.001 - uSaturation));',
|
||||||
|
' } else if (uSaturation < 0.0) {',
|
||||||
|
' color.rgb += (average - color.rgb) * (-uSaturation);',
|
||||||
|
' }',
|
||||||
|
'',
|
||||||
|
' color.a = color.a * uOpacity;',
|
||||||
|
'',
|
||||||
|
' gl_FragColor = color;',
|
||||||
'}'
|
'}'
|
||||||
].join('\n'));
|
].join('\n'));
|
||||||
};
|
};
|
||||||
@@ -132,8 +156,10 @@ ol.webgl.Map = function(target, opt_values) {
|
|||||||
* @private
|
* @private
|
||||||
* @type {{aPosition: number,
|
* @type {{aPosition: number,
|
||||||
* aTexCoord: number,
|
* aTexCoord: number,
|
||||||
|
* uHue: WebGLUniformLocation,
|
||||||
* uMatrix: WebGLUniformLocation,
|
* uMatrix: WebGLUniformLocation,
|
||||||
* uOpacity: WebGLUniformLocation,
|
* uOpacity: WebGLUniformLocation,
|
||||||
|
* uSaturation: WebGLUniformLocation,
|
||||||
* uTexture: WebGLUniformLocation}|null}
|
* uTexture: WebGLUniformLocation}|null}
|
||||||
*/
|
*/
|
||||||
this.locations_ = null;
|
this.locations_ = null;
|
||||||
@@ -458,8 +484,10 @@ ol.webgl.Map.prototype.renderInternal = function() {
|
|||||||
this.locations_ = {
|
this.locations_ = {
|
||||||
aPosition: gl.getAttribLocation(program, 'aPosition'),
|
aPosition: gl.getAttribLocation(program, 'aPosition'),
|
||||||
aTexCoord: gl.getAttribLocation(program, 'aTexCoord'),
|
aTexCoord: gl.getAttribLocation(program, 'aTexCoord'),
|
||||||
|
uHue: gl.getUniformLocation(program, 'uHue'),
|
||||||
uMatrix: gl.getUniformLocation(program, 'uMatrix'),
|
uMatrix: gl.getUniformLocation(program, 'uMatrix'),
|
||||||
uOpacity: gl.getUniformLocation(program, 'uOpacity'),
|
uOpacity: gl.getUniformLocation(program, 'uOpacity'),
|
||||||
|
uSaturation: gl.getUniformLocation(program, 'uSaturation'),
|
||||||
uTexture: gl.getUniformLocation(program, 'uTexture')
|
uTexture: gl.getUniformLocation(program, 'uTexture')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -489,7 +517,9 @@ ol.webgl.Map.prototype.renderInternal = function() {
|
|||||||
this.forEachVisibleLayer(function(layer, layerRenderer) {
|
this.forEachVisibleLayer(function(layer, layerRenderer) {
|
||||||
gl.uniformMatrix4fv(
|
gl.uniformMatrix4fv(
|
||||||
this.locations_.uMatrix, false, layerRenderer.getMatrix());
|
this.locations_.uMatrix, false, layerRenderer.getMatrix());
|
||||||
|
gl.uniform1f(this.locations_.uHue, layer.getHue());
|
||||||
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());
|
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());
|
||||||
|
gl.uniform1f(this.locations_.uSaturation, layer.getSaturation());
|
||||||
gl.bindTexture(goog.webgl.TEXTURE_2D, layerRenderer.getTexture());
|
gl.bindTexture(goog.webgl.TEXTURE_2D, layerRenderer.getTexture());
|
||||||
gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4);
|
gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4);
|
||||||
}, this);
|
}, this);
|
||||||
|
|||||||
Reference in New Issue
Block a user