Skip to content

Commit

Permalink
added(display): Line dashes now support dynamic StyleExpressions with…
Browse files Browse the repository at this point in the history
… intermediate zoom level support.

Signed-off-by: Tim Deubler <[email protected]>
  • Loading branch information
TerminalTim committed Nov 27, 2024
1 parent c974a4d commit 07066c9
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 15 deletions.
6 changes: 3 additions & 3 deletions packages/display/src/displays/styleTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,9 @@ const parseStyleGroup = (styleGroup: readonly(Style & { __p?: true })[], expPars
for (let name in style) {
if (name in parsePropertyNames) {
const value = style[name];
const skipExpressions = name == 'strokeDasharray';

if (!skipExpressions && ExpressionParser.isJSONExp(value)) {
if (ExpressionParser.isJSONExp(value) && (
name != 'strokeDasharray' || isNaN(value[0].charAt(0))
)) {
// if (name != 'strokeDasharray' || typeof parseInt(value[0]) != 'number') {
style[name] = expParser.parseJSON(value);
// }
Expand Down
22 changes: 14 additions & 8 deletions packages/display/src/displays/webgl/buffer/FeatureFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ type ZDrawGroup = {

export type GroupMap = { [zIndex: string]: ZDrawGroup };

const isDynamicProperty = (prop: any) => prop instanceof Expression;
export const isDynamicProperty = (prop: any) => prop instanceof Expression;
// const isDynamicProperty = (prop: any) => typeof prop == 'function';

const DYNAMIC_MODE = 1;
let dynamicValueId = 0;
const PIXEL_UNITS = ['px', 'px'];

export class FeatureFactory {
private readonly gl: WebGLRenderingContext;
Expand Down Expand Up @@ -588,10 +588,16 @@ export class FeatureFactory {
offsetUnit +
strokeLinecap +
strokeLinejoin;
strokeDasharray = getValue('strokeDasharray', style, feature, level);

strokeDasharray = getValue('strokeDasharray', style, feature, level, DYNAMIC_MODE);

if (Array.isArray(strokeDasharray) && strokeDasharray[0]) {
if (isDynamicProperty(strokeDasharray)) {
groupId += (strokeDasharray as Expression).id();
strokeDasharray = {
pattern: strokeDasharray,
units: PIXEL_UNITS
};
} else if (Array.isArray(strokeDasharray) && strokeDasharray[0]) {
let pattern = [];
let units = [];

Expand All @@ -602,16 +608,16 @@ export class FeatureFactory {

groupId += size + unit;
}

strokeDasharray = {pattern, units};
} else {
strokeDasharray = UNDEF;
}

if (strokeDasharray) {
strokeDashimage = getValue('strokeDashimage', style, feature, level);

if (strokeDashimage) {
groupId += strokeDashimage.slice(-8);
}
} else {
strokeDasharray = UNDEF;
}
} else {
strokeWidth = getValue('strokeWidth', style, feature, level);
Expand Down
8 changes: 5 additions & 3 deletions packages/display/src/displays/webgl/buffer/LineFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {GeoJSONCoordinate as Coordinate, Tile} from '@here/xyz-maps-core';
import {CollisionData, CollisionHandler} from '../CollisionHandler';
import {DistanceGroup} from './DistanceGroup';
import {FlexAttribute} from './templates/TemplateBuffer';
import {isDynamicProperty} from './FeatureFactory';

const TO_DEG = 180 / Math.PI;
const DEFAULT_MIN_REPEAT = 256;
Expand Down Expand Up @@ -169,16 +170,17 @@ export class LineFactory {
const groupBuffer: LineBuffer = group.buffer;

if (strokeDasharray) {
// Multiple dash/gap combinations are exclusively supported within the same unit due to the utilization of a pattern texture.
if (strokeDasharray.pattern.length > 2 &&
if (!isDynamicProperty(strokeDasharray.pattern) &&
// Multiple dash/gap combinations are exclusively supported within the same unit due to the utilization of a pattern texture.
strokeDasharray.pattern.length > 2 &&
// has mixed units
!strokeDasharray.units.some((e) => e != strokeDasharray.units[0])
) {
const dashPatternTexture = this.dashes.get(strokeDasharray.pattern);
groupBuffer.addUniform('u_dashPattern', dashPatternTexture.texture);
groupBuffer.addUniform('u_dashSize', [dashPatternTexture.texture.width / dashPatternTexture.scale, 0]);
} else {
groupBuffer.addUniform('u_dashSize', [strokeDasharray.pattern[0], strokeDasharray.pattern[1]]);
groupBuffer.addUniform('u_dashSize', strokeDasharray.pattern);
}
}

Expand Down
10 changes: 9 additions & 1 deletion packages/display/src/displays/webgl/buffer/createBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
webMercator
} from '@here/xyz-maps-core';
import {Layer} from '../../Layers';
import {CollisionGroup, FeatureFactory, GroupMap} from './FeatureFactory';
import {CollisionGroup, FeatureFactory, GroupMap, isDynamicProperty} from './FeatureFactory';
import {GlyphTexture} from '../GlyphTexture';
import {TemplateBufferBucket} from './templates/TemplateBufferBucket';
import {Texture} from '../Texture';
Expand Down Expand Up @@ -213,17 +213,24 @@ const createBuffer = (
if (type == 'Line') {
if (shared.strokeDasharray) {
geoBuffer.type = 'DashedLine';

// if (isDynamicProperty(shared.strokeDasharray)) {
// geoBuffer.addUniform('u_dashUnit', [0, 0]);
// } else {
geoBuffer.addUniform('u_dashUnit', [
shared.strokeDasharray.units[0] == 'm' ? meterToPixel : 0,
shared.strokeDasharray.units[1] == 'm' ? meterToPixel : 0
]);
// }
}
// scissor un-clipped geometry in any case...(huge geometry possible)
// otherwise clipping can be skipped to avoid strokeWidth cutoffs close to tile edges
geoBuffer.clip = !tile.clipped;

geoBuffer.addUniform('u_fill', stroke);

// if (isDynamicProperty(shared.strokeWidth)) debugger;

geoBuffer.addUniform('u_strokeWidth', [strokeWidth, shared.unit == 'm' ? meterToPixel : 0]);
// geoBuffer.addUniform('u_strokeWidth', [strokeWidth * .5, shared.unit == 'm' ? meterToPixel : 0]);

Expand Down Expand Up @@ -417,6 +424,7 @@ const createBuffer = (
}
}
}
// console.log('buffers', buffers);
onDone(buffers.reverse(), pendingResources);
},

Expand Down

0 comments on commit 07066c9

Please sign in to comment.