CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-deck-gl--extensions

Plug-and-play extension system providing advanced functionalities for deck.gl layers including brushing, filtering, styling, clipping, collision detection, masking, and terrain rendering capabilities.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

styling.mddocs/

Path and Shape Styling

Advanced styling capabilities for path-based and fill-based layers, including dash patterns, path offsets, and texture-based pattern fills for enhanced visual representation.

import { PathStyleExtension, FillStyleExtension } from "@deck.gl/extensions";
import type {
  PathStyleExtensionProps,
  PathStyleExtensionOptions,
  FillStyleExtensionProps,
  FillStyleExtensionOptions,
  FillStyleModuleProps
} from "@deck.gl/extensions";

Capabilities

PathStyleExtension

Adds dash and offset capabilities to PathLayer and composite layers that render paths, enabling advanced line styling and positioning.

/**
 * Adds selected features to the PathLayer and composite layers that render the PathLayer
 * Provides dash and offset capabilities for advanced path styling
 */
class PathStyleExtension extends LayerExtension<PathStyleExtensionOptions> {
  static extensionName: 'PathStyleExtension';
  static defaultProps: PathStyleExtensionDefaultProps;
  
  constructor(options?: Partial<PathStyleExtensionOptions>);
  
  isEnabled(layer: Layer): boolean;
  getShaders(extension: this): any;
  initializeState(context: LayerContext, extension: this): void;
  updateState(params: UpdateParameters, extension: this): void;
  getDashOffsets(path: number[] | number[][]): number[];
}

interface PathStyleExtensionProps<DataT = any> {
  /**
   * Accessor for dash array [dashSize, gapSize] for each path.
   * Only effective if dash option is enabled.
   * @default {type: 'accessor', value: [0, 0]}
   */
  getDashArray?: Accessor<DataT, [number, number]>;
  
  /**
   * Accessor for path offset (perpendicular to path direction) for each path.
   * Positive values offset to the right, negative to the left.
   * Only effective if offset option is enabled.
   * @default {type: 'accessor', value: 0}
   */
  getOffset?: Accessor<DataT, number>;
  
  /**
   * If true, adjust dash pattern to align with path length.
   * Ensures dashes start and end at path endpoints.
   * @default false
   */
  dashJustified?: boolean;
  
  /**
   * If true, gaps in dash patterns are pickable (respond to mouse events).
   * If false, only the dash segments are pickable.
   * @default false
   */
  dashGapPickable?: boolean;
}

interface PathStyleExtensionOptions {
  /**
   * Enable dash pattern functionality.
   * @default false
   */
  dash: boolean;
  
  /**
   * Enable path offset functionality.
   * @default false
   */
  offset: boolean;
  
  /**
   * Use high-precision dash calculations for very long paths.
   * @default false
   */
  highPrecisionDash: boolean;
}

interface PathStyleExtensionDefaultProps {
  getDashArray: {type: 'accessor', value: [0, 0]};
  getOffset: {type: 'accessor', value: 0};
  dashJustified: false;
  dashGapPickable: false;
}

FillStyleExtension

Adds pattern fill capabilities to layers that render fills, such as PolygonLayer and ScatterplotLayer, enabling texture-based pattern rendering.

/**
 * Adds selected features to layers that render a "fill"
 * Provides pattern filling capability using texture atlases
 */
class FillStyleExtension extends LayerExtension<FillStyleExtensionOptions> {
  static extensionName: 'FillStyleExtension';
  static defaultProps: FillStyleExtensionDefaultProps;
  
  constructor(options?: Partial<FillStyleExtensionOptions>);
  
  isEnabled(layer: Layer): boolean;
  getShaders(extension: this): any;
  initializeState(context: LayerContext, extension: this): void;
  updateState(params: UpdateParameters, extension: this): void;
  draw(params: any, extension: this): void;
  finalizeState(): void;
  getPatternFrame(name: string): number[];
}

interface FillStyleExtensionProps<DataT = any> {
  /**
   * Enable/disable pattern fill functionality.
   * @default true
   */
  fillPatternEnabled?: boolean;
  
  /**
   * Texture atlas containing pattern images.
   * Can be a URL string or texture source object.
   */
  fillPatternAtlas?: string | TextureSource;
  
  /**
   * Mapping of pattern names to their positions in the atlas.
   * Can be a URL to JSON mapping or mapping object.
   */
  fillPatternMapping?: string | Record<string, PatternFrame>;
  
  /**
   * If true, pattern acts as a mask (shows through base color).
   * If false, pattern replaces the base color entirely.
   * @default true
   */
  fillPatternMask?: boolean;
  
  /**
   * Accessor to retrieve pattern name for each object.
   * @default d => d.pattern
   */
  getFillPattern?: AccessorFunction<DataT, string>;
  
  /**
   * Accessor for pattern scale factor for each object.
   * @default {type: 'accessor', value: 1}
   */
  getFillPatternScale?: Accessor<DataT, number>;
  
  /**
   * Accessor for pattern offset [x, y] for each object.
   * @default {type: 'accessor', value: [0, 0]}
   */
  getFillPatternOffset?: Accessor<DataT, [number, number]>;
}

interface FillStyleExtensionOptions {
  /**
   * Enable pattern fill functionality.
   * @default false
   */
  pattern: boolean;
}

interface FillStyleExtensionDefaultProps {
  fillPatternEnabled: true;
  fillPatternAtlas: {type: 'image', value: null, async: true, parameters: {lodMaxClamp: 0}};
  fillPatternMapping: {type: 'object', value: {}, async: true};
  fillPatternMask: true;
  getFillPattern: {type: 'accessor', value: (d: any) => d.pattern};
  getFillPatternScale: {type: 'accessor', value: 1};
  getFillPatternOffset: {type: 'accessor', value: [0, 0]};
}

interface PatternFrame {
  x: number;
  y: number;
  width: number;
  height: number;
}

interface TextureSource {
  // WebGL texture or image source
}

interface FillStyleModuleProps {
  project: ProjectProps;
  fillPatternEnabled?: boolean;
  fillPatternMask?: boolean;
  fillPatternTexture: Texture;
}

Usage Examples:

import { PathLayer, PolygonLayer } from "@deck.gl/layers";
import { PathStyleExtension, FillStyleExtension } from "@deck.gl/extensions";

// Dashed path lines
const dashedPathLayer = new PathLayer({
  id: "dashed-paths",
  data: pathData,
  extensions: [new PathStyleExtension({ dash: true })],
  getPath: d => d.coordinates,
  getDashArray: d => [20, 10], // 20 unit dash, 10 unit gap
  dashJustified: true, // Align dashes with path endpoints
  getWidth: 5
});

// Offset paths (useful for multiple lanes)
const offsetPathLayer = new PathLayer({
  id: "offset-paths", 
  data: roadData,
  extensions: [new PathStyleExtension({ offset: true })],
  getPath: d => d.centerline,
  getOffset: d => d.laneOffset, // Offset from centerline
  getWidth: 3
});

// Combined dash and offset
const styledPathLayer = new PathLayer({
  id: "styled-paths",
  data: pathData,
  extensions: [new PathStyleExtension({ dash: true, offset: true })],
  getPath: d => d.coordinates,
  getDashArray: d => d.style === 'dotted' ? [5, 5] : [0, 0],
  getOffset: d => d.side === 'right' ? 10 : -10,
  dashGapPickable: false, // Only dash segments are clickable
  getWidth: 2
});

// Pattern-filled polygons
const patternPolygonLayer = new PolygonLayer({
  id: "pattern-polygons",
  data: polygonData,
  extensions: [new FillStyleExtension({ pattern: true })],
  getPolygon: d => d.coordinates,
  fillPatternAtlas: './patterns.png', // Texture atlas image
  fillPatternMapping: './patterns.json', // Pattern mapping file
  getFillPattern: d => d.patternType, // Pattern name from data
  getFillPatternScale: d => d.scale || 1,
  getFillPatternOffset: [0, 0],
  fillPatternMask: true // Pattern shows through base color
});

// Dynamic pattern scaling and positioning
const dynamicPatternLayer = new PolygonLayer({
  id: "dynamic-patterns",
  data: polygonData,
  extensions: [new FillStyleExtension({ pattern: true })],
  getPolygon: d => d.coordinates,
  fillPatternAtlas: patternTexture,
  fillPatternMapping: {
    'stripes': { x: 0, y: 0, width: 64, height: 64 },
    'dots': { x: 64, y: 0, width: 64, height: 64 },
    'crosshatch': { x: 0, y: 64, width: 64, height: 64 }
  },
  getFillPattern: d => d.pattern,
  getFillPatternScale: d => d.density, // Scale based on data
  getFillPatternOffset: d => [d.offsetX, d.offsetY], // Custom offset
  fillPatternMask: false // Replace base color entirely
});

Advanced Styling Techniques

High-Precision Dashes

// For very long paths requiring precise dash calculations
const precisionDashLayer = new PathLayer({
  extensions: [new PathStyleExtension({ 
    dash: true, 
    highPrecisionDash: true 
  })],
  getPath: d => d.longPath, // Very long geographical path
  getDashArray: [1000, 500], // Large dash pattern in meters
  dashJustified: true
});

Pattern Atlas Management

// Using a pre-loaded texture atlas
const textureAtlas = device.createTexture({
  data: patternImage,
  width: 256,
  height: 256
});

const patternLayer = new PolygonLayer({
  extensions: [new FillStyleExtension({ pattern: true })],
  fillPatternAtlas: textureAtlas,
  fillPatternMapping: {
    'brick': { x: 0, y: 0, width: 64, height: 64 },
    'wood': { x: 64, y: 0, width: 64, height: 64 },
    'metal': { x: 0, y: 64, width: 64, height: 64 }
  }
});

Conditional Styling

// Apply styling based on data properties
const conditionalStyledLayer = new PathLayer({
  extensions: [new PathStyleExtension({ dash: true, offset: true })],
  getDashArray: d => {
    switch(d.roadType) {
      case 'highway': return [0, 0]; // Solid line
      case 'local': return [10, 5]; // Dashed
      case 'trail': return [5, 10]; // Dotted
      default: return [0, 0];
    }
  },
  getOffset: d => d.direction === 'eastbound' ? 5 : -5
});

Performance Considerations

  • Dash calculations are performed on the GPU for optimal performance
  • Pattern fills use texture atlases to minimize GPU memory usage
  • High-precision dash mode has minimal performance impact for most use cases
  • Offset calculations add negligible overhead to path rendering
  • Pattern scaling and offset are computed per-vertex on the GPU

Compatibility

PathStyleExtension

  • Compatible with: PathLayer, ArcLayer, LineLayer, and composite layers using these
  • Supports both WebGL and WebGPU rendering backends
  • Can be combined with other extensions (filtering, brushing, etc.)

FillStyleExtension

  • Compatible with: PolygonLayer, ScatterplotLayer, IconLayer, and other fill-based layers
  • Requires texture atlas and pattern mapping for pattern fills
  • Works with both static and dynamic pattern assignments
  • Supports asynchronous loading of pattern resources

Install with Tessl CLI

npx tessl i tessl/npm-deck-gl--extensions

docs

brushing.md

data-filtering.md

geometry-operations.md

index.md

legacy-experimental.md

styling.md

tile.json