@deck.gl/extensions 9.3.0-alpha.5 → 9.3.0-beta.1
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/data-filter/shader-module.d.ts +18 -4
- package/dist/data-filter/shader-module.d.ts.map +1 -1
- package/dist/data-filter/shader-module.js.map +1 -1
- package/dist/dist.dev.js +251 -11
- package/dist/fp64/fp64-extension.d.ts.map +1 -1
- package/dist/fp64/fp64-extension.js +2 -3
- package/dist/fp64/fp64-extension.js.map +1 -1
- package/dist/index.cjs +230 -11
- package/dist/index.cjs.map +3 -3
- package/dist/path-style/path-style-extension.d.ts +2 -1
- package/dist/path-style/path-style-extension.d.ts.map +1 -1
- package/dist/path-style/path-style-extension.js +53 -14
- package/dist/path-style/path-style-extension.js.map +1 -1
- package/dist/path-style/shaders.glsl.d.ts +18 -0
- package/dist/path-style/shaders.glsl.d.ts.map +1 -1
- package/dist/path-style/shaders.glsl.js +182 -0
- package/dist/path-style/shaders.glsl.js.map +1 -1
- package/dist.min.js +217 -53
- package/package.json +6 -5
- package/src/data-filter/shader-module.ts +22 -7
- package/src/fp64/fp64-extension.ts +2 -5
- package/src/path-style/path-style-extension.ts +67 -14
- package/src/path-style/shaders.glsl.ts +213 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Plug-and-play functionalities for deck.gl layers",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "9.3.0-
|
|
6
|
+
"version": "9.3.0-beta.1",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -38,13 +38,14 @@
|
|
|
38
38
|
"prepublishOnly": "npm run build-bundle && npm run build-bundle -- --env=dev"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@luma.gl/shadertools": "^9.3.
|
|
41
|
+
"@luma.gl/shadertools": "^9.3.2",
|
|
42
|
+
"@luma.gl/webgl": "^9.3.2",
|
|
42
43
|
"@math.gl/core": "^4.1.0"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"@deck.gl/core": "~9.3.0-alpha.1",
|
|
46
|
-
"@luma.gl/core": "~9.3.
|
|
47
|
-
"@luma.gl/engine": "~9.3.
|
|
47
|
+
"@luma.gl/core": "~9.3.2",
|
|
48
|
+
"@luma.gl/engine": "~9.3.2"
|
|
48
49
|
},
|
|
49
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "a8b482631c7b10460411b08c8c674b86176ec191"
|
|
50
51
|
}
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import type {ShaderModule} from '@luma.gl/shadertools';
|
|
5
|
+
import type {ShaderModule, UniformTypes} from '@luma.gl/shadertools';
|
|
6
6
|
import type {DataFilterExtensionOptions, DataFilterExtensionProps} from './data-filter-extension';
|
|
7
|
-
import {UniformFormat} from '@luma.gl/shadertools/dist/types';
|
|
8
7
|
|
|
9
8
|
/*
|
|
10
9
|
* data filter shader module
|
|
@@ -230,6 +229,22 @@ export type DataFilterModuleProps = {
|
|
|
230
229
|
categoryBitMask?: CategoryBitMask;
|
|
231
230
|
} & DataFilterExtensionProps;
|
|
232
231
|
|
|
232
|
+
type DataFilterUniforms = {
|
|
233
|
+
useSoftMargin: boolean;
|
|
234
|
+
enabled: boolean;
|
|
235
|
+
transformSize: boolean;
|
|
236
|
+
transformColor: boolean;
|
|
237
|
+
min: [number, number, number, number];
|
|
238
|
+
softMin: [number, number, number, number];
|
|
239
|
+
softMax: [number, number, number, number];
|
|
240
|
+
max: [number, number, number, number];
|
|
241
|
+
min64High: [number, number, number, number];
|
|
242
|
+
max64High: [number, number, number, number];
|
|
243
|
+
categoryBitMask: [number, number, number, number];
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
type DataFilterUniformTypeMap = Required<UniformTypes<DataFilterUniforms>>;
|
|
247
|
+
|
|
233
248
|
/* eslint-disable camelcase */
|
|
234
249
|
function getUniforms(opts?: DataFilterModuleProps | {}): Record<string, any> {
|
|
235
250
|
if (!opts || !('extensions' in opts)) {
|
|
@@ -330,9 +345,9 @@ const inject = {
|
|
|
330
345
|
`
|
|
331
346
|
};
|
|
332
347
|
|
|
333
|
-
type UniformTypesFunc = (opts: DataFilterExtensionOptions) =>
|
|
334
|
-
function uniformTypesFromOptions(opts: DataFilterExtensionOptions):
|
|
335
|
-
const uniformTypes:
|
|
348
|
+
type UniformTypesFunc = (opts: DataFilterExtensionOptions) => DataFilterUniformTypeMap;
|
|
349
|
+
function uniformTypesFromOptions(opts: DataFilterExtensionOptions): DataFilterUniformTypeMap {
|
|
350
|
+
const uniformTypes: DataFilterUniformTypeMap = {
|
|
336
351
|
useSoftMargin: 'i32',
|
|
337
352
|
enabled: 'i32',
|
|
338
353
|
transformSize: 'i32',
|
|
@@ -349,7 +364,7 @@ function uniformTypesFromOptions(opts: DataFilterExtensionOptions): any {
|
|
|
349
364
|
return uniformTypes;
|
|
350
365
|
}
|
|
351
366
|
|
|
352
|
-
export const dataFilter: ShaderModule<DataFilterModuleProps> & {
|
|
367
|
+
export const dataFilter: ShaderModule<DataFilterModuleProps, DataFilterUniforms> & {
|
|
353
368
|
uniformTypesFromOptions: UniformTypesFunc;
|
|
354
369
|
} = {
|
|
355
370
|
name: 'dataFilter',
|
|
@@ -360,7 +375,7 @@ export const dataFilter: ShaderModule<DataFilterModuleProps> & {
|
|
|
360
375
|
uniformTypesFromOptions
|
|
361
376
|
};
|
|
362
377
|
|
|
363
|
-
export const dataFilter64: ShaderModule<DataFilterModuleProps> & {
|
|
378
|
+
export const dataFilter64: ShaderModule<DataFilterModuleProps, DataFilterUniforms> & {
|
|
364
379
|
uniformTypesFromOptions: UniformTypesFunc;
|
|
365
380
|
} = {
|
|
366
381
|
name: 'dataFilter',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
-
import {LayerExtension
|
|
5
|
+
import {LayerExtension} from '@deck.gl/core';
|
|
6
6
|
import project64 from './project64';
|
|
7
7
|
|
|
8
8
|
import type {Layer} from '@deck.gl/core';
|
|
@@ -13,10 +13,7 @@ export default class Fp64Extension extends LayerExtension {
|
|
|
13
13
|
|
|
14
14
|
getShaders(this: Layer): any {
|
|
15
15
|
const {coordinateSystem} = this.props;
|
|
16
|
-
if (
|
|
17
|
-
coordinateSystem !== COORDINATE_SYSTEM.LNGLAT &&
|
|
18
|
-
coordinateSystem !== COORDINATE_SYSTEM.DEFAULT
|
|
19
|
-
) {
|
|
16
|
+
if (coordinateSystem !== 'lnglat' && coordinateSystem !== 'default') {
|
|
20
17
|
throw new Error('fp64: coordinateSystem must be LNGLAT');
|
|
21
18
|
}
|
|
22
19
|
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import {LayerExtension, _mergeShaders as mergeShaders} from '@deck.gl/core';
|
|
6
6
|
import {vec3} from '@math.gl/core';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
dashShaders,
|
|
9
|
+
Defines,
|
|
10
|
+
offsetShaders,
|
|
11
|
+
scatterplotDashShaders,
|
|
12
|
+
textBackgroundDashShaders
|
|
13
|
+
} from './shaders.glsl';
|
|
8
14
|
|
|
9
15
|
import type {Accessor, Layer, LayerContext, UpdateParameters} from '@deck.gl/core';
|
|
10
16
|
import type {ShaderModule} from '@luma.gl/shadertools';
|
|
@@ -21,6 +27,10 @@ type PathStyleProps = {
|
|
|
21
27
|
dashGapPickable: boolean;
|
|
22
28
|
};
|
|
23
29
|
|
|
30
|
+
type SDFDashStyleProps = {
|
|
31
|
+
dashGapPickable: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
24
34
|
export type PathStyleExtensionProps<DataT = any> = {
|
|
25
35
|
/**
|
|
26
36
|
* Accessor for the dash array to draw each path with: `[dashSize, gapSize]` relative to the width of the path.
|
|
@@ -63,7 +73,9 @@ export type PathStyleExtensionOptions = {
|
|
|
63
73
|
highPrecisionDash: boolean;
|
|
64
74
|
};
|
|
65
75
|
|
|
66
|
-
|
|
76
|
+
type LayerType = 'path' | 'scatterplot' | 'textBackground';
|
|
77
|
+
|
|
78
|
+
/** Adds selected features to the `PathLayer`, `ScatterplotLayer`, `TextBackgroundLayer`, and composite layers that render them. */
|
|
67
79
|
export default class PathStyleExtension extends LayerExtension<PathStyleExtensionOptions> {
|
|
68
80
|
static defaultProps = defaultProps;
|
|
69
81
|
static extensionName = 'PathStyleExtension';
|
|
@@ -76,16 +88,49 @@ export default class PathStyleExtension extends LayerExtension<PathStyleExtensio
|
|
|
76
88
|
super({dash: dash || highPrecisionDash, offset, highPrecisionDash});
|
|
77
89
|
}
|
|
78
90
|
|
|
91
|
+
private getLayerType(layer: Layer): LayerType | null {
|
|
92
|
+
if ('pathTesselator' in layer.state) {
|
|
93
|
+
return 'path';
|
|
94
|
+
}
|
|
95
|
+
const layerName = (layer.constructor as any).layerName;
|
|
96
|
+
if (layerName === 'ScatterplotLayer') {
|
|
97
|
+
return 'scatterplot';
|
|
98
|
+
}
|
|
99
|
+
if (layerName === 'TextBackgroundLayer') {
|
|
100
|
+
return 'textBackground';
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
79
105
|
isEnabled(layer: Layer<PathStyleExtensionProps>): boolean {
|
|
80
|
-
return
|
|
106
|
+
return this.getLayerType(layer) !== null;
|
|
81
107
|
}
|
|
82
108
|
|
|
83
109
|
getShaders(this: Layer<PathStyleExtensionProps>, extension: this): any {
|
|
84
|
-
|
|
110
|
+
const layerType = extension.getLayerType(this);
|
|
111
|
+
if (!layerType) {
|
|
85
112
|
return null;
|
|
86
113
|
}
|
|
87
114
|
|
|
88
|
-
|
|
115
|
+
if (layerType === 'scatterplot' || layerType === 'textBackground') {
|
|
116
|
+
if (!extension.opts.dash) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const inject =
|
|
120
|
+
layerType === 'scatterplot'
|
|
121
|
+
? scatterplotDashShaders.inject
|
|
122
|
+
: textBackgroundDashShaders.inject;
|
|
123
|
+
const pathStyle: ShaderModule<SDFDashStyleProps> = {
|
|
124
|
+
name: 'pathStyle',
|
|
125
|
+
inject,
|
|
126
|
+
uniformTypes: {
|
|
127
|
+
dashGapPickable: 'i32'
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
return {modules: [pathStyle]};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// PathLayer: existing logic
|
|
89
134
|
let result = {} as {inject: Record<string, string>};
|
|
90
135
|
const defines: Defines = {};
|
|
91
136
|
if (extension.opts.dash) {
|
|
@@ -115,15 +160,15 @@ export default class PathStyleExtension extends LayerExtension<PathStyleExtensio
|
|
|
115
160
|
|
|
116
161
|
initializeState(this: Layer<PathStyleExtensionProps>, context: LayerContext, extension: this) {
|
|
117
162
|
const attributeManager = this.getAttributeManager();
|
|
118
|
-
|
|
119
|
-
|
|
163
|
+
const layerType = extension.getLayerType(this);
|
|
164
|
+
if (!attributeManager || !layerType) {
|
|
120
165
|
return;
|
|
121
166
|
}
|
|
122
167
|
|
|
123
168
|
if (extension.opts.dash) {
|
|
124
169
|
attributeManager.addInstanced({
|
|
125
170
|
instanceDashArrays: {size: 2, accessor: 'getDashArray'},
|
|
126
|
-
...(extension.opts.highPrecisionDash
|
|
171
|
+
...(layerType === 'path' && extension.opts.highPrecisionDash
|
|
127
172
|
? {
|
|
128
173
|
instanceDashOffsets: {
|
|
129
174
|
size: 1,
|
|
@@ -134,7 +179,7 @@ export default class PathStyleExtension extends LayerExtension<PathStyleExtensio
|
|
|
134
179
|
: {})
|
|
135
180
|
});
|
|
136
181
|
}
|
|
137
|
-
if (extension.opts.offset) {
|
|
182
|
+
if (layerType === 'path' && extension.opts.offset) {
|
|
138
183
|
attributeManager.addInstanced({
|
|
139
184
|
instanceOffsets: {size: 1, accessor: 'getOffset'}
|
|
140
185
|
});
|
|
@@ -151,11 +196,19 @@ export default class PathStyleExtension extends LayerExtension<PathStyleExtensio
|
|
|
151
196
|
}
|
|
152
197
|
|
|
153
198
|
if (extension.opts.dash) {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
199
|
+
const layerType = extension.getLayerType(this);
|
|
200
|
+
if (layerType === 'scatterplot' || layerType === 'textBackground') {
|
|
201
|
+
const pathStyleProps: SDFDashStyleProps = {
|
|
202
|
+
dashGapPickable: Boolean(this.props.dashGapPickable)
|
|
203
|
+
};
|
|
204
|
+
this.setShaderModuleProps({pathStyle: pathStyleProps});
|
|
205
|
+
} else {
|
|
206
|
+
const pathStyleProps: PathStyleProps = {
|
|
207
|
+
dashAlignMode: this.props.dashJustified ? 1 : 0,
|
|
208
|
+
dashGapPickable: Boolean(this.props.dashGapPickable)
|
|
209
|
+
};
|
|
210
|
+
this.setShaderModuleProps({pathStyle: pathStyleProps});
|
|
211
|
+
}
|
|
159
212
|
}
|
|
160
213
|
}
|
|
161
214
|
|
|
@@ -88,6 +88,219 @@ in float vDashOffset;
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
export const scatterplotDashShaders = {
|
|
92
|
+
inject: {
|
|
93
|
+
'vs:#decl': `
|
|
94
|
+
in vec2 instanceDashArrays;
|
|
95
|
+
out vec2 vDashArray;
|
|
96
|
+
`,
|
|
97
|
+
|
|
98
|
+
'vs:#main-end': `
|
|
99
|
+
vDashArray = instanceDashArrays;
|
|
100
|
+
`,
|
|
101
|
+
|
|
102
|
+
'fs:#decl': `
|
|
103
|
+
layout(std140) uniform pathStyleUniforms {
|
|
104
|
+
bool dashGapPickable;
|
|
105
|
+
} pathStyle;
|
|
106
|
+
|
|
107
|
+
in vec2 vDashArray;
|
|
108
|
+
|
|
109
|
+
#define PI 3.141592653589793
|
|
110
|
+
`,
|
|
111
|
+
|
|
112
|
+
'fs:#main-start': `
|
|
113
|
+
bool inDashGap = false;
|
|
114
|
+
float dashUnitLength = vDashArray.x + vDashArray.y;
|
|
115
|
+
if (dashUnitLength > 0.0 && scatterplot.stroked > 0.5) {
|
|
116
|
+
float _distToCenter = length(unitPosition) * outerRadiusPixels;
|
|
117
|
+
float innerRadius = innerUnitRadius * outerRadiusPixels;
|
|
118
|
+
if (_distToCenter >= innerRadius) {
|
|
119
|
+
float strokeWidth = (1.0 - innerUnitRadius) * outerRadiusPixels;
|
|
120
|
+
float midStrokeRadius = (innerUnitRadius + 1.0) * 0.5 * outerRadiusPixels;
|
|
121
|
+
float angle = atan(unitPosition.y, unitPosition.x) + PI;
|
|
122
|
+
float circumference = 2.0 * PI * midStrokeRadius;
|
|
123
|
+
float posAlongStroke = (angle / (2.0 * PI)) * circumference / strokeWidth;
|
|
124
|
+
float unitOffset = mod(posAlongStroke, dashUnitLength);
|
|
125
|
+
if (unitOffset > vDashArray.x) {
|
|
126
|
+
if (scatterplot.filled > 0.5) {
|
|
127
|
+
inDashGap = true;
|
|
128
|
+
} else {
|
|
129
|
+
if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
|
|
130
|
+
discard;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
`,
|
|
137
|
+
|
|
138
|
+
'fs:#main-end': `
|
|
139
|
+
if (inDashGap) {
|
|
140
|
+
float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
|
|
141
|
+
fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
|
|
142
|
+
fragColor = picking_filterPickingColor(fragColor);
|
|
143
|
+
fragColor = picking_filterHighlightColor(fragColor);
|
|
144
|
+
}
|
|
145
|
+
`
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const textBackgroundDashShaders = {
|
|
150
|
+
inject: {
|
|
151
|
+
'vs:#decl': `
|
|
152
|
+
in vec2 instanceDashArrays;
|
|
153
|
+
out vec2 vDashArray;
|
|
154
|
+
`,
|
|
155
|
+
|
|
156
|
+
'vs:#main-end': `
|
|
157
|
+
vDashArray = instanceDashArrays;
|
|
158
|
+
`,
|
|
159
|
+
|
|
160
|
+
'fs:#decl': `
|
|
161
|
+
layout(std140) uniform pathStyleUniforms {
|
|
162
|
+
bool dashGapPickable;
|
|
163
|
+
} pathStyle;
|
|
164
|
+
|
|
165
|
+
in vec2 vDashArray;
|
|
166
|
+
|
|
167
|
+
#define PI 3.141592653589793
|
|
168
|
+
|
|
169
|
+
// Calculate position along rounded rectangle perimeter in stroke-width units
|
|
170
|
+
float getPerimeterPosition(vec2 fragUV, vec2 dims, vec4 radii, float lineWidth) {
|
|
171
|
+
float width = dims.x;
|
|
172
|
+
float height = dims.y;
|
|
173
|
+
|
|
174
|
+
float maxRadius = min(width, height) * 0.5;
|
|
175
|
+
float rBL = min(radii.w, maxRadius);
|
|
176
|
+
float rTL = min(radii.z, maxRadius);
|
|
177
|
+
float rTR = min(radii.x, maxRadius);
|
|
178
|
+
float rBR = min(radii.y, maxRadius);
|
|
179
|
+
|
|
180
|
+
vec2 p = fragUV * dims;
|
|
181
|
+
|
|
182
|
+
float leftLen = height - rBL - rTL;
|
|
183
|
+
float topLen = width - rTL - rTR;
|
|
184
|
+
float rightLen = height - rTR - rBR;
|
|
185
|
+
float bottomLen = width - rBR - rBL;
|
|
186
|
+
|
|
187
|
+
float arcBL = PI * 0.5 * rBL;
|
|
188
|
+
float arcTL = PI * 0.5 * rTL;
|
|
189
|
+
float arcTR = PI * 0.5 * rTR;
|
|
190
|
+
float arcBR = PI * 0.5 * rBR;
|
|
191
|
+
|
|
192
|
+
float pos = 0.0;
|
|
193
|
+
|
|
194
|
+
float distLeft = p.x;
|
|
195
|
+
float distRight = width - p.x;
|
|
196
|
+
float distBottom = p.y;
|
|
197
|
+
float distTop = height - p.y;
|
|
198
|
+
float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
|
|
199
|
+
|
|
200
|
+
if (p.x < rBL && p.y < rBL) {
|
|
201
|
+
vec2 c = vec2(rBL, rBL);
|
|
202
|
+
vec2 d = p - c;
|
|
203
|
+
float angle = atan(-d.x, -d.y);
|
|
204
|
+
pos = angle / (PI * 0.5) * arcBL;
|
|
205
|
+
} else if (p.x < rTL && p.y > height - rTL) {
|
|
206
|
+
vec2 c = vec2(rTL, height - rTL);
|
|
207
|
+
vec2 d = p - c;
|
|
208
|
+
float angle = atan(d.y, -d.x);
|
|
209
|
+
pos = arcBL + leftLen + angle / (PI * 0.5) * arcTL;
|
|
210
|
+
} else if (p.x > width - rTR && p.y > height - rTR) {
|
|
211
|
+
vec2 c = vec2(width - rTR, height - rTR);
|
|
212
|
+
vec2 d = p - c;
|
|
213
|
+
float angle = atan(d.x, d.y);
|
|
214
|
+
pos = arcBL + leftLen + arcTL + topLen + angle / (PI * 0.5) * arcTR;
|
|
215
|
+
} else if (p.x > width - rBR && p.y < rBR) {
|
|
216
|
+
vec2 c = vec2(width - rBR, rBR);
|
|
217
|
+
vec2 d = p - c;
|
|
218
|
+
float angle = atan(-d.y, d.x);
|
|
219
|
+
pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + angle / (PI * 0.5) * arcBR;
|
|
220
|
+
} else if (minDist == distLeft) {
|
|
221
|
+
pos = arcBL + clamp(p.y - rBL, 0.0, leftLen);
|
|
222
|
+
} else if (minDist == distTop) {
|
|
223
|
+
pos = arcBL + leftLen + arcTL + clamp(p.x - rTL, 0.0, topLen);
|
|
224
|
+
} else if (minDist == distRight) {
|
|
225
|
+
pos = arcBL + leftLen + arcTL + topLen + arcTR + clamp(height - rTR - p.y, 0.0, rightLen);
|
|
226
|
+
} else {
|
|
227
|
+
pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + arcBR + clamp(width - rBR - p.x, 0.0, bottomLen);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return pos / lineWidth;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Simple rectangular perimeter calculation (no rounded corners)
|
|
234
|
+
float getRectPerimeterPosition(vec2 fragUV, vec2 dims, float lineWidth) {
|
|
235
|
+
float width = dims.x;
|
|
236
|
+
float height = dims.y;
|
|
237
|
+
|
|
238
|
+
float distLeft = fragUV.x * width;
|
|
239
|
+
float distRight = (1.0 - fragUV.x) * width;
|
|
240
|
+
float distBottom = fragUV.y * height;
|
|
241
|
+
float distTop = (1.0 - fragUV.y) * height;
|
|
242
|
+
|
|
243
|
+
float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
|
|
244
|
+
|
|
245
|
+
float pos = 0.0;
|
|
246
|
+
if (minDist == distLeft) {
|
|
247
|
+
pos = fragUV.y * height;
|
|
248
|
+
} else if (minDist == distTop) {
|
|
249
|
+
pos = height + fragUV.x * width;
|
|
250
|
+
} else if (minDist == distRight) {
|
|
251
|
+
pos = height + width + (1.0 - fragUV.y) * height;
|
|
252
|
+
} else {
|
|
253
|
+
pos = 2.0 * height + width + (1.0 - fragUV.x) * width;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return pos / lineWidth;
|
|
257
|
+
}
|
|
258
|
+
`,
|
|
259
|
+
|
|
260
|
+
'fs:#main-start': `
|
|
261
|
+
bool inDashGap = false;
|
|
262
|
+
float dashUnitLength = vDashArray.x + vDashArray.y;
|
|
263
|
+
if (dashUnitLength > 0.0 && textBackground.stroked) {
|
|
264
|
+
float distToEdge;
|
|
265
|
+
bool hasRoundedCorners = textBackground.borderRadius != vec4(0.0);
|
|
266
|
+
if (hasRoundedCorners) {
|
|
267
|
+
distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
|
|
268
|
+
} else {
|
|
269
|
+
distToEdge = rect(uv, dimensions);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (distToEdge <= vLineWidth && distToEdge >= 0.0) {
|
|
273
|
+
float posAlongStroke;
|
|
274
|
+
if (hasRoundedCorners) {
|
|
275
|
+
posAlongStroke = getPerimeterPosition(uv, dimensions, textBackground.borderRadius, vLineWidth);
|
|
276
|
+
} else {
|
|
277
|
+
posAlongStroke = getRectPerimeterPosition(uv, dimensions, vLineWidth);
|
|
278
|
+
}
|
|
279
|
+
float unitOffset = mod(posAlongStroke, dashUnitLength);
|
|
280
|
+
if (unitOffset > vDashArray.x) {
|
|
281
|
+
if (vFillColor.a > 0.0) {
|
|
282
|
+
inDashGap = true;
|
|
283
|
+
} else {
|
|
284
|
+
if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
|
|
285
|
+
discard;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
`,
|
|
292
|
+
|
|
293
|
+
'fs:#main-end': `
|
|
294
|
+
if (inDashGap) {
|
|
295
|
+
float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
|
|
296
|
+
fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
|
|
297
|
+
fragColor = picking_filterPickingColor(fragColor);
|
|
298
|
+
fragColor = picking_filterHighlightColor(fragColor);
|
|
299
|
+
}
|
|
300
|
+
`
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
91
304
|
export const offsetShaders = {
|
|
92
305
|
inject: {
|
|
93
306
|
'vs:#decl': `
|