Skip to content

Commit

Permalink
feat(Style): use defineStyleCategory() for all
Browse files Browse the repository at this point in the history
  • Loading branch information
ftoromanoff committed Jan 31, 2025
1 parent e7bf0d3 commit 6edff5b
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 115 deletions.
102 changes: 13 additions & 89 deletions src/Core/Style.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,14 @@ function defineStyleCategory(style, category, userValue) {
return value;
}
style[category] = {};
value = userValue;
if (userValue instanceof Function) { // always true
value = { ...userValue };
if (userValue instanceof Function) {
value = readExpression(userValue, style.context);
}
defaultRules[category].keys.forEach((key) => {
defineStyleProperty(style, category, key, value[key], defaultRules[category].defaultValue[key]);
defineStyleProperty(style, category, key, value[key], defaultRules[category].defaultValue?.[key]);// zoom has no defaultValue
});
defaultRules[category].ifKeys.forEach((key) => {
defaultRules[category].ifKeys?.forEach((key) => { // zoom, stroke, text and icon have no ifKeys
if (value[key] != undefined) {
defineStyleProperty(style, category, key, value[key]);
}
Expand Down Expand Up @@ -545,93 +545,17 @@ class Style {
params.text = params.text || {};
params.icon = params.icon || {};

if (params.zoom instanceof Function) {
defineStyleCategory(this, 'zoom', params.zoom);
} else {
this.zoom = {};
defineStyleProperty(this, 'zoom', 'min', params.zoom.min);
defineStyleProperty(this, 'zoom', 'max', params.zoom.max);
}

if (params.fill instanceof Function) {
defineStyleCategory(this, 'fill', params.fill);
} else {
this.fill = {};
defineStyleProperty(this, 'fill', 'color', params.fill.color);
defineStyleProperty(this, 'fill', 'opacity', params.fill.opacity, 1.0);
defineStyleProperty(this, 'fill', 'pattern', params.fill.pattern);
defineStyleProperty(this, 'fill', 'base_altitude', params.fill.base_altitude, baseAltitudeDefault);
if (params.fill.extrusion_height) {
defineStyleProperty(this, 'fill', 'extrusion_height', params.fill.extrusion_height);
}
}

if (params.stroke instanceof Function) {
defineStyleCategory(this, 'stroke', params.stroke);
} else {
this.stroke = {};
defineStyleProperty(this, 'stroke', 'color', params.stroke.color);
defineStyleProperty(this, 'stroke', 'opacity', params.stroke.opacity, 1.0);
defineStyleProperty(this, 'stroke', 'width', params.stroke.width, 1.0);
defineStyleProperty(this, 'stroke', 'dasharray', params.stroke.dasharray, []);
defineStyleProperty(this, 'stroke', 'base_altitude', params.stroke.base_altitude, baseAltitudeDefault);
}

if (params.point instanceof Function) {
defineStyleCategory(this, 'point', params.point);
} else {
this.point = {};
defineStyleProperty(this, 'point', 'color', params.point.color);
defineStyleProperty(this, 'point', 'line', params.point.line);
defineStyleProperty(this, 'point', 'opacity', params.point.opacity, 1.0);
defineStyleProperty(this, 'point', 'radius', params.point.radius, 2.0);
defineStyleProperty(this, 'point', 'width', params.point.width, 0.0);
defineStyleProperty(this, 'point', 'base_altitude', params.point.base_altitude, baseAltitudeDefault);
if (params.point.model) {
defineStyleProperty(this, 'point', 'model', params.point.model);
}
if (params.icon.key) {
console.warn("'icon.key' is deprecated: use 'icon.id' instead");
params.icon.id = params.icon.key;
}

if (params.text instanceof Function) {
defineStyleCategory(this, 'text', params.text);
} else {
this.text = {};
defineStyleProperty(this, 'text', 'field', params.text.field);
defineStyleProperty(this, 'text', 'zOrder', params.text.zOrder, 'auto');
defineStyleProperty(this, 'text', 'color', params.text.color, '#000000');
defineStyleProperty(this, 'text', 'anchor', params.text.anchor, 'center');
defineStyleProperty(this, 'text', 'offset', params.text.offset, [0, 0]);
defineStyleProperty(this, 'text', 'padding', params.text.padding, 2);
defineStyleProperty(this, 'text', 'size', params.text.size, 16);
defineStyleProperty(this, 'text', 'placement', params.text.placement, 'point');
defineStyleProperty(this, 'text', 'rotation', params.text.rotation, 'auto');
defineStyleProperty(this, 'text', 'wrap', params.text.wrap, 10);
defineStyleProperty(this, 'text', 'spacing', params.text.spacing, 0);
defineStyleProperty(this, 'text', 'transform', params.text.transform, 'none');
defineStyleProperty(this, 'text', 'justify', params.text.justify, 'center');
defineStyleProperty(this, 'text', 'opacity', params.text.opacity, 1.0);
defineStyleProperty(this, 'text', 'font', params.text.font, ['Open Sans Regular', 'Arial Unicode MS Regular', 'sans-serif']);
defineStyleProperty(this, 'text', 'haloColor', params.text.haloColor, '#000000');
defineStyleProperty(this, 'text', 'haloWidth', params.text.haloWidth, 0);
defineStyleProperty(this, 'text', 'haloBlur', params.text.haloBlur, 0);
}

if (params.icon instanceof Function) {
defineStyleCategory(this, 'icon', params.icon);
} else {
this.icon = {};
defineStyleProperty(this, 'icon', 'source', params.icon.source);
if (params.icon.key) {
console.warn("'icon.key' is deprecated: use 'icon.id' instead");
params.icon.id = params.icon.key;
}
defineStyleProperty(this, 'icon', 'id', params.icon.id);
defineStyleProperty(this, 'icon', 'cropValues', params.icon.cropValues);
defineStyleProperty(this, 'icon', 'anchor', params.icon.anchor, 'center');
defineStyleProperty(this, 'icon', 'size', params.icon.size, 1);
defineStyleProperty(this, 'icon', 'color', params.icon.color);
defineStyleProperty(this, 'icon', 'opacity', params.icon.opacity, 1.0);
}
defineStyleCategory(this, 'zoom', params.zoom);
defineStyleCategory(this, 'fill', params.fill);
defineStyleCategory(this, 'stroke', params.stroke);
defineStyleCategory(this, 'point', params.point);
defineStyleCategory(this, 'text', params.text);
defineStyleCategory(this, 'icon', params.icon);
}

setContext(ctx) {
Expand Down
89 changes: 63 additions & 26 deletions test/unit/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,34 @@ describe('Style', function () {
stubFetcherTexture.restore();
});

const styleOpt = {
fill: {
color: 'blue',
opacity: {
stops: [[10, '{opacity}']], // Mapbox vectorTile
},
pattern: {
// Mock MapBox StyleExpression() instance
expression: { evaluate: () => 'pattern' },
it('Instanciate style from styleOpt and context', function _it() {
const styleOpt = {
fill: {
color: 'blue',
opacity: {
stops: [[10, '{opacity}']], // Mapbox vectorTile
},
pattern: {
// Mock MapBox StyleExpression() instance
expression: { evaluate: () => 'pattern' },
},
extrusion_height: {
stops: [[10, (p, ctx) => 10 + ctx.coordinates.z]],
},
},
extrusion_height: {
stops: [[10, (p, ctx) => 10 + ctx.coordinates.z]],
};
const ctx = {
coordinates: { z: -2 },
properties: {
opacity: -3,
},
},
};
const ctx = {
coordinates: { z: -2 },
properties: {
opacity: -3,
},
};

const style = new Style(styleOpt);
style.point.color = 'red';
style.setContext(ctx);
// mock StyleContext() instance
style.context.featureStyle = { stroke: { color: 'pink' } };
};
const style = new Style(styleOpt);
style.point.color = 'red';
style.setContext(ctx);
// mock StyleContext() instance
style.context.featureStyle = { stroke: { color: 'pink' } };

it('Instanciate style from styleOpt and context', function _it() {
// no default value
assert.equal(style.point.line, undefined);
// defaultValue is value
Expand All @@ -82,6 +81,44 @@ describe('Style', function () {
assert.equal(style.stroke.color, 'pink');
});

it('Instanciate style from fct at category level', function _it() {
const fill = () => ({
color: 'blue',
opacity: {
stops: [[10, '{opacity}']], // Mapbox vectorTile
},
pattern: {
// Mock MapBox StyleExpression() instance
expression: { evaluate: () => 'pattern' },
},
extrusion_height: {
stops: [[10, (p, ctx) => 10 + ctx.coordinates.z]],
},
});
const styleOpt = {
fill,
};
const ctx = {
coordinates: { z: -2 },
properties: {
opacity: -3,
},
};
const style = new Style(styleOpt);
style.setContext(ctx);
// mock StyleContext() instance
style.context.featureStyle = { stroke: { color: 'pink' } };

// userValue
assert.equal(style.fill.color, fill().color);
// userValue with stops & {}
assert.equal(style.fill.opacity, ctx.properties.opacity);
// userValue as MapBox expression
assert.equal(style.fill.pattern, fill().pattern.expression.evaluate());
// userValue with stops & function
assert.equal(style.fill.extrusion_height, fill().extrusion_height.stops[0][1](2, ctx));
});

describe('applyToCanvasPolygon()', () => {
const styleOpt = {
point: {},
Expand Down

0 comments on commit 6edff5b

Please sign in to comment.