@deck.gl-community/infovis-layers 9.3.8 → 9.4.0-alpha.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/index.cjs +1840 -1420
- package/dist/index.cjs.map +4 -4
- package/dist/layers/block-layer/block-layer-uniforms.d.ts +4 -3
- package/dist/layers/block-layer/block-layer-uniforms.d.ts.map +1 -1
- package/dist/layers/block-layer/block-layer-uniforms.js +4 -3
- package/dist/layers/block-layer/block-layer-uniforms.js.map +1 -1
- package/dist/layers/block-layer/block-layer-vertex.glsl.d.ts +1 -1
- package/dist/layers/block-layer/block-layer-vertex.glsl.js +4 -4
- package/dist/layers/block-layer/block-layer.d.ts +2 -0
- package/dist/layers/block-layer/block-layer.d.ts.map +1 -1
- package/dist/layers/block-layer/block-layer.js +23 -2
- package/dist/layers/block-layer/block-layer.js.map +1 -1
- package/dist/layers/block-layer/block-layer.wgsl.d.ts +4 -0
- package/dist/layers/block-layer/block-layer.wgsl.d.ts.map +1 -0
- package/dist/layers/block-layer/block-layer.wgsl.js +134 -0
- package/dist/layers/block-layer/block-layer.wgsl.js.map +1 -0
- package/dist/layers/fast-text-layer/fast-text-layer.d.ts +47 -0
- package/dist/layers/fast-text-layer/fast-text-layer.d.ts.map +1 -1
- package/dist/layers/fast-text-layer/fast-text-layer.js +5 -1
- package/dist/layers/fast-text-layer/fast-text-layer.js.map +1 -1
- package/dist/layers/fast-text-layer/fast-text-layer.wgsl.d.ts +4 -0
- package/dist/layers/fast-text-layer/fast-text-layer.wgsl.d.ts.map +1 -0
- package/dist/layers/fast-text-layer/fast-text-layer.wgsl.js +247 -0
- package/dist/layers/fast-text-layer/fast-text-layer.wgsl.js.map +1 -0
- package/dist/layers/time-delta-layer.d.ts.map +1 -1
- package/dist/layers/time-delta-layer.js +34 -17
- package/dist/layers/time-delta-layer.js.map +1 -1
- package/package.json +12 -12
- package/src/layers/block-layer/block-layer-uniforms.ts +4 -3
- package/src/layers/block-layer/block-layer-vertex.glsl.ts +4 -4
- package/src/layers/block-layer/block-layer.ts +24 -2
- package/src/layers/block-layer/block-layer.wgsl.ts +134 -0
- package/src/layers/fast-text-layer/fast-text-layer.ts +5 -1
- package/src/layers/fast-text-layer/fast-text-layer.wgsl.ts +247 -0
- package/src/layers/time-delta-layer.ts +34 -17
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// deck.gl-community
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
/** WebGPU shaders for packed glyphs, following luma.gl's text-rendering conventions. */
|
|
6
|
+
export default /* wgsl */ `
|
|
7
|
+
struct FastTextUniforms {
|
|
8
|
+
fontAtlasSize: vec2<f32>,
|
|
9
|
+
fontSize: f32,
|
|
10
|
+
size: f32,
|
|
11
|
+
sizeScale: f32,
|
|
12
|
+
sizeMinPixels: f32,
|
|
13
|
+
sizeMaxPixels: f32,
|
|
14
|
+
pixelOffset: vec2<f32>,
|
|
15
|
+
billboard: f32,
|
|
16
|
+
sizeUnits: i32,
|
|
17
|
+
alphaCutoff: f32,
|
|
18
|
+
sdfEnabled: f32,
|
|
19
|
+
sdfBuffer: f32,
|
|
20
|
+
sdfGamma: f32,
|
|
21
|
+
contentCutoffPixels: vec2<f32>,
|
|
22
|
+
contentAlign: vec2<i32>,
|
|
23
|
+
flipY: f32,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
@group(0) @binding(auto) var<uniform> fastText: FastTextUniforms;
|
|
27
|
+
@group(0) @binding(auto) var fontAtlasTexture: texture_2d<f32>;
|
|
28
|
+
@group(0) @binding(auto) var fontAtlasTextureSampler: sampler;
|
|
29
|
+
|
|
30
|
+
struct FastTextAttributes {
|
|
31
|
+
@location(0) positions: vec2<f32>,
|
|
32
|
+
@location(1) instancePositions: vec2<f32>,
|
|
33
|
+
@location(2) instanceGlyphOffsets: vec2<i32>,
|
|
34
|
+
@location(3) instanceGlyphFrames: vec4<u32>,
|
|
35
|
+
@location(4) instanceClipRects: vec4<i32>,
|
|
36
|
+
@location(5) instanceColors: vec4<f32>,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
struct FastTextVaryings {
|
|
40
|
+
@builtin(position) position: vec4<f32>,
|
|
41
|
+
@location(0) color: vec4<f32>,
|
|
42
|
+
@location(1) textureCoords: vec2<f32>,
|
|
43
|
+
@location(2) uv: vec2<f32>,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
struct FastTextClipResult {
|
|
47
|
+
position: vec4<f32>,
|
|
48
|
+
pixelOffset: vec2<f32>,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
fn fast_text_alignment_pixel_offset(
|
|
52
|
+
anchor: f32,
|
|
53
|
+
extent: f32,
|
|
54
|
+
clipStart: f32,
|
|
55
|
+
clipEnd: f32,
|
|
56
|
+
mode: i32
|
|
57
|
+
) -> f32 {
|
|
58
|
+
if (clipEnd < clipStart) {
|
|
59
|
+
return 0.0;
|
|
60
|
+
}
|
|
61
|
+
if (mode == 1) {
|
|
62
|
+
return max(-(anchor + clipStart), 0.0);
|
|
63
|
+
}
|
|
64
|
+
if (mode == 2) {
|
|
65
|
+
let visibleMin = max(0.0, anchor + clipStart);
|
|
66
|
+
let visibleMax = min(extent, anchor + clipEnd);
|
|
67
|
+
return select(0.0, (visibleMin + visibleMax) * 0.5 - anchor, visibleMin < visibleMax);
|
|
68
|
+
}
|
|
69
|
+
if (mode == 3) {
|
|
70
|
+
return min(extent - (anchor + clipEnd), 0.0);
|
|
71
|
+
}
|
|
72
|
+
return 0.0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fn fast_text_clip_glyph_vertex(
|
|
76
|
+
initialPixelOffset: vec2<f32>,
|
|
77
|
+
anchorPositionScreen: vec2<f32>,
|
|
78
|
+
clipRect: vec4<i32>,
|
|
79
|
+
initialPosition: vec4<f32>
|
|
80
|
+
) -> FastTextClipResult {
|
|
81
|
+
var result: FastTextClipResult;
|
|
82
|
+
result.position = initialPosition;
|
|
83
|
+
result.pixelOffset = initialPixelOffset;
|
|
84
|
+
|
|
85
|
+
let clipRectFloat = vec4<f32>(clipRect);
|
|
86
|
+
var clipXY = project_size_vec2(clipRectFloat.xy) * project.scale;
|
|
87
|
+
let clipWH = project_size_vec2(clipRectFloat.zw) * project.scale;
|
|
88
|
+
|
|
89
|
+
if (fastText.flipY > 0.5) {
|
|
90
|
+
clipXY.y = -clipXY.y - clipWH.y;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (fastText.contentAlign.x > 0 || fastText.contentAlign.y > 0) {
|
|
94
|
+
let viewportPixels = project.viewportSize / project.devicePixelRatio;
|
|
95
|
+
let scrollPixels = vec2<f32>(
|
|
96
|
+
fast_text_alignment_pixel_offset(
|
|
97
|
+
anchorPositionScreen.x,
|
|
98
|
+
viewportPixels.x,
|
|
99
|
+
clipXY.x,
|
|
100
|
+
clipXY.x + clipWH.x,
|
|
101
|
+
fastText.contentAlign.x
|
|
102
|
+
),
|
|
103
|
+
-fast_text_alignment_pixel_offset(
|
|
104
|
+
anchorPositionScreen.y,
|
|
105
|
+
viewportPixels.y,
|
|
106
|
+
-clipXY.y - clipWH.y,
|
|
107
|
+
-clipXY.y,
|
|
108
|
+
fastText.contentAlign.y
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
result.pixelOffset += scrollPixels;
|
|
112
|
+
result.position = vec4<f32>(
|
|
113
|
+
result.position.xy + project_pixel_size_to_clipspace(scrollPixels),
|
|
114
|
+
result.position.zw
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (clipRectFloat.z >= 0.0) {
|
|
119
|
+
if (result.pixelOffset.x < clipXY.x || result.pixelOffset.x > clipXY.x + clipWH.x) {
|
|
120
|
+
result.position = vec4<f32>(0.0);
|
|
121
|
+
} else if (fastText.contentCutoffPixels.x > 0.0) {
|
|
122
|
+
let viewportWidth = project.viewportSize.x / project.devicePixelRatio;
|
|
123
|
+
let left = max(anchorPositionScreen.x + clipXY.x, 0.0);
|
|
124
|
+
let right = min(anchorPositionScreen.x + clipXY.x + clipWH.x, viewportWidth);
|
|
125
|
+
if (right - left < fastText.contentCutoffPixels.x) {
|
|
126
|
+
result.position = vec4<f32>(0.0);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (clipRectFloat.w >= 0.0) {
|
|
132
|
+
if (result.pixelOffset.y < clipXY.y || result.pixelOffset.y > clipXY.y + clipWH.y) {
|
|
133
|
+
result.position = vec4<f32>(0.0);
|
|
134
|
+
} else if (fastText.contentCutoffPixels.y > 0.0) {
|
|
135
|
+
let viewportHeight = project.viewportSize.y / project.devicePixelRatio;
|
|
136
|
+
let top = max(anchorPositionScreen.y - clipXY.y - clipWH.y, 0.0);
|
|
137
|
+
let bottom = min(anchorPositionScreen.y - clipXY.y, viewportHeight);
|
|
138
|
+
if (bottom - top < fastText.contentCutoffPixels.y) {
|
|
139
|
+
result.position = vec4<f32>(0.0);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@vertex
|
|
148
|
+
fn vertexMain(attributes: FastTextAttributes) -> FastTextVaryings {
|
|
149
|
+
let worldPosition = vec3<f32>(attributes.instancePositions, 0.0);
|
|
150
|
+
geometry.worldPosition = worldPosition;
|
|
151
|
+
geometry.uv = attributes.positions;
|
|
152
|
+
|
|
153
|
+
let glyphFrame = vec4<f32>(attributes.instanceGlyphFrames);
|
|
154
|
+
let glyphSize = glyphFrame.zw;
|
|
155
|
+
let sizePixels = clamp(
|
|
156
|
+
project_unit_size_to_pixel(fastText.size * fastText.sizeScale, fastText.sizeUnits),
|
|
157
|
+
fastText.sizeMinPixels,
|
|
158
|
+
fastText.sizeMaxPixels
|
|
159
|
+
);
|
|
160
|
+
let instanceScale = select(sizePixels / fastText.fontSize, 0.0, fastText.fontSize == 0.0);
|
|
161
|
+
var pixelOffset = vec2<f32>(attributes.instanceGlyphOffsets) + attributes.positions * glyphSize;
|
|
162
|
+
pixelOffset = pixelOffset * instanceScale + fastText.pixelOffset;
|
|
163
|
+
pixelOffset.y = -pixelOffset.y;
|
|
164
|
+
|
|
165
|
+
var clipPosition: vec4<f32>;
|
|
166
|
+
var anchorPositionClip: vec4<f32>;
|
|
167
|
+
|
|
168
|
+
if (fastText.billboard > 0.5) {
|
|
169
|
+
let projected = project_position_to_clipspace_and_commonspace(
|
|
170
|
+
worldPosition,
|
|
171
|
+
vec3<f32>(0.0),
|
|
172
|
+
vec3<f32>(0.0)
|
|
173
|
+
);
|
|
174
|
+
geometry.position = projected.commonPosition;
|
|
175
|
+
anchorPositionClip = projected.clipPosition;
|
|
176
|
+
clipPosition = vec4<f32>(
|
|
177
|
+
projected.clipPosition.xy + project_pixel_size_to_clipspace(pixelOffset),
|
|
178
|
+
projected.clipPosition.zw
|
|
179
|
+
);
|
|
180
|
+
} else {
|
|
181
|
+
var offsetCommon = vec3<f32>(project_pixel_size_vec2(pixelOffset), 0.0);
|
|
182
|
+
if (fastText.flipY > 0.5) {
|
|
183
|
+
offsetCommon.y = -offsetCommon.y;
|
|
184
|
+
}
|
|
185
|
+
let projected = project_position_to_clipspace_and_commonspace(
|
|
186
|
+
worldPosition,
|
|
187
|
+
vec3<f32>(0.0),
|
|
188
|
+
offsetCommon
|
|
189
|
+
);
|
|
190
|
+
geometry.position = projected.commonPosition;
|
|
191
|
+
anchorPositionClip = project_position_to_clipspace(
|
|
192
|
+
worldPosition,
|
|
193
|
+
vec3<f32>(0.0),
|
|
194
|
+
vec3<f32>(0.0)
|
|
195
|
+
);
|
|
196
|
+
clipPosition = projected.clipPosition;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
let anchorPositionNdc = anchorPositionClip.xy / anchorPositionClip.w;
|
|
200
|
+
let anchorPositionScreen = vec2<f32>(
|
|
201
|
+
anchorPositionNdc.x + 1.0,
|
|
202
|
+
1.0 - anchorPositionNdc.y
|
|
203
|
+
) * 0.5 * project.viewportSize / project.devicePixelRatio;
|
|
204
|
+
let clipped = fast_text_clip_glyph_vertex(
|
|
205
|
+
pixelOffset,
|
|
206
|
+
anchorPositionScreen,
|
|
207
|
+
attributes.instanceClipRects,
|
|
208
|
+
clipPosition
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
var varyings: FastTextVaryings;
|
|
212
|
+
varyings.position = clipped.position;
|
|
213
|
+
varyings.color = attributes.instanceColors;
|
|
214
|
+
varyings.textureCoords =
|
|
215
|
+
(glyphFrame.xy + attributes.positions * glyphSize) / fastText.fontAtlasSize;
|
|
216
|
+
varyings.uv = attributes.positions;
|
|
217
|
+
return varyings;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@fragment
|
|
221
|
+
fn fragmentMain(varyings: FastTextVaryings) -> @location(0) vec4<f32> {
|
|
222
|
+
geometry.uv = varyings.uv;
|
|
223
|
+
|
|
224
|
+
var alpha = textureSample(
|
|
225
|
+
fontAtlasTexture,
|
|
226
|
+
fontAtlasTextureSampler,
|
|
227
|
+
varyings.textureCoords
|
|
228
|
+
).a;
|
|
229
|
+
|
|
230
|
+
if (fastText.sdfEnabled > 0.5) {
|
|
231
|
+
alpha = smoothstep(
|
|
232
|
+
fastText.sdfBuffer - fastText.sdfGamma,
|
|
233
|
+
fastText.sdfBuffer + fastText.sdfGamma,
|
|
234
|
+
alpha
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let outputAlpha = alpha * varyings.color.a;
|
|
239
|
+
if (outputAlpha < fastText.alphaCutoff) {
|
|
240
|
+
discard;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return deckgl_premultiplied_alpha(
|
|
244
|
+
vec4<f32>(varyings.color.rgb, outputAlpha * layer.opacity)
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
`;
|
|
@@ -8,6 +8,7 @@ import {LineLayer, TextLayer, type TextLayerProps} from '@deck.gl/layers';
|
|
|
8
8
|
// import {PathStyleExtension} from '@deck.gl/extensions';
|
|
9
9
|
|
|
10
10
|
import {formatTimeMs} from '../utils/format-utils';
|
|
11
|
+
import {FastTextLayer} from './fast-text-layer/fast-text-layer';
|
|
11
12
|
|
|
12
13
|
/** Properties supported by {@link TimeDeltaLayer}. */
|
|
13
14
|
export type TimeDeltaLayerProps = LayerProps & _TimeDeltaLayerProps;
|
|
@@ -92,6 +93,7 @@ export class TimeDeltaLayer extends CompositeLayer<Required<_TimeDeltaLayerProps
|
|
|
92
93
|
const timeDeltaPosition = [(startTimeMs + endTimeMs) / 2, y - 10];
|
|
93
94
|
const timeDeltaMs = Math.abs(endTimeMs - startTimeMs);
|
|
94
95
|
const timeDeltaLabel = formatTimeMs(timeDeltaMs, {space: false});
|
|
96
|
+
const labelData = [{position: timeDeltaPosition, text: timeDeltaLabel}];
|
|
95
97
|
|
|
96
98
|
const timeLines = [
|
|
97
99
|
{
|
|
@@ -133,23 +135,38 @@ export class TimeDeltaLayer extends CompositeLayer<Required<_TimeDeltaLayerProps
|
|
|
133
135
|
}),
|
|
134
136
|
|
|
135
137
|
// Label
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
138
|
+
this.context?.device?.type === 'webgpu'
|
|
139
|
+
? new FastTextLayer({
|
|
140
|
+
id: 'header-time-delta-label',
|
|
141
|
+
data: labelData,
|
|
142
|
+
getPosition: d => d.position,
|
|
143
|
+
getText: d => d.text,
|
|
144
|
+
characterSet: '-0123456789.dhmsµ',
|
|
145
|
+
size: fontSize,
|
|
146
|
+
fontFamily,
|
|
147
|
+
fontSettings,
|
|
148
|
+
fontWeight,
|
|
149
|
+
getColor: color,
|
|
150
|
+
textAnchor: 'middle',
|
|
151
|
+
alignmentBaseline: 'center'
|
|
152
|
+
})
|
|
153
|
+
: new TextLayer({
|
|
154
|
+
id: 'header-time-delta-label',
|
|
155
|
+
data: labelData,
|
|
156
|
+
getPosition: d => d.position,
|
|
157
|
+
getText: d => d.text,
|
|
158
|
+
characterSet: '-0123456789.dhmsµ',
|
|
159
|
+
getSize: fontSize,
|
|
160
|
+
fontFamily,
|
|
161
|
+
fontSettings,
|
|
162
|
+
fontWeight,
|
|
163
|
+
getColor: color,
|
|
164
|
+
getTextAnchor: 'middle',
|
|
165
|
+
getAlignmentBaseline: 'center',
|
|
166
|
+
background: true,
|
|
167
|
+
getBackgroundColor: [255 - color[0], 255 - color[1], 255 - color[2], 255],
|
|
168
|
+
backgroundPadding: [4, 2]
|
|
169
|
+
})
|
|
153
170
|
];
|
|
154
171
|
}
|
|
155
172
|
}
|