@woosh/meep-engine 3.60.0 → 3.60.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.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/src/shade/playground/sh_exponential/main.js +2 -2
  3. package/src/shade/renderer/global_illumination/probe_clipmap/PROBE_CLIPMAP_PROPOSAL_2026_10_27.md +4 -0
  4. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts +6 -1
  5. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.d.ts.map +1 -1
  6. package/src/shade/renderer/global_illumination/probe_clipmap/probe/shader_probe_clipmap_shade.js +12 -4
  7. package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
  8. package/src/shade/renderer/light/GPULightCollection.js +3 -5
  9. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts +13 -5
  10. package/src/shade/renderer/light/environment/execute_filter_environment_map.d.ts.map +1 -1
  11. package/src/shade/renderer/light/environment/execute_filter_environment_map.js +133 -7
  12. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts +9 -0
  13. package/src/shade/renderer/light/environment/graph_filter_environment_map.d.ts.map +1 -1
  14. package/src/shade/renderer/light/environment/graph_filter_environment_map.js +33 -4
  15. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts +13 -0
  16. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.d.ts.map +1 -0
  17. package/src/shade/renderer/light/environment/shader_convolve_reflection_map_from_averages.js +169 -0
  18. package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts +3 -0
  19. package/src/shade/renderer/light/environment/shader_downsample_environment_map.d.ts.map +1 -0
  20. package/src/shade/renderer/light/environment/shader_downsample_environment_map.js +105 -0
  21. package/src/shade/renderer/light/environment/sphere_probe_lod_to_roughness.d.ts +10 -0
  22. package/src/shade/renderer/light/environment/sphere_probe_lod_to_roughness.d.ts.map +1 -0
  23. package/src/shade/renderer/light/environment/sphere_probe_lod_to_roughness.js +23 -0
  24. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts +8 -4
  25. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.d.ts.map +1 -1
  26. package/src/shade/renderer/shader/chunk/light/probe/chunk_probe_visibility_weight.js +9 -5
  27. package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
  28. package/src/shade/wgsl/emulator/WGSLLanguageCore.js +26 -1
  29. package/src/view/elements/progress/segmented/GhostTrail.d.ts +78 -12
  30. package/src/view/elements/progress/segmented/GhostTrail.d.ts.map +1 -1
  31. package/src/view/elements/progress/segmented/GhostTrail.js +294 -98
  32. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts +68 -24
  33. package/src/view/elements/progress/segmented/SegmentedResourceBarView.d.ts.map +1 -1
  34. package/src/view/elements/progress/segmented/SegmentedResourceBarView.js +196 -128
  35. package/src/view/elements/progress/segmented/playground/main.js +18 -11
  36. package/src/view/elements/progress/segmented/segment_cell_extent.d.ts +14 -0
  37. package/src/view/elements/progress/segmented/segment_cell_extent.d.ts.map +1 -0
  38. package/src/view/elements/progress/segmented/segment_cell_extent.js +44 -0
  39. package/src/view/elements/progress/segmented/segment_mask_url.d.ts +24 -0
  40. package/src/view/elements/progress/segmented/segment_mask_url.d.ts.map +1 -0
  41. package/src/view/elements/progress/segmented/segment_mask_url.js +74 -0
  42. package/src/view/elements/progress/segmented/segment_mask_width.d.ts +18 -0
  43. package/src/view/elements/progress/segmented/segment_mask_width.d.ts.map +1 -0
  44. package/src/view/elements/progress/segmented/segment_mask_width.js +46 -0
  45. package/src/view/elements/progress/segmented/segmented-resource-bar.css +6 -10
@@ -1,98 +1,294 @@
1
- import { smoothStep } from "../../../../core/math/smoothStep.js";
2
-
3
- /**
4
- * A value that trails another one down: the "ghost" behind a bar's fill that shows how much was just lost.
5
- *
6
- * When the target drops, the trail holds where it was for {@link delay_ms}, then eases down to the target over
7
- * {@link duration_ms}. A further drop while it holds or eases restarts the hold from wherever the trail is. When
8
- * the target rises above the trail, the trail jumps to it at once.
9
- *
10
- * Time is passed in, in milliseconds on any monotonic clock, so the trail can be driven and checked without one.
11
- */
12
- export class GhostTrail {
13
- /**
14
- * How long the trail holds after a drop before it starts to move
15
- * @type {number}
16
- */
17
- delay_ms = 450;
18
-
19
- /**
20
- * How long the ease from the held value down to the target takes; 0 snaps once the hold ends
21
- * @type {number}
22
- */
23
- duration_ms = 350;
24
-
25
- /**
26
- * @type {number}
27
- * @private
28
- */
29
- __from = 0;
30
-
31
- /**
32
- * @type {number}
33
- * @private
34
- */
35
- __to = 0;
36
-
37
- /**
38
- * When the current hold began
39
- * @type {number}
40
- * @private
41
- */
42
- __drop_time = 0;
43
-
44
- /**
45
- * Tell the trail its target's new value.
46
- * @param {number} target
47
- * @param {number} time_ms
48
- */
49
- set(target, time_ms) {
50
- const current = this.sample(time_ms);
51
-
52
- if (target >= current) {
53
- this.__from = target;
54
- this.__to = target;
55
- } else {
56
- this.__from = current;
57
- this.__to = target;
58
- this.__drop_time = time_ms;
59
- }
60
- }
61
-
62
- /**
63
- * Where the trail is at a given time; never below its target.
64
- * @param {number} time_ms
65
- * @returns {number}
66
- */
67
- sample(time_ms) {
68
- const from = this.__from;
69
- const to = this.__to;
70
-
71
- if (from === to) {
72
- return to;
73
- }
74
-
75
- const start = this.__drop_time + this.delay_ms;
76
-
77
- if (time_ms < start) {
78
- return from;
79
- }
80
-
81
- const end = start + this.duration_ms;
82
-
83
- if (time_ms >= end) {
84
- return to;
85
- }
86
-
87
- return from + (to - from) * smoothStep(start, end, time_ms);
88
- }
89
-
90
- /**
91
- * Whether the trail has reached its target and will not move until {@link set} is called again
92
- * @param {number} time_ms
93
- * @returns {boolean}
94
- */
95
- is_settled(time_ms) {
96
- return this.__from === this.__to || time_ms >= this.__drop_time + this.delay_ms + this.duration_ms;
97
- }
98
- }
1
+ import { assert } from "../../../../core/assert.js";
2
+ import { clamp01 } from "../../../../core/math/clamp01.js";
3
+
4
+ /**
5
+ * Floats per loss in {@link GhostTrail}'s store: [start, duration, low, amplitude]. A loss's trail is
6
+ * `low + amplitude * u²`, where u runs from 1 (held, and at the start of the ease) to 0 (the ease is over).
7
+ * @type {number}
8
+ */
9
+ const LOSS_STRIDE = 4;
10
+
11
+ /**
12
+ * A value that trails another one down: the "ghost" behind a bar's fill that shows how much was just lost.
13
+ *
14
+ * The knobs are the three Dota 2 exposes for its hero bars as console variables: a short hold after a drop
15
+ * (`dota_health_hurt_delay`) and a decay whose length sits between a floor and a ceiling
16
+ * (`dota_health_hurt_decay_time_min` / `_max`). The defaults, 0.1 s / 0.3 s / 0.8 s, are the values players'
17
+ * published configs list as Dota's own; Valve does not document them. Everything else here is this class's own
18
+ * choice, not known Dota behaviour: the decay's length growing linearly with the loss (the whole bar takes the
19
+ * ceiling), the ease-out curve, and how losses that overlap combine.
20
+ *
21
+ * Every drop is a loss with a trail of its own: it holds at the value from before the drop for {@link delay_ms},
22
+ * then eases down over a length sized by that loss alone. The trail shows the highest of the live losses' trails,
23
+ * and never less than the target. Because no loss looks at another, a drop is drawn the same whether the trail
24
+ * was at rest or still moving when it came: a damage tick that lands just before or just after the previous one
25
+ * has faded looks the same, where a single trail that re-plans has to pick one side of that line.
26
+ *
27
+ * Each loss eases toward the lowest the target has been since it happened, never toward the target itself, so a
28
+ * rise that stays under the trail (regeneration after a hit) cannot lift it. When a later drop lowers that floor,
29
+ * the rest of the loss's ease is rescaled toward the new floor from where it is, so it does not jump. The trail
30
+ * is continuous in time and never rises unless the target rises above it; when it does, the trail jumps to the
31
+ * target and every loss is forgotten.
32
+ *
33
+ * A target that is not a finite number is ignored: the trail carries on with what it had, so one bad value cannot
34
+ * leave it NaN, and its owner animating it forever, for every value after.
35
+ *
36
+ * Each loss's start and length are fixed when it happens, so changing the knobs never revives or reshapes a trail
37
+ * already under way.
38
+ *
39
+ * Time is passed in, in milliseconds on any monotonic clock, so the trail can be driven and checked without one.
40
+ */
41
+ export class GhostTrail {
42
+ /**
43
+ * How long a loss's trail holds before it starts to ease down
44
+ * @type {number}
45
+ */
46
+ delay_ms = 100;
47
+
48
+ /**
49
+ * Length of the ease for the smallest loss; 0 with {@link duration_max_ms} 0 snaps once the hold ends
50
+ * @type {number}
51
+ */
52
+ duration_min_ms = 300;
53
+
54
+ /**
55
+ * Length of the ease for a loss of the whole bar (1); smaller losses take proportionally less, down to
56
+ * {@link duration_min_ms}
57
+ * @type {number}
58
+ */
59
+ duration_max_ms = 800;
60
+
61
+ /**
62
+ * The target, as last set
63
+ * @type {number}
64
+ * @private
65
+ */
66
+ __to = 0;
67
+
68
+ /**
69
+ * Live losses, {@link LOSS_STRIDE} floats each: when the ease starts (after the hold), the ease's length, the
70
+ * lowest the target has been since the loss, and how far above that the trail is while u is 1
71
+ * @type {Float64Array}
72
+ * @private
73
+ */
74
+ __losses = new Float64Array(LOSS_STRIDE * 8);
75
+
76
+ /**
77
+ * @type {number}
78
+ * @private
79
+ */
80
+ __loss_count = 0;
81
+
82
+ /**
83
+ * Length of the ease for a loss of `gap`, a fraction of the bar
84
+ * @param {number} gap
85
+ * @returns {number}
86
+ * @private
87
+ */
88
+ __duration_for(gap) {
89
+ const min = this.duration_min_ms;
90
+
91
+ return min + (this.duration_max_ms - min) * clamp01(gap);
92
+ }
93
+
94
+ /**
95
+ * How much of one loss's ease is left at `time_ms`: 1 while it holds, falling to 0 when the ease is over
96
+ * @param {number} index
97
+ * @param {number} time_ms
98
+ * @returns {number}
99
+ * @private
100
+ */
101
+ __loss_u(index, time_ms) {
102
+ const losses = this.__losses;
103
+ const offset = index * LOSS_STRIDE;
104
+
105
+ const elapsed = time_ms - losses[offset];
106
+ const duration = losses[offset + 1];
107
+
108
+ if (elapsed < 0) {
109
+ return 1;
110
+ }
111
+
112
+ if (elapsed >= duration) {
113
+ return 0;
114
+ }
115
+
116
+ return 1 - elapsed / duration;
117
+ }
118
+
119
+ /**
120
+ * Where one loss's trail is at `time_ms`; an ease-out, fastest at the start of the ease
121
+ * @param {number} index
122
+ * @param {number} time_ms
123
+ * @returns {number}
124
+ * @private
125
+ */
126
+ __loss_at(index, time_ms) {
127
+ const offset = index * LOSS_STRIDE;
128
+ const u = this.__loss_u(index, time_ms);
129
+
130
+ return this.__losses[offset + 2] + this.__losses[offset + 3] * u * u;
131
+ }
132
+
133
+ /**
134
+ * @param {number} start
135
+ * @param {number} duration
136
+ * @param {number} low
137
+ * @param {number} amplitude
138
+ * @private
139
+ */
140
+ __add_loss(start, duration, low, amplitude) {
141
+ const count = this.__loss_count;
142
+
143
+ if ((count + 1) * LOSS_STRIDE > this.__losses.length) {
144
+ const grown = new Float64Array(this.__losses.length * 2);
145
+
146
+ grown.set(this.__losses);
147
+
148
+ this.__losses = grown;
149
+ }
150
+
151
+ const losses = this.__losses;
152
+ const offset = count * LOSS_STRIDE;
153
+
154
+ losses[offset] = start;
155
+ losses[offset + 1] = duration;
156
+ losses[offset + 2] = low;
157
+ losses[offset + 3] = amplitude;
158
+
159
+ this.__loss_count = count + 1;
160
+ }
161
+
162
+ /**
163
+ * Tell the trail its target's new value.
164
+ * @param {number} target
165
+ * @param {number} time_ms
166
+ */
167
+ set(target, time_ms) {
168
+ // the knobs are public and may change between calls, so they are checked where they are read
169
+ assert.isFinite(this.delay_ms, 'delay_ms');
170
+ assert.greaterThanOrEqual(this.delay_ms, 0, 'delay_ms must not be negative');
171
+ assert.isFinite(this.duration_max_ms, 'duration_max_ms');
172
+ assert.greaterThanOrEqual(this.duration_min_ms, 0, 'duration_min_ms must not be negative');
173
+ assert.greaterThanOrEqual(this.duration_max_ms, this.duration_min_ms, 'duration_max_ms must not be under duration_min_ms');
174
+ assert.isFinite(time_ms, 'time_ms');
175
+
176
+ if (!Number.isFinite(target)) {
177
+ return;
178
+ }
179
+
180
+ if (target >= this.sample(time_ms)) {
181
+ // a rise to or above the trail: jump to it, and forget every loss
182
+ this.__to = target;
183
+ this.__loss_count = 0;
184
+
185
+ return;
186
+ }
187
+
188
+ // drop the losses whose ease is over (each rests at its low, which is never above the target); for the rest,
189
+ // if the target went under the low, lower it and rescale what is left of the ease so the trail is where it was
190
+ const losses = this.__losses;
191
+ const count = this.__loss_count;
192
+
193
+ let kept = 0;
194
+
195
+ for (let i = 0; i < count; i++) {
196
+ const offset = i * LOSS_STRIDE;
197
+
198
+ const u = this.__loss_u(i, time_ms);
199
+
200
+ if (u <= 0) {
201
+ continue;
202
+ }
203
+
204
+ let low = losses[offset + 2];
205
+ let amplitude = losses[offset + 3];
206
+
207
+ if (target < low) {
208
+ // where the trail is now, kept: low + amplitude * u² before and after. u > 0 here, and the
209
+ // product amplitude * u² stays at most the trail's height over the new low however small u is
210
+ const value = low + amplitude * u * u;
211
+
212
+ low = target;
213
+ amplitude = (value - low) / (u * u);
214
+ }
215
+
216
+ const kept_offset = kept * LOSS_STRIDE;
217
+
218
+ losses[kept_offset] = losses[offset];
219
+ losses[kept_offset + 1] = losses[offset + 1];
220
+ losses[kept_offset + 2] = low;
221
+ losses[kept_offset + 3] = amplitude;
222
+
223
+ kept++;
224
+ }
225
+
226
+ this.__loss_count = kept;
227
+
228
+ const before = this.__to;
229
+
230
+ if (target < before) {
231
+ this.__add_loss(time_ms + this.delay_ms, this.__duration_for(before - target), target, before - target);
232
+ }
233
+
234
+ this.__to = target;
235
+ }
236
+
237
+ /**
238
+ * Stand the trail at `target` with nothing lost: every loss forgotten, whatever was showing. For a target that
239
+ * moved without anything being lost, such as the same amount out of a raised maximum.
240
+ * @param {number} target
241
+ */
242
+ reset(target) {
243
+ if (!Number.isFinite(target)) {
244
+ return;
245
+ }
246
+
247
+ this.__to = target;
248
+ this.__loss_count = 0;
249
+ }
250
+
251
+ /**
252
+ * Where the trail is at a given time: the highest of the live losses' trails, and never below the target.
253
+ * @param {number} time_ms
254
+ * @returns {number}
255
+ */
256
+ sample(time_ms) {
257
+ let value = this.__to;
258
+
259
+ const count = this.__loss_count;
260
+
261
+ for (let i = 0; i < count; i++) {
262
+ const v = this.__loss_at(i, time_ms);
263
+
264
+ if (v > value) {
265
+ value = v;
266
+ }
267
+ }
268
+
269
+ return value;
270
+ }
271
+
272
+ /**
273
+ * Whether the trail shows the target and will not move until {@link set} is called again
274
+ * @param {number} time_ms
275
+ * @returns {boolean}
276
+ */
277
+ is_settled(time_ms) {
278
+ const to = this.__to;
279
+ const losses = this.__losses;
280
+ const count = this.__loss_count;
281
+
282
+ for (let i = 0; i < count; i++) {
283
+ const offset = i * LOSS_STRIDE;
284
+
285
+ // a loss still easing and still above the target; one at or under it stays there, since its trail
286
+ // only falls and the target holds until the next set
287
+ if (time_ms < losses[offset] + losses[offset + 1] && this.__loss_at(i, time_ms) > to) {
288
+ return false;
289
+ }
290
+ }
291
+
292
+ return true;
293
+ }
294
+ }
@@ -3,11 +3,18 @@
3
3
  * a ghost behind the fill trails a drop so the loss stays readable for a moment.
4
4
  *
5
5
  * Two modes:
6
- * - notches (default): a continuous fill, with a notch at every multiple of each {@link SegmentTier}'s unit;
7
- * - cells (`cells` given): `count` separate cells with exact, identical gaps, for counting rounds and the like.
6
+ * - notches (default): a continuous fill, with a notch at every multiple of each {@link SegmentTier}'s unit. Each
7
+ * tier is one layer the width of the bar (`.notch.<class_name>`), which CSS paints — colour, height — and a mask
8
+ * cuts to that tier's notches;
9
+ * - cells (`cells` given): `count` separate cells with exact, identical gaps, for counting rounds and the like. One
10
+ * strip (`.cell-strip`, the empty cells' colour) holding a `.cell-ghost` and a `.cell-fill`, cut into cells by a
11
+ * mask; the fill and ghost end on a cell's edge, or part way across one that is filling.
8
12
  *
9
- * Notches and cells sit on whole device pixels at any pixel ratio and under a CSS scale. Colours, notch heights
10
- * and the ghost are styled by `segmented-resource-bar.css` through `--segmented-bar-*` custom properties.
13
+ * The masks are drawn in whole device pixels and the layers they cut placed so those pixels land on the screen's,
14
+ * at any pixel ratio and under a CSS scale: every notch of a tier is the same width and every gap the same, at
15
+ * 125% as at 100%. Colours, notch heights and the ghost are styled by `segmented-resource-bar.css` through
16
+ * `--segmented-bar-*` custom properties. Where masks cannot be drawn (no canvas, as under jsdom) the layers are
17
+ * placed but uncut.
11
18
  */
12
19
  export class SegmentedResourceBarView extends View {
13
20
  /**
@@ -18,10 +25,12 @@ export class SegmentedResourceBarView extends View {
18
25
  * @param {string[]} [options.classList]
19
26
  * @param {{unit:number, class_name:string, width_px:number, min_spacing_px:number}[]} [options.tiers] notch tiers, finest first; see {@link SegmentTier}
20
27
  * @param {{count:number, group:number}|null} [options.cells] draw `count` cells instead of notches, in groups of `group` (0 for none)
21
- * @param {number} [options.ghost_delay_ms=450] how long the ghost holds after a drop
22
- * @param {number} [options.ghost_duration_ms=350] how long the ghost then takes to catch up; 0 under prefers-reduced-motion
28
+ * @param {number} [options.ghost_delay_ms=100] how long the ghost holds after a drop; see {@link GhostTrail}
29
+ * @param {number} [options.ghost_duration_min_ms=300] how long the ghost takes to close the smallest loss
30
+ * @param {number} [options.ghost_duration_max_ms=800] how long it takes to close a loss of the whole bar; both
31
+ * durations are 0 under prefers-reduced-motion, so the ghost holds, then snaps
23
32
  */
24
- constructor({ values, max, classList, tiers, cells, ghost_delay_ms, ghost_duration_ms }: {
33
+ constructor({ values, max, classList, tiers, cells, ghost_delay_ms, ghost_duration_min_ms, ghost_duration_max_ms }: {
25
34
  values: (Vector1 | ObservedInteger)[];
26
35
  max?: Vector1 | ObservedInteger | ReactiveExpression;
27
36
  classList?: string[];
@@ -36,7 +45,8 @@ export class SegmentedResourceBarView extends View {
36
45
  group: number;
37
46
  } | null;
38
47
  ghost_delay_ms?: number;
39
- ghost_duration_ms?: number;
48
+ ghost_duration_min_ms?: number;
49
+ ghost_duration_max_ms?: number;
40
50
  });
41
51
  /**
42
52
  *
@@ -69,7 +79,12 @@ export class SegmentedResourceBarView extends View {
69
79
  * @type {number}
70
80
  * @private
71
81
  */
72
- private __ghost_duration_ms;
82
+ private __ghost_duration_min_ms;
83
+ /**
84
+ * @type {number}
85
+ * @private
86
+ */
87
+ private __ghost_duration_max_ms;
73
88
  /**
74
89
  * Total fill as a fraction of max, as last drawn
75
90
  * @type {number}
@@ -97,16 +112,34 @@ export class SegmentedResourceBarView extends View {
97
112
  * @private
98
113
  */
99
114
  private __animate_ghost;
115
+ /**
116
+ * The max moved since the fill was last drawn: the next fill resets the ghost rather than trailing a loss
117
+ * @type {boolean}
118
+ * @private
119
+ */
120
+ private __max_moved;
100
121
  __built_max: number;
101
122
  __built_width: number;
102
123
  __built_ratio: number;
103
124
  __built_origin_phase: number;
104
125
  /**
105
- * scratch for {@link segment_notch_place}
106
- * @type {Float64Array}
126
+ * Cell mode: the cells as last laid out across {@link __el_strip}, or null before the bar has been measured
127
+ * @type {SegmentCellLayout|null}
128
+ * @private
129
+ */
130
+ private __cell_layout;
131
+ /**
132
+ * Device pixels per CSS pixel the cells were laid out at
133
+ * @type {number}
107
134
  * @private
108
135
  */
109
- private __place;
136
+ private __cell_ratio;
137
+ /**
138
+ * scratch: [x, width, ...] device-pixel columns for a mask
139
+ * @type {number[]}
140
+ * @private
141
+ */
142
+ private __columns;
110
143
  /**
111
144
  *
112
145
  * @type {List<NumericInterval>}
@@ -124,20 +157,19 @@ export class SegmentedResourceBarView extends View {
124
157
  */
125
158
  private __value_fills;
126
159
  /**
160
+ * Notch mode: one layer per tier, the whole bar wide, styled by the tier's class and masked to its notches
127
161
  * @type {HTMLElement[]}
128
162
  * @private
129
163
  */
130
- private __notch_elements;
164
+ private __tier_layers;
131
165
  /**
132
- * @type {HTMLElement[]}
166
+ * Cell mode: the strip the cells are cut from by a mask, and the ghost and fill drawn along it
167
+ * @type {HTMLElement|null}
133
168
  * @private
134
169
  */
135
- private __cell_elements;
136
- __cell_fill_elements: HTMLDivElement[];
137
- __cell_ghost_elements: HTMLDivElement[];
138
- __cell_states: Uint8Array;
139
- __cell_fill_drawn: Float64Array;
140
- __cell_ghost_drawn: Float64Array;
170
+ private __el_strip;
171
+ __el_cell_ghost: HTMLDivElement;
172
+ __el_cell_fill: HTMLDivElement;
141
173
  /**
142
174
  * The notches' own box; what they are positioned in and what is measured to place them
143
175
  * @type {HTMLElement}
@@ -160,19 +192,31 @@ export class SegmentedResourceBarView extends View {
160
192
  /**
161
193
  * Place the notches or cells again, if the max, the bar's width (by {@link REBUILD_WIDTH_THRESHOLD_PX} or more),
162
194
  * its pixel ratio or the device-pixel phase of its left edge has moved since they were last placed.
195
+ *
196
+ * Both are drawn as a mask in whole device pixels over a layer CSS paints (see {@link segment_mask_url}): a DOM
197
+ * box per notch or cell cannot be put on the device-pixel grid at a fractional pixel ratio, where Chrome paints
198
+ * a row of equal 1 px gaps as 1, 2, 1, 2... whatever positions it is given (measured at 125% and 150%).
163
199
  */
164
200
  updateSegments(): void;
201
+ /**
202
+ * @param {HTMLElement} el
203
+ * @param {number} width_device
204
+ * @param {number} shift_px
205
+ * @param {number} ratio
206
+ * @private
207
+ */
208
+ private __place_layer;
165
209
  /**
166
210
  * @param {number} max
167
- * @param {number} width
168
- * @param {number} left
211
+ * @param {number} width_device
212
+ * @param {number} shift_px
169
213
  * @param {number} ratio
170
214
  * @private
171
215
  */
172
216
  private __place_notches;
173
217
  /**
174
- * @param {number} width
175
- * @param {number} left
218
+ * @param {number} width_device
219
+ * @param {number} shift_px
176
220
  * @param {number} ratio
177
221
  * @private
178
222
  */
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedResourceBarView.d.ts","sourceRoot":"","sources":["../../../../../../src/view/elements/progress/segmented/SegmentedResourceBarView.js"],"names":[],"mappings":"AA0CA;;;;;;;;;;GAUG;AACH;IACI;;;;;;;;;;OAUG;IACH;QARgD,MAAM,EAA3C,CAAC,OAAO,kBAAgB,CAAC,EAAE;QAC0B,GAAG,GAAxD,OAAO,uCAAmC;QACvB,SAAS,GAA5B,MAAM,EAAE;QAC6E,KAAK,GAA1F;YAAC,IAAI,EAAC,MAAM,CAAC;YAAC,UAAU,EAAC,MAAM,CAAC;YAAC,QAAQ,EAAC,MAAM,CAAC;YAAC,cAAc,EAAC,MAAM,CAAA;SAAC,EAAE;QAC9B,KAAK,GAAjD;YAAC,KAAK,EAAC,MAAM,CAAC;YAAC,KAAK,EAAC,MAAM,CAAA;SAAC,GAAC,IAAI;QAChB,cAAc,GAA/B,MAAM;QACW,iBAAiB,GAAlC,MAAM;OAsQhB;IA9OG;;;;OAIG;IACH,yBAA8B;IAE9B;;;;OAIG;IACH,oBAAsB;IAEtB;;;OAGG;IACH,gBAAoB;IAEpB;;;OAGG;IACH,gBAAoB;IAEpB;;;OAGG;IACH,gBAA+B;IAG/B;;;OAGG;IACH,4BAA4C;IAE5C;;;;OAIG;IACH,yBAAyB;IAEzB;;;OAGG;IACH,yBAAgH;IAEhH;;;;OAIG;IACH,oBAAuB;IAie3B;;OAEG;IACH,4BASC;IAzeG,yBAA4B;IAC5B,mBAAmB;IA8bvB;;OAEG;IACH,wBAQC;IArcG,oBAAsB;IACtB,sBAAwB;IACxB,sBAAwB;IACxB,6BAA+B;IAE/B;;;;OAIG;IACH,gBAAkC;IAElC;;;OAGG;IACH,YAFU,qBAAqB,CAEH;IAG5B,mBAAuC;IASvC;;;OAGG;IACH,mBAA+C;IAG/C;;;OAGG;IACH,sBAAuB;IAEvB;;;OAGG;IACH,yBAA0B;IAE1B;;;OAGG;IACH,wBAAyB;IACzB,uCAA8B;IAC9B,wCAA+B;IAC/B,0BAAqE;IAGrE,gCAA2E;IAC3E,iCAA4E;IAkBxE;;;;OAIG;IACH,oBAAgD;IA8BpD;;;OAGG;IACH,gBAFU,QAAQ,CAsChB;IAWF;;;;OAIG;IACH,uBAA2C;IAuC/C,eAGC;IAED,wBAGC;IAED;;;OAGG;IACH,uBAmDC;IAED;;;;;;OAMG;IACH,wBAoCC;IAED;;;;;OAKG;IACH,sBAkBC;IAED,mBAwCC;IAED;;;;OAIG;IACH,eAaC;IAED;;;;OAIG;IACH,qBA6BC;IAeD;;;;OAIG;IACH,mCAUC;CAeJ;iBAxnBgB,kBAAkB;iBALlB,0CAA0C;qBAGtC,6BAA6B;oBAF9B,kCAAkC"}
1
+ {"version":3,"file":"SegmentedResourceBarView.d.ts","sourceRoot":"","sources":["../../../../../../src/view/elements/progress/segmented/SegmentedResourceBarView.js"],"names":[],"mappings":"AA4BA;;;;;;;;;;;;;;;;;GAiBG;AACH;IACI;;;;;;;;;;;;OAYG;IACH;QAVgD,MAAM,EAA3C,CAAC,OAAO,kBAAgB,CAAC,EAAE;QAC0B,GAAG,GAAxD,OAAO,uCAAmC;QACvB,SAAS,GAA5B,MAAM,EAAE;QAC6E,KAAK,GAA1F;YAAC,IAAI,EAAC,MAAM,CAAC;YAAC,UAAU,EAAC,MAAM,CAAC;YAAC,QAAQ,EAAC,MAAM,CAAC;YAAC,cAAc,EAAC,MAAM,CAAA;SAAC,EAAE;QAC9B,KAAK,GAAjD;YAAC,KAAK,EAAC,MAAM,CAAC;YAAC,KAAK,EAAC,MAAM,CAAA;SAAC,GAAC,IAAI;QAChB,cAAc,GAA/B,MAAM;QACW,qBAAqB,GAAtC,MAAM;QACW,qBAAqB,GAAtC,MAAM;OAyShB;IA5QG;;;;OAIG;IACH,yBAA8B;IAE9B;;;;OAIG;IACH,oBAAsB;IAEtB;;;OAGG;IACH,gBAAoB;IAEpB;;;OAGG;IACH,gBAAoB;IAEpB;;;OAGG;IACH,gBAA+B;IAG/B;;;OAGG;IACH,gCAAoD;IAEpD;;;OAGG;IACH,gCAAoD;IAEpD;;;;OAIG;IACH,yBAAyB;IAEzB;;;OAGG;IACH,yBAAgH;IAEhH;;;;OAIG;IACH,oBAAuB;IAgiB3B;;OAEG;IACH,4BASC;IAxiBG,yBAA4B;IAC5B,mBAAmB;IA6fvB;;OAEG;IACH,wBAQC;IArgBG;;;;OAIG;IACH,oBAAwB;IAGxB,oBAAsB;IACtB,sBAAwB;IACxB,sBAAwB;IACxB,6BAA+B;IAE/B;;;;OAIG;IACH,sBAAyB;IAEzB;;;;OAIG;IACH,qBAAqB;IAErB;;;;OAIG;IACH,kBAAmB;IAEnB;;;OAGG;IACH,YAFU,qBAAqB,CAEH;IAG5B,mBAAuC;IASvC;;;OAGG;IACH,mBAA+C;IAG/C;;;OAGG;IACH,sBAAuB;IAEvB;;;;OAIG;IACH,sBAAuB;IAEvB;;;;OAIG;IACH,mBAAsB;IACtB,gCAA2B;IAC3B,+BAA0B;IAkBtB;;;;OAIG;IACH,oBAAgD;IAoCpD;;;OAGG;IACH,gBAFU,QAAQ,CAsChB;IAWF;;;;OAIG;IACH,uBAA2C;IAuC/C,eAGC;IAED,wBAMC;IAED;;;;;;;OAOG;IACH,uBA4DC;IAED;;;;;;OAMG;IACH,sBAKC;IAED;;;;;;OAMG;IACH,wBA2CC;IAED;;;;;OAKG;IACH,sBAoBC;IAED,mBAiDC;IAED;;;;OAIG;IACH,eAaC;IAED;;;;OAIG;IACH,qBAoBC;IAeD;;;;OAIG;IACH,mCAUC;CAeJ;iBA5rBgB,kBAAkB;iBALlB,0CAA0C;qBAGtC,6BAA6B;oBAF9B,kCAAkC"}