feat(extensions): add StrokeStyleExtension for dashed strokes on SDF layers#9976
feat(extensions): add StrokeStyleExtension for dashed strokes on SDF layers#9976chrisgervang wants to merge 8 commits intomasterfrom
Conversation
105108f to
4fb089b
Compare
Add a new StrokeStyleExtension that enables rendering dashed strokes on ScatterplotLayer circle outlines. This implements feature request #9864. The extension uses shader injection to calculate dash patterns based on the angle around the circle's circumference. It supports: - getDashArray accessor: [solidLength, gapLength] relative to stroke width - dashGapPickable prop: controls whether gaps are pickable When a circle is both stroked and filled, the fill color shows through the gaps. When only stroked (no fill), fragments in gaps are discarded. https://claude.ai/code/session_01KsGs1v7AGFNXyvMUhjaiFm
…ndLayer Add support for dashed strokes on TextBackgroundLayer rectangles in addition to ScatterplotLayer circles. The extension now auto-detects the layer type and uses the appropriate shader injection: - ScatterplotLayer: angle-based dash calculation around circle circumference - TextBackgroundLayer: perimeter-based dash calculation around rectangle edges No performance impact on ScatterplotLayer since each layer type gets only its specific shader code at compile time. https://claude.ai/code/session_01KsGs1v7AGFNXyvMUhjaiFm
…calculation The perimeter position calculation now properly accounts for rounded corners in TextBackgroundLayer. When borderRadius is set: - Corner arcs are included in the perimeter length calculation - Position along corner arcs uses angle-based interpolation - Each corner can have a different radius (vec4 borderRadius) This ensures dash patterns flow smoothly around rounded corners without discontinuities. https://claude.ai/code/session_01KsGs1v7AGFNXyvMUhjaiFm
Add comprehensive documentation for the new StrokeStyleExtension including: - Usage examples for ScatterplotLayer and TextBackgroundLayer - API reference for getDashArray and dashGapPickable props - Explanation of how dash calculation works for circles vs rectangles - Comparison table with PathStyleExtension - Details on rounded corner support for TextBackgroundLayer https://claude.ai/code/session_01KsGs1v7AGFNXyvMUhjaiFm
- Add examples/stroke-style-test for interactive testing - Apply linter formatting to test file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…sion docs TextBackgroundLayer is an internal layer without its own documentation page. Link to TextLayer instead since TextBackgroundLayer is used internally by it. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…eStyleExtension - Fix corner angle formulas to correctly produce angles in range [0, PI/2] - Fix edge detection to use distance-based comparison instead of diagonal-based which failed for non-square rectangles - Simplify test app data for clearer demonstration Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
71c76f9 to
c30b251
Compare
For ScatterplotLayer with both fill and stroke, dash gaps now correctly show the fill color instead of discarding the fragment. Also re-applies autoHighlight effect to the fill color in gaps. Test app updates: - Use shared vite.config.local.mjs instead of custom config - Add fill-only comparison circle for size comparison - Enable autoHighlight on comparison circle Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| // In dash gap - discard unless picking gaps | ||
| if (!(strokeStyle.dashGapPickable && bool(picking.isActive))) { | ||
| discard; | ||
| } |
There was a problem hiding this comment.
TextBackgroundLayer dash gaps discard fill color
High Severity
The textBackgroundDashShaders unconditionally discards fragments in dash gaps, but TextBackgroundLayer always has a fill. This creates transparent holes at the rectangle's edge where the fill color should show through. The scatterplot shader correctly handles this by setting a strokeStyle_inDashGap flag and overriding the color with vFillColor in an fs:#main-end injection, but the TextBackgroundLayer shader has no such fs:#main-end injection — it just discards.
Additional Locations (1)
| * Detect which layer type this is to use the appropriate shader injections | ||
| */ | ||
| private getLayerType(layer: Layer<StrokeStyleExtensionProps>): SupportedLayerType { | ||
| const layerName = layer.constructor.name; |
There was a problem hiding this comment.
Layer detection uses minifiable constructor.name instead of layerName
Medium Severity
getLayerType reads layer.constructor.name for detection, but JavaScript class names get mangled in minified production builds. deck.gl layers provide a static layerName property (e.g. 'ScatterplotLayer') specifically to survive minification — the framework's own toString() method uses (this.constructor as typeof Layer).layerName for this reason. The prop-based fallback ('radiusScale' in layer.props) mitigates this but is less reliable and could match unintended layers.


Summary
Implements feature request #9864 - adds
StrokeStyleExtensionto enable dashed strokes on SDF-based layers.Supported Layers
New Props (via extension)
getDashArray:[dashSize, gapSize]relative to stroke widthdashGapPickable: Whether gaps are pickable (default:false)Usage
https://claude.ai/code/session_01KsGs1v7AGFNXyvMUhjaiFm
Note
Medium Risk
Opt-in shader injection adds new dashed-stroke rendering/picking paths for
ScatterplotLayerandTextBackgroundLayer, which could introduce subtle visual or picking regressions for layers using the extension. Changes are otherwise additive with new docs/tests/examples to validate output.Overview
Adds a new
StrokeStyleExtensionthat enables dashed strokes for SDF-based stroked layers, exposinggetDashArrayanddashGapPickableand injecting layer-specific shader code forScatterplotLayer(angle-based dashes) andTextBackgroundLayer(perimeter/rounded-corner dashes).Exports the extension from
@deck.gl/extensions, documents it in the extensions API reference and TOC, and adds an example app plus new unit and golden-image render tests covering dashed filled and stroked-only scatterplots.Written by Cursor Bugbot for commit ffa78a6. This will update automatically on new commits. Configure here.