Literal Style / add support for color interpolation

This commit is contained in:
Olivier Guyot
2019-10-22 18:55:48 +02:00
parent 85c3aae454
commit 485ade42b5
3 changed files with 61 additions and 32 deletions

View File

@@ -17,11 +17,15 @@
* * `['time']` returns the time in seconds since the creation of the layer
*
* * Math operators:
* * `['*', value1, value1]` multiplies value1 by value2
* * `['+', value1, value1]` adds value1 and value2
* * `['clamp', value1, value2, value3]` clamps value1 between values2 and value3
* * `['stretch', value1, value2, value3, value4, value5]` maps value1 from [value2, value3] range to
* [value4, value5] range, clamping values along the way
* * `['*', value1, value1]` multiplies `value1` by `value2`
* * `['+', value1, value1]` adds `value1` and `value2`
* * `['clamp', value, low, high]` clamps `value` between `low` and `high`
* * `['stretch', value, low1, high1, low2, high2]` maps `value` from [`low1`, `high1`] range to
* [`low2`, `high2`] range, clamping values along the way
*
* * Color operators:
* * `['interpolate', ratio, color1, color2]` returns a color through interpolation between `color1` and
* `color2` with the given `ratio`
*
* * Logical operators:
* * `['<', value1, value2]` returns `1` if `value1` is strictly lower than value 2, or `0` otherwise.
@@ -33,9 +37,13 @@
* * `['between', value1, value2, value3]` returns `1` if `value1` is contained between `value2` and `value3`
* (inclusively), or `0` otherwise.
*
* Values can either be literals (numbers) or another operator, as they will be evaluated recursively.
* Values can either be literals or another operator, as they will be evaluated recursively.
* Literal values can be of the following types:
* * `number`
* * `string`
* * {@link module:ol/color~Color}
*
* @typedef {Array<*>|number} ExpressionValue
* @typedef {Array<*>|import("../color.js").Color|string|number} ExpressionValue
*/
/**

View File

@@ -642,11 +642,7 @@ export function parseLiteralStyle(style) {
const symbStyle = style.symbol;
const size = Array.isArray(symbStyle.size) && typeof symbStyle.size[0] == 'number' ?
symbStyle.size : [symbStyle.size, symbStyle.size];
const color = (typeof symbStyle.color === 'string' ?
asArray(symbStyle.color).map(function(c, i) {
return i < 3 ? c / 255 : c;
}) :
symbStyle.color || [255, 255, 255, 1]);
const color = symbStyle.color || 'white';
const texCoord = symbStyle.textureCoord || [0, 0, 1, 1];
const offset = symbStyle.offset || [0, 0];
const opacity = symbStyle.opacity !== undefined ? symbStyle.opacity : 1;
@@ -660,8 +656,8 @@ export function parseLiteralStyle(style) {
const fragAttributes = [];
// parse function for fragment shader
function pFrag(value) {
return parse(value, fragAttributes, 'v_', variables);
function pFrag(value, type) {
return parse(value, fragAttributes, 'v_', variables, type);
}
let opacityFilter = '1.0';
@@ -682,6 +678,8 @@ export function parseLiteralStyle(style) {
default: throw new Error('Unexpected symbol type: ' + symbStyle.symbolType);
}
const parsedColor = pFrag(color, ValueTypes.COLOR);
const builder = new ShaderBuilder()
.setSizeExpression(`vec2(${pVert(size[0])}, ${pVert(size[1])})`)
.setSymbolOffsetExpression(`vec2(${pVert(offset[0])}, ${pVert(offset[1])})`)
@@ -689,7 +687,7 @@ export function parseLiteralStyle(style) {
`vec4(${pVert(texCoord[0])}, ${pVert(texCoord[1])}, ${pVert(texCoord[2])}, ${pVert(texCoord[3])})`)
.setSymbolRotateWithView(!!symbStyle.rotateWithView)
.setColorExpression(
`vec4(${pFrag(color[0])}, ${pFrag(color[1])}, ${pFrag(color[2])}, ${pFrag(color[3])} * ${pFrag(opacity)} * ${opacityFilter})`);
`vec4(${parsedColor}.rgb, ${parsedColor}.a * ${pFrag(opacity)} * ${opacityFilter})`);
if (style.filter) {
builder.setFragmentDiscardExpression(`${pFrag(style.filter)} <= 0.0`);