@deck.gl/extensions 9.3.0-alpha.6 → 9.3.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dist.dev.js CHANGED
@@ -2736,7 +2736,7 @@ vec4 project_position_to_clipspace(
2736
2736
  var Fp64Extension = class extends import_core6.LayerExtension {
2737
2737
  getShaders() {
2738
2738
  const { coordinateSystem } = this.props;
2739
- if (coordinateSystem !== import_core6.COORDINATE_SYSTEM.LNGLAT && coordinateSystem !== import_core6.COORDINATE_SYSTEM.DEFAULT) {
2739
+ if (coordinateSystem !== "lnglat" && coordinateSystem !== "default") {
2740
2740
  throw new Error("fp64: coordinateSystem must be LNGLAT");
2741
2741
  }
2742
2742
  return {
@@ -2825,6 +2825,209 @@ in float vDashOffset;
2825
2825
  }
2826
2826
  }
2827
2827
  }
2828
+ `
2829
+ }
2830
+ };
2831
+ var scatterplotDashShaders = {
2832
+ inject: {
2833
+ "vs:#decl": `
2834
+ in vec2 instanceDashArrays;
2835
+ out vec2 vDashArray;
2836
+ `,
2837
+ "vs:#main-end": `
2838
+ vDashArray = instanceDashArrays;
2839
+ `,
2840
+ "fs:#decl": `
2841
+ layout(std140) uniform pathStyleUniforms {
2842
+ bool dashGapPickable;
2843
+ } pathStyle;
2844
+
2845
+ in vec2 vDashArray;
2846
+
2847
+ #define PI 3.141592653589793
2848
+ `,
2849
+ "fs:#main-start": `
2850
+ bool inDashGap = false;
2851
+ float dashUnitLength = vDashArray.x + vDashArray.y;
2852
+ if (dashUnitLength > 0.0 && scatterplot.stroked > 0.5) {
2853
+ float _distToCenter = length(unitPosition) * outerRadiusPixels;
2854
+ float innerRadius = innerUnitRadius * outerRadiusPixels;
2855
+ if (_distToCenter >= innerRadius) {
2856
+ float strokeWidth = (1.0 - innerUnitRadius) * outerRadiusPixels;
2857
+ float midStrokeRadius = (innerUnitRadius + 1.0) * 0.5 * outerRadiusPixels;
2858
+ float angle = atan(unitPosition.y, unitPosition.x) + PI;
2859
+ float circumference = 2.0 * PI * midStrokeRadius;
2860
+ float posAlongStroke = (angle / (2.0 * PI)) * circumference / strokeWidth;
2861
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
2862
+ if (unitOffset > vDashArray.x) {
2863
+ if (scatterplot.filled > 0.5) {
2864
+ inDashGap = true;
2865
+ } else {
2866
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
2867
+ discard;
2868
+ }
2869
+ }
2870
+ }
2871
+ }
2872
+ }
2873
+ `,
2874
+ "fs:#main-end": `
2875
+ if (inDashGap) {
2876
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
2877
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
2878
+ fragColor = picking_filterPickingColor(fragColor);
2879
+ fragColor = picking_filterHighlightColor(fragColor);
2880
+ }
2881
+ `
2882
+ }
2883
+ };
2884
+ var textBackgroundDashShaders = {
2885
+ inject: {
2886
+ "vs:#decl": `
2887
+ in vec2 instanceDashArrays;
2888
+ out vec2 vDashArray;
2889
+ `,
2890
+ "vs:#main-end": `
2891
+ vDashArray = instanceDashArrays;
2892
+ `,
2893
+ "fs:#decl": `
2894
+ layout(std140) uniform pathStyleUniforms {
2895
+ bool dashGapPickable;
2896
+ } pathStyle;
2897
+
2898
+ in vec2 vDashArray;
2899
+
2900
+ #define PI 3.141592653589793
2901
+
2902
+ // Calculate position along rounded rectangle perimeter in stroke-width units
2903
+ float getPerimeterPosition(vec2 fragUV, vec2 dims, vec4 radii, float lineWidth) {
2904
+ float width = dims.x;
2905
+ float height = dims.y;
2906
+
2907
+ float maxRadius = min(width, height) * 0.5;
2908
+ float rBL = min(radii.w, maxRadius);
2909
+ float rTL = min(radii.z, maxRadius);
2910
+ float rTR = min(radii.x, maxRadius);
2911
+ float rBR = min(radii.y, maxRadius);
2912
+
2913
+ vec2 p = fragUV * dims;
2914
+
2915
+ float leftLen = height - rBL - rTL;
2916
+ float topLen = width - rTL - rTR;
2917
+ float rightLen = height - rTR - rBR;
2918
+ float bottomLen = width - rBR - rBL;
2919
+
2920
+ float arcBL = PI * 0.5 * rBL;
2921
+ float arcTL = PI * 0.5 * rTL;
2922
+ float arcTR = PI * 0.5 * rTR;
2923
+ float arcBR = PI * 0.5 * rBR;
2924
+
2925
+ float pos = 0.0;
2926
+
2927
+ float distLeft = p.x;
2928
+ float distRight = width - p.x;
2929
+ float distBottom = p.y;
2930
+ float distTop = height - p.y;
2931
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
2932
+
2933
+ if (p.x < rBL && p.y < rBL) {
2934
+ vec2 c = vec2(rBL, rBL);
2935
+ vec2 d = p - c;
2936
+ float angle = atan(-d.x, -d.y);
2937
+ pos = angle / (PI * 0.5) * arcBL;
2938
+ } else if (p.x < rTL && p.y > height - rTL) {
2939
+ vec2 c = vec2(rTL, height - rTL);
2940
+ vec2 d = p - c;
2941
+ float angle = atan(d.y, -d.x);
2942
+ pos = arcBL + leftLen + angle / (PI * 0.5) * arcTL;
2943
+ } else if (p.x > width - rTR && p.y > height - rTR) {
2944
+ vec2 c = vec2(width - rTR, height - rTR);
2945
+ vec2 d = p - c;
2946
+ float angle = atan(d.x, d.y);
2947
+ pos = arcBL + leftLen + arcTL + topLen + angle / (PI * 0.5) * arcTR;
2948
+ } else if (p.x > width - rBR && p.y < rBR) {
2949
+ vec2 c = vec2(width - rBR, rBR);
2950
+ vec2 d = p - c;
2951
+ float angle = atan(-d.y, d.x);
2952
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + angle / (PI * 0.5) * arcBR;
2953
+ } else if (minDist == distLeft) {
2954
+ pos = arcBL + clamp(p.y - rBL, 0.0, leftLen);
2955
+ } else if (minDist == distTop) {
2956
+ pos = arcBL + leftLen + arcTL + clamp(p.x - rTL, 0.0, topLen);
2957
+ } else if (minDist == distRight) {
2958
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + clamp(height - rTR - p.y, 0.0, rightLen);
2959
+ } else {
2960
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + arcBR + clamp(width - rBR - p.x, 0.0, bottomLen);
2961
+ }
2962
+
2963
+ return pos / lineWidth;
2964
+ }
2965
+
2966
+ // Simple rectangular perimeter calculation (no rounded corners)
2967
+ float getRectPerimeterPosition(vec2 fragUV, vec2 dims, float lineWidth) {
2968
+ float width = dims.x;
2969
+ float height = dims.y;
2970
+
2971
+ float distLeft = fragUV.x * width;
2972
+ float distRight = (1.0 - fragUV.x) * width;
2973
+ float distBottom = fragUV.y * height;
2974
+ float distTop = (1.0 - fragUV.y) * height;
2975
+
2976
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
2977
+
2978
+ float pos = 0.0;
2979
+ if (minDist == distLeft) {
2980
+ pos = fragUV.y * height;
2981
+ } else if (minDist == distTop) {
2982
+ pos = height + fragUV.x * width;
2983
+ } else if (minDist == distRight) {
2984
+ pos = height + width + (1.0 - fragUV.y) * height;
2985
+ } else {
2986
+ pos = 2.0 * height + width + (1.0 - fragUV.x) * width;
2987
+ }
2988
+
2989
+ return pos / lineWidth;
2990
+ }
2991
+ `,
2992
+ "fs:#main-start": `
2993
+ bool inDashGap = false;
2994
+ float dashUnitLength = vDashArray.x + vDashArray.y;
2995
+ if (dashUnitLength > 0.0 && textBackground.stroked) {
2996
+ float distToEdge;
2997
+ bool hasRoundedCorners = textBackground.borderRadius != vec4(0.0);
2998
+ if (hasRoundedCorners) {
2999
+ distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
3000
+ } else {
3001
+ distToEdge = rect(uv, dimensions);
3002
+ }
3003
+
3004
+ if (distToEdge <= vLineWidth && distToEdge >= 0.0) {
3005
+ float posAlongStroke;
3006
+ if (hasRoundedCorners) {
3007
+ posAlongStroke = getPerimeterPosition(uv, dimensions, textBackground.borderRadius, vLineWidth);
3008
+ } else {
3009
+ posAlongStroke = getRectPerimeterPosition(uv, dimensions, vLineWidth);
3010
+ }
3011
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
3012
+ if (unitOffset > vDashArray.x) {
3013
+ if (vFillColor.a > 0.0) {
3014
+ inDashGap = true;
3015
+ } else {
3016
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
3017
+ discard;
3018
+ }
3019
+ }
3020
+ }
3021
+ }
3022
+ }
3023
+ `,
3024
+ "fs:#main-end": `
3025
+ if (inDashGap) {
3026
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
3027
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
3028
+ fragColor = picking_filterPickingColor(fragColor);
3029
+ fragColor = picking_filterHighlightColor(fragColor);
3030
+ }
2828
3031
  `
2829
3032
  }
2830
3033
  };
@@ -2869,13 +3072,41 @@ in float instanceOffsets;
2869
3072
  } = {}) {
2870
3073
  super({ dash: dash || highPrecisionDash, offset, highPrecisionDash });
2871
3074
  }
3075
+ getLayerType(layer) {
3076
+ if ("pathTesselator" in layer.state) {
3077
+ return "path";
3078
+ }
3079
+ const layerName = layer.constructor.layerName;
3080
+ if (layerName === "ScatterplotLayer") {
3081
+ return "scatterplot";
3082
+ }
3083
+ if (layerName === "TextBackgroundLayer") {
3084
+ return "textBackground";
3085
+ }
3086
+ return null;
3087
+ }
2872
3088
  isEnabled(layer) {
2873
- return "pathTesselator" in layer.state;
3089
+ return this.getLayerType(layer) !== null;
2874
3090
  }
2875
3091
  getShaders(extension) {
2876
- if (!extension.isEnabled(this)) {
3092
+ const layerType = extension.getLayerType(this);
3093
+ if (!layerType) {
2877
3094
  return null;
2878
3095
  }
3096
+ if (layerType === "scatterplot" || layerType === "textBackground") {
3097
+ if (!extension.opts.dash) {
3098
+ return null;
3099
+ }
3100
+ const inject7 = layerType === "scatterplot" ? scatterplotDashShaders.inject : textBackgroundDashShaders.inject;
3101
+ const pathStyle2 = {
3102
+ name: "pathStyle",
3103
+ inject: inject7,
3104
+ uniformTypes: {
3105
+ dashGapPickable: "i32"
3106
+ }
3107
+ };
3108
+ return { modules: [pathStyle2] };
3109
+ }
2879
3110
  let result = {};
2880
3111
  const defines = {};
2881
3112
  if (extension.opts.dash) {
@@ -2903,13 +3134,14 @@ in float instanceOffsets;
2903
3134
  }
2904
3135
  initializeState(context, extension) {
2905
3136
  const attributeManager = this.getAttributeManager();
2906
- if (!attributeManager || !extension.isEnabled(this)) {
3137
+ const layerType = extension.getLayerType(this);
3138
+ if (!attributeManager || !layerType) {
2907
3139
  return;
2908
3140
  }
2909
3141
  if (extension.opts.dash) {
2910
3142
  attributeManager.addInstanced({
2911
3143
  instanceDashArrays: { size: 2, accessor: "getDashArray" },
2912
- ...extension.opts.highPrecisionDash ? {
3144
+ ...layerType === "path" && extension.opts.highPrecisionDash ? {
2913
3145
  instanceDashOffsets: {
2914
3146
  size: 1,
2915
3147
  accessor: "getPath",
@@ -2918,7 +3150,7 @@ in float instanceOffsets;
2918
3150
  } : {}
2919
3151
  });
2920
3152
  }
2921
- if (extension.opts.offset) {
3153
+ if (layerType === "path" && extension.opts.offset) {
2922
3154
  attributeManager.addInstanced({
2923
3155
  instanceOffsets: { size: 1, accessor: "getOffset" }
2924
3156
  });
@@ -2929,11 +3161,19 @@ in float instanceOffsets;
2929
3161
  return;
2930
3162
  }
2931
3163
  if (extension.opts.dash) {
2932
- const pathStyleProps = {
2933
- dashAlignMode: this.props.dashJustified ? 1 : 0,
2934
- dashGapPickable: Boolean(this.props.dashGapPickable)
2935
- };
2936
- this.setShaderModuleProps({ pathStyle: pathStyleProps });
3164
+ const layerType = extension.getLayerType(this);
3165
+ if (layerType === "scatterplot" || layerType === "textBackground") {
3166
+ const pathStyleProps = {
3167
+ dashGapPickable: Boolean(this.props.dashGapPickable)
3168
+ };
3169
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
3170
+ } else {
3171
+ const pathStyleProps = {
3172
+ dashAlignMode: this.props.dashJustified ? 1 : 0,
3173
+ dashGapPickable: Boolean(this.props.dashGapPickable)
3174
+ };
3175
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
3176
+ }
2937
3177
  }
2938
3178
  }
2939
3179
  getDashOffsets(path) {
@@ -1 +1 @@
1
- {"version":3,"file":"fp64-extension.d.ts","sourceRoot":"","sources":["../../src/fp64/fp64-extension.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,cAAc,EAAoB,MAAM,eAAe,CAAC;AAGhE,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEzC,yEAAyE;AACzE,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,cAAc;IACvD,MAAM,CAAC,aAAa,SAAmB;IAEvC,UAAU,CAAC,IAAI,EAAE,KAAK,GAAG,GAAG;IAc5B,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI;CAItD"}
1
+ {"version":3,"file":"fp64-extension.d.ts","sourceRoot":"","sources":["../../src/fp64/fp64-extension.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAC;AAG7C,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEzC,yEAAyE;AACzE,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,cAAc;IACvD,MAAM,CAAC,aAAa,SAAmB;IAEvC,UAAU,CAAC,IAAI,EAAE,KAAK,GAAG,GAAG;IAW5B,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI;CAItD"}
@@ -1,14 +1,13 @@
1
1
  // deck.gl
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
- import { LayerExtension, COORDINATE_SYSTEM } from '@deck.gl/core';
4
+ import { LayerExtension } from '@deck.gl/core';
5
5
  import project64 from "./project64.js";
6
6
  /** @deprecated Adds the legacy 64-bit precision to geospatial layers. */
7
7
  class Fp64Extension extends LayerExtension {
8
8
  getShaders() {
9
9
  const { coordinateSystem } = this.props;
10
- if (coordinateSystem !== COORDINATE_SYSTEM.LNGLAT &&
11
- coordinateSystem !== COORDINATE_SYSTEM.DEFAULT) {
10
+ if (coordinateSystem !== 'lnglat' && coordinateSystem !== 'default') {
12
11
  throw new Error('fp64: coordinateSystem must be LNGLAT');
13
12
  }
14
13
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"fp64-extension.js","sourceRoot":"","sources":["../../src/fp64/fp64-extension.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EAAC,cAAc,EAAE,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,SAAS,uBAAoB;AAIpC,yEAAyE;AACzE,MAAqB,aAAc,SAAQ,cAAc;IAGvD,UAAU;QACR,MAAM,EAAC,gBAAgB,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACtC,IACE,gBAAgB,KAAK,iBAAiB,CAAC,MAAM;YAC7C,gBAAgB,KAAK,iBAAiB,CAAC,OAAO,EAC9C,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,SAAS,CAAC;SACrB,CAAC;IACJ,CAAC;IAED,IAAI,CAAc,MAAW,EAAE,SAAe;QAC5C,MAAM,EAAC,QAAQ,EAAC,GAAG,MAAM,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,oBAAoB,CAAC,EAAC,SAAS,EAAE,EAAC,QAAQ,EAAC,EAAC,CAAC,CAAC;IACrD,CAAC;;AAnBM,2BAAa,GAAG,eAAe,CAAC;eADpB,aAAa"}
1
+ {"version":3,"file":"fp64-extension.js","sourceRoot":"","sources":["../../src/fp64/fp64-extension.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAC;AAC7C,OAAO,SAAS,uBAAoB;AAIpC,yEAAyE;AACzE,MAAqB,aAAc,SAAQ,cAAc;IAGvD,UAAU;QACR,MAAM,EAAC,gBAAgB,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACtC,IAAI,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACpE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO;YACL,OAAO,EAAE,CAAC,SAAS,CAAC;SACrB,CAAC;IACJ,CAAC;IAED,IAAI,CAAc,MAAW,EAAE,SAAe;QAC5C,MAAM,EAAC,QAAQ,EAAC,GAAG,MAAM,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,oBAAoB,CAAC,EAAC,SAAS,EAAE,EAAC,QAAQ,EAAC,EAAC,CAAC,CAAC;IACrD,CAAC;;AAhBM,2BAAa,GAAG,eAAe,CAAC;eADpB,aAAa"}
package/dist/index.cjs CHANGED
@@ -1012,7 +1012,7 @@ function calculateUniforms({ viewProjectionMatrix, scale }) {
1012
1012
  var Fp64Extension = class extends import_core5.LayerExtension {
1013
1013
  getShaders() {
1014
1014
  const { coordinateSystem } = this.props;
1015
- if (coordinateSystem !== import_core5.COORDINATE_SYSTEM.LNGLAT && coordinateSystem !== import_core5.COORDINATE_SYSTEM.DEFAULT) {
1015
+ if (coordinateSystem !== "lnglat" && coordinateSystem !== "default") {
1016
1016
  throw new Error("fp64: coordinateSystem must be LNGLAT");
1017
1017
  }
1018
1018
  return {
@@ -1100,6 +1100,188 @@ discard;
1100
1100
  `
1101
1101
  }
1102
1102
  };
1103
+ var scatterplotDashShaders = {
1104
+ inject: {
1105
+ "vs:#decl": `
1106
+ in vec2 instanceDashArrays;
1107
+ out vec2 vDashArray;
1108
+ `,
1109
+ "vs:#main-end": `
1110
+ vDashArray = instanceDashArrays;
1111
+ `,
1112
+ "fs:#decl": `
1113
+ layout(std140) uniform pathStyleUniforms {
1114
+ bool dashGapPickable;
1115
+ } pathStyle;
1116
+ in vec2 vDashArray;
1117
+ #define PI 3.141592653589793
1118
+ `,
1119
+ "fs:#main-start": `
1120
+ bool inDashGap = false;
1121
+ float dashUnitLength = vDashArray.x + vDashArray.y;
1122
+ if (dashUnitLength > 0.0 && scatterplot.stroked > 0.5) {
1123
+ float _distToCenter = length(unitPosition) * outerRadiusPixels;
1124
+ float innerRadius = innerUnitRadius * outerRadiusPixels;
1125
+ if (_distToCenter >= innerRadius) {
1126
+ float strokeWidth = (1.0 - innerUnitRadius) * outerRadiusPixels;
1127
+ float midStrokeRadius = (innerUnitRadius + 1.0) * 0.5 * outerRadiusPixels;
1128
+ float angle = atan(unitPosition.y, unitPosition.x) + PI;
1129
+ float circumference = 2.0 * PI * midStrokeRadius;
1130
+ float posAlongStroke = (angle / (2.0 * PI)) * circumference / strokeWidth;
1131
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
1132
+ if (unitOffset > vDashArray.x) {
1133
+ if (scatterplot.filled > 0.5) {
1134
+ inDashGap = true;
1135
+ } else {
1136
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
1137
+ discard;
1138
+ }
1139
+ }
1140
+ }
1141
+ }
1142
+ }
1143
+ `,
1144
+ "fs:#main-end": `
1145
+ if (inDashGap) {
1146
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
1147
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
1148
+ fragColor = picking_filterPickingColor(fragColor);
1149
+ fragColor = picking_filterHighlightColor(fragColor);
1150
+ }
1151
+ `
1152
+ }
1153
+ };
1154
+ var textBackgroundDashShaders = {
1155
+ inject: {
1156
+ "vs:#decl": `
1157
+ in vec2 instanceDashArrays;
1158
+ out vec2 vDashArray;
1159
+ `,
1160
+ "vs:#main-end": `
1161
+ vDashArray = instanceDashArrays;
1162
+ `,
1163
+ "fs:#decl": `
1164
+ layout(std140) uniform pathStyleUniforms {
1165
+ bool dashGapPickable;
1166
+ } pathStyle;
1167
+ in vec2 vDashArray;
1168
+ #define PI 3.141592653589793
1169
+ float getPerimeterPosition(vec2 fragUV, vec2 dims, vec4 radii, float lineWidth) {
1170
+ float width = dims.x;
1171
+ float height = dims.y;
1172
+ float maxRadius = min(width, height) * 0.5;
1173
+ float rBL = min(radii.w, maxRadius);
1174
+ float rTL = min(radii.z, maxRadius);
1175
+ float rTR = min(radii.x, maxRadius);
1176
+ float rBR = min(radii.y, maxRadius);
1177
+ vec2 p = fragUV * dims;
1178
+ float leftLen = height - rBL - rTL;
1179
+ float topLen = width - rTL - rTR;
1180
+ float rightLen = height - rTR - rBR;
1181
+ float bottomLen = width - rBR - rBL;
1182
+ float arcBL = PI * 0.5 * rBL;
1183
+ float arcTL = PI * 0.5 * rTL;
1184
+ float arcTR = PI * 0.5 * rTR;
1185
+ float arcBR = PI * 0.5 * rBR;
1186
+ float pos = 0.0;
1187
+ float distLeft = p.x;
1188
+ float distRight = width - p.x;
1189
+ float distBottom = p.y;
1190
+ float distTop = height - p.y;
1191
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
1192
+ if (p.x < rBL && p.y < rBL) {
1193
+ vec2 c = vec2(rBL, rBL);
1194
+ vec2 d = p - c;
1195
+ float angle = atan(-d.x, -d.y);
1196
+ pos = angle / (PI * 0.5) * arcBL;
1197
+ } else if (p.x < rTL && p.y > height - rTL) {
1198
+ vec2 c = vec2(rTL, height - rTL);
1199
+ vec2 d = p - c;
1200
+ float angle = atan(d.y, -d.x);
1201
+ pos = arcBL + leftLen + angle / (PI * 0.5) * arcTL;
1202
+ } else if (p.x > width - rTR && p.y > height - rTR) {
1203
+ vec2 c = vec2(width - rTR, height - rTR);
1204
+ vec2 d = p - c;
1205
+ float angle = atan(d.x, d.y);
1206
+ pos = arcBL + leftLen + arcTL + topLen + angle / (PI * 0.5) * arcTR;
1207
+ } else if (p.x > width - rBR && p.y < rBR) {
1208
+ vec2 c = vec2(width - rBR, rBR);
1209
+ vec2 d = p - c;
1210
+ float angle = atan(-d.y, d.x);
1211
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + angle / (PI * 0.5) * arcBR;
1212
+ } else if (minDist == distLeft) {
1213
+ pos = arcBL + clamp(p.y - rBL, 0.0, leftLen);
1214
+ } else if (minDist == distTop) {
1215
+ pos = arcBL + leftLen + arcTL + clamp(p.x - rTL, 0.0, topLen);
1216
+ } else if (minDist == distRight) {
1217
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + clamp(height - rTR - p.y, 0.0, rightLen);
1218
+ } else {
1219
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + arcBR + clamp(width - rBR - p.x, 0.0, bottomLen);
1220
+ }
1221
+ return pos / lineWidth;
1222
+ }
1223
+ float getRectPerimeterPosition(vec2 fragUV, vec2 dims, float lineWidth) {
1224
+ float width = dims.x;
1225
+ float height = dims.y;
1226
+ float distLeft = fragUV.x * width;
1227
+ float distRight = (1.0 - fragUV.x) * width;
1228
+ float distBottom = fragUV.y * height;
1229
+ float distTop = (1.0 - fragUV.y) * height;
1230
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
1231
+ float pos = 0.0;
1232
+ if (minDist == distLeft) {
1233
+ pos = fragUV.y * height;
1234
+ } else if (minDist == distTop) {
1235
+ pos = height + fragUV.x * width;
1236
+ } else if (minDist == distRight) {
1237
+ pos = height + width + (1.0 - fragUV.y) * height;
1238
+ } else {
1239
+ pos = 2.0 * height + width + (1.0 - fragUV.x) * width;
1240
+ }
1241
+ return pos / lineWidth;
1242
+ }
1243
+ `,
1244
+ "fs:#main-start": `
1245
+ bool inDashGap = false;
1246
+ float dashUnitLength = vDashArray.x + vDashArray.y;
1247
+ if (dashUnitLength > 0.0 && textBackground.stroked) {
1248
+ float distToEdge;
1249
+ bool hasRoundedCorners = textBackground.borderRadius != vec4(0.0);
1250
+ if (hasRoundedCorners) {
1251
+ distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
1252
+ } else {
1253
+ distToEdge = rect(uv, dimensions);
1254
+ }
1255
+ if (distToEdge <= vLineWidth && distToEdge >= 0.0) {
1256
+ float posAlongStroke;
1257
+ if (hasRoundedCorners) {
1258
+ posAlongStroke = getPerimeterPosition(uv, dimensions, textBackground.borderRadius, vLineWidth);
1259
+ } else {
1260
+ posAlongStroke = getRectPerimeterPosition(uv, dimensions, vLineWidth);
1261
+ }
1262
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
1263
+ if (unitOffset > vDashArray.x) {
1264
+ if (vFillColor.a > 0.0) {
1265
+ inDashGap = true;
1266
+ } else {
1267
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
1268
+ discard;
1269
+ }
1270
+ }
1271
+ }
1272
+ }
1273
+ }
1274
+ `,
1275
+ "fs:#main-end": `
1276
+ if (inDashGap) {
1277
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
1278
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
1279
+ fragColor = picking_filterPickingColor(fragColor);
1280
+ fragColor = picking_filterHighlightColor(fragColor);
1281
+ }
1282
+ `
1283
+ }
1284
+ };
1103
1285
  var offsetShaders = {
1104
1286
  inject: {
1105
1287
  "vs:#decl": `
@@ -1137,13 +1319,41 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
1137
1319
  constructor({ dash = false, offset = false, highPrecisionDash = false } = {}) {
1138
1320
  super({ dash: dash || highPrecisionDash, offset, highPrecisionDash });
1139
1321
  }
1322
+ getLayerType(layer) {
1323
+ if ("pathTesselator" in layer.state) {
1324
+ return "path";
1325
+ }
1326
+ const layerName = layer.constructor.layerName;
1327
+ if (layerName === "ScatterplotLayer") {
1328
+ return "scatterplot";
1329
+ }
1330
+ if (layerName === "TextBackgroundLayer") {
1331
+ return "textBackground";
1332
+ }
1333
+ return null;
1334
+ }
1140
1335
  isEnabled(layer) {
1141
- return "pathTesselator" in layer.state;
1336
+ return this.getLayerType(layer) !== null;
1142
1337
  }
1143
1338
  getShaders(extension) {
1144
- if (!extension.isEnabled(this)) {
1339
+ const layerType = extension.getLayerType(this);
1340
+ if (!layerType) {
1145
1341
  return null;
1146
1342
  }
1343
+ if (layerType === "scatterplot" || layerType === "textBackground") {
1344
+ if (!extension.opts.dash) {
1345
+ return null;
1346
+ }
1347
+ const inject7 = layerType === "scatterplot" ? scatterplotDashShaders.inject : textBackgroundDashShaders.inject;
1348
+ const pathStyle2 = {
1349
+ name: "pathStyle",
1350
+ inject: inject7,
1351
+ uniformTypes: {
1352
+ dashGapPickable: "i32"
1353
+ }
1354
+ };
1355
+ return { modules: [pathStyle2] };
1356
+ }
1147
1357
  let result = {};
1148
1358
  const defines = {};
1149
1359
  if (extension.opts.dash) {
@@ -1171,13 +1381,14 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
1171
1381
  }
1172
1382
  initializeState(context, extension) {
1173
1383
  const attributeManager = this.getAttributeManager();
1174
- if (!attributeManager || !extension.isEnabled(this)) {
1384
+ const layerType = extension.getLayerType(this);
1385
+ if (!attributeManager || !layerType) {
1175
1386
  return;
1176
1387
  }
1177
1388
  if (extension.opts.dash) {
1178
1389
  attributeManager.addInstanced({
1179
1390
  instanceDashArrays: { size: 2, accessor: "getDashArray" },
1180
- ...extension.opts.highPrecisionDash ? {
1391
+ ...layerType === "path" && extension.opts.highPrecisionDash ? {
1181
1392
  instanceDashOffsets: {
1182
1393
  size: 1,
1183
1394
  accessor: "getPath",
@@ -1186,7 +1397,7 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
1186
1397
  } : {}
1187
1398
  });
1188
1399
  }
1189
- if (extension.opts.offset) {
1400
+ if (layerType === "path" && extension.opts.offset) {
1190
1401
  attributeManager.addInstanced({
1191
1402
  instanceOffsets: { size: 1, accessor: "getOffset" }
1192
1403
  });
@@ -1197,11 +1408,19 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
1197
1408
  return;
1198
1409
  }
1199
1410
  if (extension.opts.dash) {
1200
- const pathStyleProps = {
1201
- dashAlignMode: this.props.dashJustified ? 1 : 0,
1202
- dashGapPickable: Boolean(this.props.dashGapPickable)
1203
- };
1204
- this.setShaderModuleProps({ pathStyle: pathStyleProps });
1411
+ const layerType = extension.getLayerType(this);
1412
+ if (layerType === "scatterplot" || layerType === "textBackground") {
1413
+ const pathStyleProps = {
1414
+ dashGapPickable: Boolean(this.props.dashGapPickable)
1415
+ };
1416
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
1417
+ } else {
1418
+ const pathStyleProps = {
1419
+ dashAlignMode: this.props.dashJustified ? 1 : 0,
1420
+ dashGapPickable: Boolean(this.props.dashGapPickable)
1421
+ };
1422
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
1423
+ }
1205
1424
  }
1206
1425
  }
1207
1426
  getDashOffsets(path) {