or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

brushing.mddata-filtering.mdgeometry-operations.mdindex.mdlegacy-experimental.mdstyling.md
tile.json

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