Skip to content

Commit

Permalink
pickingLineWidthExtraPixels prop (uber#694)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorDykhta authored Feb 4, 2022
1 parent c8d9c03 commit 7f2f94d
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/api-reference/layers/editable-geojson-layer.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,12 @@ Number of pixels around the mouse cursor used for picking. This value determines

Number of layers of overlapping features that will be picked. Useful in cases where features overlap.

#### `pickingLineWidthExtraPixels` (Number, optional)

- Default: `0`

Additional line width in pixels used for picking. Can be useful when `EditableGeojsonLayer` is over a deck.gl layer and precise picking is problematic, and when usage of `pickingDepth` introduces performance issues.

### Sub Layers

`EditableGeoJsonLayer` renders the following sub-layers:
Expand Down
5 changes: 5 additions & 0 deletions modules/layers/src/layers/editable-geojson-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
import { PROJECTED_PIXEL_SIZE_MULTIPLIER } from '../constants';

import EditableLayer, { EditableLayerProps } from './editable-layer';
import EditablePathLayer from './editable-path-layer';

const DEFAULT_LINE_COLOR: RGBAColor = [0x0, 0x0, 0x0, 0x99];
const DEFAULT_FILL_COLOR: RGBAColor = [0x0, 0x0, 0x0, 0x90];
Expand Down Expand Up @@ -120,6 +121,7 @@ export interface EditableGeojsonLayerProps<D> extends EditableLayerProps<D> {
lineWidthScale?: number;
lineWidthMinPixels?: number;
lineWidthMaxPixels?: number;
pickingLineWidthExtraPixels?: number;
lineWidthUnits?: string;
lineJointRounded?: boolean;
lineCapRounded?: boolean;
Expand Down Expand Up @@ -178,6 +180,7 @@ const defaultProps: EditableGeojsonLayerProps<any> = {
lineWidthScale: PROJECTED_PIXEL_SIZE_MULTIPLIER,
lineWidthMinPixels: 1,
lineWidthMaxPixels: Number.MAX_SAFE_INTEGER,
pickingLineWidthExtraPixels: 0,
lineWidthUnits: 'pixels',
lineJointRounded: false,
lineCapRounded: false,
Expand Down Expand Up @@ -306,6 +309,8 @@ export default class EditableGeoJsonLayer extends EditableLayer<
},
'polygons-stroke': {
billboard: this.props.billboard,
pickingLineWidthExtraPixels: this.props.pickingLineWidthExtraPixels,
type: EditablePathLayer,
updateTriggers: {
// required to update dashed array attribute
all: [this.props.selectedFeatureIndexes, this.props.mode],
Expand Down
51 changes: 51 additions & 0 deletions modules/layers/src/layers/editable-path-layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { PathLayer, PathLayerProps } from '@deck.gl/layers';

import { insertBefore } from '../utils';

interface EditablePathLayerProps extends PathLayerProps<any> {
pickingLineWidthExtraPixels?: number;
}

const defaultProps = {
...PathLayer.defaultProps,
pickingLineWidthExtraPixels: { type: 'number', min: 0, value: Number.MAX_SAFE_INTEGER },
};

export default class EditablePathLayer extends PathLayer<any, EditablePathLayerProps> {
getShaders() {
const shaders = super.getShaders();

shaders.vs = insertBefore(
shaders.vs,
'vec3 width;',
`
if(picking_uActive){
widthPixels.xy += pickingLineWidthExtraPixels;
}
`
);

return {
...shaders,
inject: {
...(shaders.inject || {}),
'vs:#decl': (shaders.inject?.['vs:#decl'] || '').concat(
`uniform float pickingLineWidthExtraPixels;`
),
},
};
}

draw(props) {
super.draw({
...props,
uniforms: {
...props.uniforms,
pickingLineWidthExtraPixels: this.props.pickingLineWidthExtraPixels,
},
});
}
}

EditablePathLayer.defaultProps = defaultProps;
EditablePathLayer.layerName = 'EditablePathLayer';
15 changes: 15 additions & 0 deletions modules/layers/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,18 @@ export function nearestPointOnProjectedLine(
},
};
}

/**
* Inserts toInsert string into base string before insertBefore string.
* @param base A string to insert into.
* @param insertBefore A sub string in `base` string to insert before.
* @param toInsert A string to insert.
* @returns Combined string. `base` string if `insertBefore` string isn't found.
*/
export function insertBefore(base: string, insertBefore: string, toInsert: string): string {
const at = base.indexOf(insertBefore);
if (at < 0) {
return base;
}
return base.slice(0, at) + toInsert + base.slice(at);
}

0 comments on commit 7f2f94d

Please sign in to comment.