palette-shader 0.18.0 → 0.20.0

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/README.md CHANGED
@@ -174,10 +174,21 @@ viz.removeColor([0.659, 0.855, 0.863]);
174
174
 
175
175
  Cancel the animation frame, release all WebGL resources (programs, textures, framebuffer, buffer, VAO), and remove the canvas from the DOM.
176
176
 
177
+ ### `render()`
178
+
179
+ Force a synchronous render immediately, bypassing the `requestAnimationFrame` schedule. Use this when the canvas (or its WebGL drawing buffer) must reflect the latest state right now — for example before reading pixels back from the canvas in the same JS tick.
180
+
181
+ ```js
182
+ viz.render();
183
+ // canvas drawing buffer is now up to date — safe to readPixels(...)
184
+ ```
185
+
177
186
  ### `getColorAtUV(x, y)`
178
187
 
179
188
  Returns the current shader result at normalized UV coordinates (`0–1` on both axes) as `[r, g, b]` in `0–1` sRGB. This reads directly from the WebGL render target (or outline source buffer), not from DOM canvas sampling.
180
189
 
190
+ When a paint is already pending (state changed since the last frame) it renders first; when the render target is already current it skips the redundant render and reads back directly. If you need to guarantee a fresh render as a side effect, call `render()` explicitly.
191
+
181
192
  ```js
182
193
  const color = viz.getColorAtUV(0.5, 0.5); // center
183
194
  ```
@@ -40,6 +40,10 @@ declare abstract class BasePaletteRenderer {
40
40
  get width(): number;
41
41
  get height(): number;
42
42
  resize(width: number, height?: number | null): void;
43
+ /** Force a synchronous render immediately, bypassing the rAF schedule.
44
+ * Use when the canvas/FBO must reflect the latest state right now — e.g.
45
+ * before reading pixels back from the canvas. */
46
+ render(): void;
43
47
  set palette(palette: ColorList);
44
48
  get palette(): ColorList;
45
49
  set pixelRatio(value: number);
@@ -142,7 +142,7 @@ ${_}`);
142
142
  function H(r, t) {
143
143
  r.bindTexture(r.TEXTURE_2D, t), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MIN_FILTER, r.NEAREST), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_MAG_FILTER, r.NEAREST), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_S, r.CLAMP_TO_EDGE), r.texParameteri(r.TEXTURE_2D, r.TEXTURE_WRAP_T, r.CLAMP_TO_EDGE);
144
144
  }
145
- function O(r, t, n) {
145
+ function S(r, t, n) {
146
146
  if (n.length === 0) throw new Error("Palette must contain at least one color");
147
147
  const e = new Float32Array(n.length * 4);
148
148
  n.forEach(([a, o, s], i) => {
@@ -1299,7 +1299,7 @@ vec3 closestColor(vec3 color, sampler2D paletteTexture) {
1299
1299
 
1300
1300
  return closest;
1301
1301
  }
1302
- `, S = `
1302
+ `, O = `
1303
1303
  precision highp float;
1304
1304
  layout(location = 0) in vec2 a_position;
1305
1305
  out vec2 vUv;
@@ -1750,7 +1750,7 @@ uniform sampler2D paletteTexture;
1750
1750
  return e && (o += `uniform vec2 uvOverride;
1751
1751
  `), o += F(a), o += P + st, o;
1752
1752
  }
1753
- const xt = `
1753
+ const Et = `
1754
1754
  precision highp float;
1755
1755
  layout(location = 0) in vec3 a_position;
1756
1756
  out vec3 vColorCoord;
@@ -1772,7 +1772,7 @@ void main() {
1772
1772
  vColorCoord = pos;
1773
1773
  #endif
1774
1774
  gl_Position = uMVP * vec4(pos - 0.5, 1.0);
1775
- }`, Et = `
1775
+ }`, xt = `
1776
1776
  precision highp float;
1777
1777
  layout(location = 0) in vec3 a_position;
1778
1778
  out vec3 vColorCoord;
@@ -1950,7 +1950,7 @@ void main() {
1950
1950
  return;
1951
1951
  }
1952
1952
  fragColor = center;
1953
- }`, w = { x: 0, y: 1, z: 2 }, Mt = 31, yt = 32, x = {
1953
+ }`, w = { x: 0, y: 1, z: 2 }, Mt = 31, yt = 32, E = {
1954
1954
  rgb: 0,
1955
1955
  rgb12bit: 1,
1956
1956
  rgb8bit: 2,
@@ -1984,7 +1984,7 @@ void main() {
1984
1984
  spectrum: 28,
1985
1985
  oklchDiag: 29,
1986
1986
  oklrchDiag: 30
1987
- }, E = {
1987
+ }, x = {
1988
1988
  rgb: 0,
1989
1989
  oklab: 1,
1990
1990
  deltaE76: 2,
@@ -2024,7 +2024,7 @@ class lt {
2024
2024
  this.paletteState = t, this.cssWidth = n, this.cssHeight = e, this.pixelRatioState = a, this.observeResize = o, this.containerElement = s, this.canvasElement = document.createElement("canvas"), this.canvasElement.classList.add(i);
2025
2025
  const l = this.canvasElement.getContext("webgl2");
2026
2026
  if (!l) throw new Error("WebGL2 not supported");
2027
- this.glContext = l, this.paletteTexture = l.createTexture(), H(l, this.paletteTexture), O(l, this.paletteTexture, this.paletteState), this.metricTexture = l.createTexture(), H(l, this.metricTexture);
2027
+ this.glContext = l, this.paletteTexture = l.createTexture(), H(l, this.paletteTexture), S(l, this.paletteTexture, this.paletteState), this.metricTexture = l.createTexture(), H(l, this.metricTexture);
2028
2028
  }
2029
2029
  normalizeInvertAxes(t) {
2030
2030
  const n = /* @__PURE__ */ new Set();
@@ -2088,9 +2088,15 @@ class lt {
2088
2088
  const { pw: e, ph: a } = this.syncCanvasSize(t, n ?? t);
2089
2089
  this.onSurfaceResized(e, a), this.schedulePaint();
2090
2090
  }
2091
+ /** Force a synchronous render immediately, bypassing the rAF schedule.
2092
+ * Use when the canvas/FBO must reflect the latest state right now — e.g.
2093
+ * before reading pixels back from the canvas. */
2094
+ render() {
2095
+ this.destroyed || (this.flushScheduledPaint(), this.renderFrame());
2096
+ }
2091
2097
  set palette(t) {
2092
2098
  if (t.length === 0) throw new Error("Palette must contain at least one color");
2093
- this.paletteState = t, O(this.glContext, this.paletteTexture, t), this.metricPaletteDirty = !0, this.schedulePaint();
2099
+ this.paletteState = t, S(this.glContext, this.paletteTexture, t), this.metricPaletteDirty = !0, this.schedulePaint();
2094
2100
  }
2095
2101
  get palette() {
2096
2102
  return this.paletteState.slice();
@@ -2129,8 +2135,8 @@ class Xt extends lt {
2129
2135
  #s = null;
2130
2136
  #g = null;
2131
2137
  #C = null;
2132
- #M = null;
2133
2138
  #y = null;
2139
+ #S = null;
2134
2140
  // 1×1 float FBO for getColorAtUV_float (lazily created)
2135
2141
  #m = null;
2136
2142
  #p = null;
@@ -2138,9 +2144,9 @@ class Xt extends lt {
2138
2144
  #I = null;
2139
2145
  #D = null;
2140
2146
  #O = null;
2141
- #S = null;
2147
+ #P = null;
2142
2148
  #w = null;
2143
- #P = !0;
2149
+ #A = !0;
2144
2150
  constructor({
2145
2151
  palette: t = J(),
2146
2152
  width: n = 512,
@@ -2167,13 +2173,13 @@ class Xt extends lt {
2167
2173
  canvasClassName: "palette-viz"
2168
2174
  }), this.#o = i, this.#c = l, this.#i = _, this.#d = b, this.#f = this.normalizeInvertAxes(C), this.#_ = f, this.#v = h, this.#n = d;
2169
2175
  const c = this.glContext;
2170
- this.#l = c.createBuffer(), c.bindBuffer(c.ARRAY_BUFFER, this.#l), c.bufferData(c.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), c.STATIC_DRAW), this.#a = c.createVertexArray(), c.bindVertexArray(this.#a), c.enableVertexAttribArray(0), c.vertexAttribPointer(0, 2, c.FLOAT, !1, 0, 0), c.bindVertexArray(null), this.#x(), this.syncCanvasSize(this.width, this.height), this.#E(), this.attachCanvas(), this.schedulePaint();
2176
+ this.#l = c.createBuffer(), c.bindBuffer(c.ARRAY_BUFFER, this.#l), c.bufferData(c.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), c.STATIC_DRAW), this.#a = c.createVertexArray(), c.bindVertexArray(this.#a), c.enableVertexAttribArray(0), c.vertexAttribPointer(0, 2, c.FLOAT, !1, 0, 0), c.bindVertexArray(null), this.#E(), this.syncCanvasSize(this.width, this.height), this.#x(), this.attachCanvas(), this.schedulePaint();
2171
2177
  }
2172
2178
  #k() {
2173
2179
  const t = this.#o.endsWith("Polar") && this.#f.includes("y");
2174
2180
  return {
2175
- DISTANCE_METRIC: E[this.#c],
2176
- COLOR_MODEL: x[this.#o],
2181
+ DISTANCE_METRIC: x[this.#c],
2182
+ COLOR_MODEL: E[this.#o],
2177
2183
  PROGRESS_AXIS: w[this.#i],
2178
2184
  INVERT_X: this.#f.includes("x") ? 1 : !1,
2179
2185
  INVERT_Y: this.#f.includes("y") && !t ? 1 : !1,
@@ -2183,19 +2189,19 @@ class Xt extends lt {
2183
2189
  GAMUT_CLIP: this.#n ? 1 : !1
2184
2190
  };
2185
2191
  }
2186
- #x() {
2192
+ #E() {
2187
2193
  const t = this.glContext;
2188
2194
  this.#t && t.deleteProgram(this.#t);
2189
2195
  const n = V(
2190
- x[this.#o],
2191
- E[this.#c],
2196
+ E[this.#o],
2197
+ x[this.#c],
2192
2198
  this.#_
2193
2199
  );
2194
- this.#t = y(t, this.#k(), n, S), this.#u = t.getUniformLocation(this.#t, "progress"), this.#T = t.getUniformLocation(this.#t, "paletteTexture"), this.#b = t.getUniformLocation(this.#t, "paletteMetricTexture"), this.#R = t.getUniformLocation(this.#t, "uPaletteSize"), this.metricPaletteDirty = !0, this.#P = !0;
2200
+ this.#t = y(t, this.#k(), n, O), this.#u = t.getUniformLocation(this.#t, "progress"), this.#T = t.getUniformLocation(this.#t, "paletteTexture"), this.#b = t.getUniformLocation(this.#t, "paletteMetricTexture"), this.#R = t.getUniformLocation(this.#t, "uPaletteSize"), this.metricPaletteDirty = !0, this.#A = !0;
2195
2201
  }
2196
- #E() {
2202
+ #x() {
2197
2203
  const t = this.glContext;
2198
- this.#g = y(t, {}, it, S), this.#C = t.getUniformLocation(this.#g, "colorMap"), this.#M = t.getUniformLocation(this.#g, "outlineWidth"), this.#y = t.getUniformLocation(this.#g, "resolution"), this.#s = t.createTexture(), this.#e = t.createFramebuffer(), this.#L(this.canvas.width, this.canvas.height);
2204
+ this.#g = y(t, {}, it, O), this.#C = t.getUniformLocation(this.#g, "colorMap"), this.#y = t.getUniformLocation(this.#g, "outlineWidth"), this.#S = t.getUniformLocation(this.#g, "resolution"), this.#s = t.createTexture(), this.#e = t.createFramebuffer(), this.#L(this.canvas.width, this.canvas.height);
2199
2205
  }
2200
2206
  #L(t, n) {
2201
2207
  const e = this.glContext;
@@ -2208,15 +2214,15 @@ class Xt extends lt {
2208
2214
  ), e.bindFramebuffer(e.FRAMEBUFFER, null);
2209
2215
  }
2210
2216
  currentMetricCode() {
2211
- return E[this.#c];
2217
+ return x[this.#c];
2212
2218
  }
2213
2219
  onSurfaceResized(t, n) {
2214
2220
  this.#s && this.#L(t, n);
2215
2221
  }
2216
2222
  renderFrame() {
2217
- this.#r && (this.#x(), this.#r = !1);
2223
+ this.#r && (this.#E(), this.#r = !1);
2218
2224
  const t = this.glContext;
2219
- t.bindFramebuffer(t.FRAMEBUFFER, this.#e), t.useProgram(this.#t), this.uploadMetricPalette(this.#R), t.uniform1f(this.#u, this.#d), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.paletteTexture), t.uniform1i(this.#T, 0), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, this.metricTexture), t.uniform1i(this.#b, 1), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.bindVertexArray(this.#a), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.flush(), t.bindFramebuffer(t.FRAMEBUFFER, null), t.useProgram(this.#g), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.#s), t.uniform1i(this.#C, 0), t.uniform1f(this.#M, this.#_ ? 0 : this.#v), t.uniform2f(this.#y, this.canvas.width, this.canvas.height), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindVertexArray(null);
2225
+ t.bindFramebuffer(t.FRAMEBUFFER, this.#e), t.useProgram(this.#t), this.uploadMetricPalette(this.#R), t.uniform1f(this.#u, this.#d), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.paletteTexture), t.uniform1i(this.#T, 0), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, this.metricTexture), t.uniform1i(this.#b, 1), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.bindVertexArray(this.#a), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindFramebuffer(t.FRAMEBUFFER, null), t.useProgram(this.#g), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.#s), t.uniform1i(this.#C, 0), t.uniform1f(this.#y, this.#_ ? 0 : this.#v), t.uniform2f(this.#S, this.canvas.width, this.canvas.height), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindVertexArray(null);
2220
2226
  }
2221
2227
  // ── Public API ──────────────────────────────────────────────────────────────
2222
2228
  destroy() {
@@ -2228,10 +2234,10 @@ class Xt extends lt {
2228
2234
  setColor(t, n) {
2229
2235
  if (n < 0 || n >= this.paletteState.length)
2230
2236
  throw new Error(`Index ${n} out of range`);
2231
- this.paletteState[n] = t, O(this.glContext, this.paletteTexture, this.paletteState), this.metricPaletteDirty = !0, this.schedulePaint();
2237
+ this.paletteState[n] = t, S(this.glContext, this.paletteTexture, this.paletteState), this.metricPaletteDirty = !0, this.schedulePaint();
2232
2238
  }
2233
2239
  addColor(t, n) {
2234
- this.paletteState.splice(n ?? this.paletteState.length, 0, t), O(this.glContext, this.paletteTexture, this.paletteState), this.metricPaletteDirty = !0, this.schedulePaint();
2240
+ this.paletteState.splice(n ?? this.paletteState.length, 0, t), S(this.glContext, this.paletteTexture, this.paletteState), this.metricPaletteDirty = !0, this.schedulePaint();
2235
2241
  }
2236
2242
  removeColor(t) {
2237
2243
  const n = typeof t == "number" ? t : this.paletteState.findIndex(
@@ -2241,13 +2247,13 @@ class Xt extends lt {
2241
2247
  if (n < 0 || n >= this.paletteState.length)
2242
2248
  throw new Error(`Index ${n} out of range`);
2243
2249
  if (this.paletteState.length === 1) throw new Error("Palette must contain at least one color");
2244
- this.paletteState.splice(n, 1), O(this.glContext, this.paletteTexture, this.paletteState), this.metricPaletteDirty = !0, this.schedulePaint();
2250
+ this.paletteState.splice(n, 1), S(this.glContext, this.paletteTexture, this.paletteState), this.metricPaletteDirty = !0, this.schedulePaint();
2245
2251
  }
2246
2252
  getColorAtUV(t, n) {
2247
2253
  if (!Number.isFinite(t) || !Number.isFinite(n))
2248
2254
  throw new Error("x and y must be finite numbers");
2249
2255
  if (t < 0 || t > 1 || n < 0 || n > 1) throw new Error("x and y must be in the range [0, 1]");
2250
- this.flushScheduledPaint(), this.renderFrame();
2256
+ this.animationFrameId !== null && (this.flushScheduledPaint(), this.renderFrame());
2251
2257
  const e = this.glContext, a = Math.min(
2252
2258
  this.canvas.width - 1,
2253
2259
  Math.max(0, Math.round(t * (this.canvas.width - 1)))
@@ -2255,7 +2261,7 @@ class Xt extends lt {
2255
2261
  this.canvas.height - 1,
2256
2262
  Math.max(0, Math.round(n * (this.canvas.height - 1)))
2257
2263
  );
2258
- e.bindFramebuffer(e.FRAMEBUFFER, this.#e);
2264
+ e.bindFramebuffer(e.FRAMEBUFFER, this.#e), e.flush();
2259
2265
  const s = new Uint8Array(4);
2260
2266
  return e.readPixels(a, o, 1, 1, e.RGBA, e.UNSIGNED_BYTE, s), e.bindFramebuffer(e.FRAMEBUFFER, null), [s[0] / 255, s[1] / 255, s[2] / 255];
2261
2267
  }
@@ -2265,27 +2271,27 @@ class Xt extends lt {
2265
2271
  if (t < 0 || t > 1 || n < 0 || n > 1) throw new Error("x and y must be in the range [0, 1]");
2266
2272
  this.flushScheduledPaint();
2267
2273
  const e = this.glContext;
2268
- if (this.#m || (this.#p = e.createTexture(), e.bindTexture(e.TEXTURE_2D, this.#p), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA16F, 1, 1, 0, e.RGBA, e.HALF_FLOAT, null), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.bindTexture(e.TEXTURE_2D, null), this.#m = e.createFramebuffer(), e.bindFramebuffer(e.FRAMEBUFFER, this.#m), e.framebufferTexture2D(
2274
+ if (this.#m || (e.getExtension("EXT_color_buffer_float"), this.#p = e.createTexture(), e.bindTexture(e.TEXTURE_2D, this.#p), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA16F, 1, 1, 0, e.RGBA, e.HALF_FLOAT, null), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.bindTexture(e.TEXTURE_2D, null), this.#m = e.createFramebuffer(), e.bindFramebuffer(e.FRAMEBUFFER, this.#m), e.framebufferTexture2D(
2269
2275
  e.FRAMEBUFFER,
2270
2276
  e.COLOR_ATTACHMENT0,
2271
2277
  e.TEXTURE_2D,
2272
2278
  this.#p,
2273
2279
  0
2274
- ), e.bindFramebuffer(e.FRAMEBUFFER, null)), this.#P) {
2280
+ ), e.bindFramebuffer(e.FRAMEBUFFER, null)), this.#r && (this.#A = !0), this.#A) {
2275
2281
  this.#h && e.deleteProgram(this.#h);
2276
2282
  const s = { ...this.#k(), OUTPUT_LINEAR: 1 }, i = V(
2277
- x[this.#o],
2278
- E[this.#c],
2283
+ E[this.#o],
2284
+ x[this.#c],
2279
2285
  this.#_,
2280
2286
  !0
2281
2287
  );
2282
- this.#h = y(e, s, i, S), this.#I = e.getUniformLocation(this.#h, "progress"), this.#D = e.getUniformLocation(this.#h, "paletteTexture"), this.#O = e.getUniformLocation(
2288
+ this.#h = y(e, s, i, O), this.#I = e.getUniformLocation(this.#h, "progress"), this.#D = e.getUniformLocation(this.#h, "paletteTexture"), this.#O = e.getUniformLocation(
2283
2289
  this.#h,
2284
2290
  "paletteMetricTexture"
2285
- ), this.#S = e.getUniformLocation(this.#h, "uPaletteSize"), this.#w = e.getUniformLocation(this.#h, "uvOverride"), this.#P = !1;
2291
+ ), this.#P = e.getUniformLocation(this.#h, "uPaletteSize"), this.#w = e.getUniformLocation(this.#h, "uvOverride"), this.#A = !1;
2286
2292
  }
2287
2293
  const a = e.getParameter(e.VIEWPORT);
2288
- e.bindFramebuffer(e.FRAMEBUFFER, this.#m), e.viewport(0, 0, 1, 1), e.useProgram(this.#h), e.uniform2f(this.#w, t, n), e.uniform1f(this.#I, this.#d), this.uploadMetricPalette(this.#S), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.paletteTexture), e.uniform1i(this.#D, 0), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.metricTexture), e.uniform1i(this.#O, 1), e.clearColor(0, 0, 0, 0), e.clear(e.COLOR_BUFFER_BIT), e.bindVertexArray(this.#a), e.drawArrays(e.TRIANGLE_STRIP, 0, 4), e.flush();
2294
+ e.bindFramebuffer(e.FRAMEBUFFER, this.#m), e.viewport(0, 0, 1, 1), e.useProgram(this.#h), e.uniform2f(this.#w, t, n), e.uniform1f(this.#I, this.#d), e.uniform1i(this.#P, this.paletteState.length), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.paletteTexture), e.uniform1i(this.#D, 0), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.metricTexture), e.uniform1i(this.#O, 1), e.clearColor(0, 0, 0, 0), e.clear(e.COLOR_BUFFER_BIT), e.bindVertexArray(this.#a), e.drawArrays(e.TRIANGLE_STRIP, 0, 4), e.flush();
2289
2295
  const o = new Float32Array(4);
2290
2296
  return e.readPixels(0, 0, 1, 1, e.RGBA, e.FLOAT, o), e.bindFramebuffer(e.FRAMEBUFFER, null), e.bindVertexArray(null), e.viewport(a[0], a[1], a[2], a[3]), [o[0], o[1], o[2]];
2291
2297
  }
@@ -2304,14 +2310,14 @@ class Xt extends lt {
2304
2310
  return this.#i;
2305
2311
  }
2306
2312
  set colorModel(t) {
2307
- if (!(t in x)) throw new Error(`colorModel '${t}' is not supported`);
2313
+ if (!(t in E)) throw new Error(`colorModel '${t}' is not supported`);
2308
2314
  this.#o = t, this.#r = !0, this.schedulePaint();
2309
2315
  }
2310
2316
  get colorModel() {
2311
2317
  return this.#o;
2312
2318
  }
2313
2319
  set distanceMetric(t) {
2314
- if (!(t in E))
2320
+ if (!(t in x))
2315
2321
  throw new Error(`distanceMetric '${t}' is not supported`);
2316
2322
  this.#c = t, this.#r = !0, this.schedulePaint();
2317
2323
  }
@@ -2346,7 +2352,7 @@ class Xt extends lt {
2346
2352
  /** @deprecated use PaletteViz.paletteToRGBA */
2347
2353
  static paletteToTexture = D;
2348
2354
  }
2349
- function Ot(r) {
2355
+ function St(r) {
2350
2356
  const t = [], n = [], e = r, a = [
2351
2357
  // axisIndex, sign, uAxis, vAxis, uSign, vSign
2352
2358
  // +X face
@@ -2377,7 +2383,7 @@ function Ot(r) {
2377
2383
  }
2378
2384
  return { vertices: new Float32Array(t), indices: new Uint32Array(n) };
2379
2385
  }
2380
- function St(r, t, n = 0) {
2386
+ function Ot(r, t, n = 0) {
2381
2387
  const e = [], a = [], o = r, s = -n, l = 1 + n - s;
2382
2388
  for (let _ = t; _ >= 0; _--) {
2383
2389
  const b = s + l * _ / t, C = e.length / 3;
@@ -2546,22 +2552,22 @@ class Ht extends lt {
2546
2552
  #s = 0;
2547
2553
  #g = 0;
2548
2554
  #C = null;
2549
- #M = null;
2550
2555
  #y = null;
2556
+ #S = null;
2551
2557
  #m = null;
2552
2558
  #p = null;
2553
2559
  #h = null;
2554
2560
  #I = null;
2555
2561
  #D = null;
2556
2562
  #O = null;
2557
- #S = null;
2558
- #w = null;
2559
2563
  #P = null;
2564
+ #w = null;
2565
+ #A = null;
2560
2566
  #k = new Float32Array(9);
2561
- #x = null;
2562
2567
  #E = null;
2568
+ #x = null;
2563
2569
  #L = null;
2564
- #A = null;
2570
+ #M = null;
2565
2571
  #F = null;
2566
2572
  #B = null;
2567
2573
  #X = null;
@@ -2591,7 +2597,7 @@ class Ht extends lt {
2591
2597
  observeResize: o,
2592
2598
  container: s,
2593
2599
  canvasClassName: "palette-viz-3d"
2594
- }), this.#o = i, this.#c = l, this.#f = this.normalizeInvertAxes(_), this.#_ = b, this.#v = C, this.#n = f, this.#d = h, this.#e = W.has(x[this.#o]), d ? this.#i = new Float32Array(d) : this.#i = new Float32Array(p(M(0.45), A(0.65))), this.#W(), this.#j(), this.syncCanvasSize(this.width, this.height), this.#N(), this.glContext.enable(this.glContext.DEPTH_TEST), this.#Q(), this.attachCanvas(), this.schedulePaint();
2600
+ }), this.#o = i, this.#c = l, this.#f = this.normalizeInvertAxes(_), this.#_ = b, this.#v = C, this.#n = f, this.#d = h, this.#e = W.has(E[this.#o]), d ? this.#i = new Float32Array(d) : this.#i = new Float32Array(p(M(0.45), A(0.65))), this.#W(), this.#j(), this.syncCanvasSize(this.width, this.height), this.#N(), this.glContext.enable(this.glContext.DEPTH_TEST), this.#Q(), this.attachCanvas(), this.schedulePaint();
2595
2601
  }
2596
2602
  #W() {
2597
2603
  const t = this.glContext;
@@ -2602,7 +2608,7 @@ class Ht extends lt {
2602
2608
  return;
2603
2609
  }
2604
2610
  this.#s = this.#n ? this.#U() : 0;
2605
- const { vertices: n, indices: e } = this.#n ? St(2, this.#s, Y) : Ot(64);
2611
+ const { vertices: n, indices: e } = this.#n ? Ot(2, this.#s, Y) : St(64);
2606
2612
  this.#T = e.length, this.#r = t.createBuffer(), t.bindBuffer(t.ARRAY_BUFFER, this.#r), t.bufferData(t.ARRAY_BUFFER, n, t.STATIC_DRAW), this.#u = t.createBuffer(), t.bindBuffer(t.ELEMENT_ARRAY_BUFFER, this.#u), t.bufferData(t.ELEMENT_ARRAY_BUFFER, e, t.STATIC_DRAW), this.#a = t.createVertexArray(), t.bindVertexArray(this.#a), t.bindBuffer(t.ARRAY_BUFFER, this.#r), t.enableVertexAttribArray(0), t.vertexAttribPointer(0, 3, t.FLOAT, !1, 0, 0), t.bindBuffer(t.ELEMENT_ARRAY_BUFFER, this.#u), t.bindVertexArray(null);
2607
2613
  }
2608
2614
  #U() {
@@ -2641,10 +2647,10 @@ class Ht extends lt {
2641
2647
  s.bindVertexArray(null);
2642
2648
  }
2643
2649
  #J() {
2644
- const t = x[this.#o];
2650
+ const t = E[this.#o];
2645
2651
  return {
2646
2652
  COLOR_MODEL: t,
2647
- DISTANCE_METRIC: E[this.#c],
2653
+ DISTANCE_METRIC: x[this.#c],
2648
2654
  INVERT_X: this.#f.includes("x") ? 1 : !1,
2649
2655
  INVERT_Y: this.#f.includes("y") ? 1 : !1,
2650
2656
  INVERT_Z: this.#f.includes("z") ? 1 : !1,
@@ -2660,14 +2666,14 @@ class Ht extends lt {
2660
2666
  const t = this.glContext;
2661
2667
  this.#t && t.deleteProgram(this.#t), this.#l && t.deleteProgram(this.#l);
2662
2668
  const n = Lt(
2663
- x[this.#o],
2664
- E[this.#c],
2669
+ E[this.#o],
2670
+ x[this.#c],
2665
2671
  this.#_
2666
2672
  ), e = At(
2667
- x[this.#o],
2673
+ E[this.#o],
2668
2674
  this.#n
2669
- ), a = this.#e ? Et : xt;
2670
- this.#t = y(t, this.#J(), n, a), this.#l = y(t, this.#J(), e, a), this.#M = t.getUniformLocation(this.#t, "uMVP"), this.#y = t.getUniformLocation(this.#l, "uMVP"), this.#m = t.getUniformLocation(this.#t, "uPosition"), this.#p = t.getUniformLocation(this.#l, "uPosition"), this.#h = t.getUniformLocation(this.#t, "paletteTexture"), this.#I = t.getUniformLocation(this.#t, "paletteMetricTexture"), this.#D = t.getUniformLocation(this.#t, "uPaletteSize"), this.#O = t.getUniformLocation(this.#t, "uColorRotation"), this.#S = t.getUniformLocation(this.#l, "uColorRotation"), this.#w = t.getUniformLocation(this.#t, "uSliceOffset"), this.#P = t.getUniformLocation(this.#l, "uSliceOffset"), this.metricPaletteDirty = !0;
2675
+ ), a = this.#e ? xt : Et;
2676
+ this.#t = y(t, this.#J(), n, a), this.#l = y(t, this.#J(), e, a), this.#y = t.getUniformLocation(this.#t, "uMVP"), this.#S = t.getUniformLocation(this.#l, "uMVP"), this.#m = t.getUniformLocation(this.#t, "uPosition"), this.#p = t.getUniformLocation(this.#l, "uPosition"), this.#h = t.getUniformLocation(this.#t, "paletteTexture"), this.#I = t.getUniformLocation(this.#t, "paletteMetricTexture"), this.#D = t.getUniformLocation(this.#t, "uPaletteSize"), this.#O = t.getUniformLocation(this.#t, "uColorRotation"), this.#P = t.getUniformLocation(this.#l, "uColorRotation"), this.#w = t.getUniformLocation(this.#t, "uSliceOffset"), this.#A = t.getUniformLocation(this.#l, "uSliceOffset"), this.metricPaletteDirty = !0;
2671
2677
  }
2672
2678
  #G(t, n, e, a) {
2673
2679
  const o = this.glContext;
@@ -2678,15 +2684,15 @@ class Ht extends lt {
2678
2684
  }
2679
2685
  #Q() {
2680
2686
  const t = this.glContext;
2681
- this.#E = t.createTexture(), this.#L = t.createRenderbuffer(), this.#x = t.createFramebuffer(), this.#K(this.canvas.width, this.canvas.height), this.#B = t.createBuffer(), t.bindBuffer(t.ARRAY_BUFFER, this.#B), t.bufferData(t.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), t.STATIC_DRAW), this.#F = t.createVertexArray(), t.bindVertexArray(this.#F), t.enableVertexAttribArray(0), t.vertexAttribPointer(0, 2, t.FLOAT, !1, 0, 0), t.bindVertexArray(null), this.#A = y(t, {}, it, S), this.#X = t.getUniformLocation(this.#A, "colorMap"), this.#H = t.getUniformLocation(this.#A, "outlineWidth"), this.#V = t.getUniformLocation(this.#A, "resolution");
2687
+ this.#x = t.createTexture(), this.#L = t.createRenderbuffer(), this.#E = t.createFramebuffer(), this.#K(this.canvas.width, this.canvas.height), this.#B = t.createBuffer(), t.bindBuffer(t.ARRAY_BUFFER, this.#B), t.bufferData(t.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), t.STATIC_DRAW), this.#F = t.createVertexArray(), t.bindVertexArray(this.#F), t.enableVertexAttribArray(0), t.vertexAttribPointer(0, 2, t.FLOAT, !1, 0, 0), t.bindVertexArray(null), this.#M = y(t, {}, it, O), this.#X = t.getUniformLocation(this.#M, "colorMap"), this.#H = t.getUniformLocation(this.#M, "outlineWidth"), this.#V = t.getUniformLocation(this.#M, "resolution");
2682
2688
  }
2683
2689
  #K(t, n) {
2684
2690
  const e = this.glContext;
2685
- e.bindTexture(e.TEXTURE_2D, this.#E), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA8, t, n, 0, e.RGBA, e.UNSIGNED_BYTE, null), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.bindTexture(e.TEXTURE_2D, null), e.bindRenderbuffer(e.RENDERBUFFER, this.#L), e.renderbufferStorage(e.RENDERBUFFER, e.DEPTH_COMPONENT16, t, n), e.bindRenderbuffer(e.RENDERBUFFER, null), e.bindFramebuffer(e.FRAMEBUFFER, this.#x), e.framebufferTexture2D(
2691
+ e.bindTexture(e.TEXTURE_2D, this.#x), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA8, t, n, 0, e.RGBA, e.UNSIGNED_BYTE, null), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.NEAREST), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.bindTexture(e.TEXTURE_2D, null), e.bindRenderbuffer(e.RENDERBUFFER, this.#L), e.renderbufferStorage(e.RENDERBUFFER, e.DEPTH_COMPONENT16, t, n), e.bindRenderbuffer(e.RENDERBUFFER, null), e.bindFramebuffer(e.FRAMEBUFFER, this.#E), e.framebufferTexture2D(
2686
2692
  e.FRAMEBUFFER,
2687
2693
  e.COLOR_ATTACHMENT0,
2688
2694
  e.TEXTURE_2D,
2689
- this.#E,
2695
+ this.#x,
2690
2696
  0
2691
2697
  ), e.framebufferRenderbuffer(
2692
2698
  e.FRAMEBUFFER,
@@ -2705,38 +2711,38 @@ class Ht extends lt {
2705
2711
  return p(n, p(e, this.#i));
2706
2712
  }
2707
2713
  currentMetricCode() {
2708
- return E[this.#c];
2714
+ return x[this.#c];
2709
2715
  }
2710
2716
  onSurfaceResized(t, n) {
2711
- this.#N(), this.#E && this.#K(t, n);
2717
+ this.#N(), this.#x && this.#K(t, n);
2712
2718
  }
2713
2719
  renderFrame() {
2714
- this.#N(), this.#R && (this.#e = W.has(x[this.#o]), this.#W(), this.#R = !1), this.#b && (this.#j(), this.#b = !1);
2720
+ this.#N(), this.#R && (this.#e = W.has(E[this.#o]), this.#W(), this.#R = !1), this.#b && (this.#j(), this.#b = !1);
2715
2721
  const t = this.glContext;
2716
- t.bindFramebuffer(t.FRAMEBUFFER, this.#x), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT | t.DEPTH_BUFFER_BIT), (this.#n || this.#e) && (t.colorMask(!1, !1, !1, !1), this.#n ? this.#Y(
2722
+ t.bindFramebuffer(t.FRAMEBUFFER, this.#E), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT | t.DEPTH_BUFFER_BIT), (this.#n || this.#e) && (t.colorMask(!1, !1, !1, !1), this.#n ? this.#Y(
2717
2723
  this.#l,
2718
- this.#y,
2719
- this.#p,
2720
2724
  this.#S,
2721
- this.#P
2725
+ this.#p,
2726
+ this.#P,
2727
+ this.#A
2722
2728
  ) : (this.#G(
2723
2729
  this.#l,
2724
- this.#y,
2730
+ this.#S,
2725
2731
  this.#p,
2726
- this.#S
2727
- ), t.bindVertexArray(this.#a), t.drawElements(t.TRIANGLES, this.#T, t.UNSIGNED_INT, 0), t.bindVertexArray(null)), t.colorMask(!0, !0, !0, !0), t.clear(t.COLOR_BUFFER_BIT), t.depthFunc(t.EQUAL), t.depthMask(!1)), this.#n ? t.useProgram(this.#t) : this.#G(this.#t, this.#M, this.#m, this.#O), this.uploadMetricPalette(this.#D), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.paletteTexture), t.uniform1i(this.#h, 0), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, this.metricTexture), t.uniform1i(this.#I, 1), this.#n ? this.#Y(
2732
+ this.#P
2733
+ ), t.bindVertexArray(this.#a), t.drawElements(t.TRIANGLES, this.#T, t.UNSIGNED_INT, 0), t.bindVertexArray(null)), t.colorMask(!0, !0, !0, !0), t.clear(t.COLOR_BUFFER_BIT), t.depthFunc(t.EQUAL), t.depthMask(!1)), this.#n ? t.useProgram(this.#t) : this.#G(this.#t, this.#y, this.#m, this.#O), this.uploadMetricPalette(this.#D), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.paletteTexture), t.uniform1i(this.#h, 0), t.activeTexture(t.TEXTURE1), t.bindTexture(t.TEXTURE_2D, this.metricTexture), t.uniform1i(this.#I, 1), this.#n ? this.#Y(
2728
2734
  this.#t,
2729
- this.#M,
2735
+ this.#y,
2730
2736
  this.#m,
2731
2737
  this.#O,
2732
2738
  this.#w
2733
- ) : (t.bindVertexArray(this.#a), t.drawElements(t.TRIANGLES, this.#T, t.UNSIGNED_INT, 0), t.bindVertexArray(null)), (this.#n || this.#e) && (t.depthMask(!0), t.depthFunc(t.LESS)), t.bindFramebuffer(t.FRAMEBUFFER, null), t.disable(t.DEPTH_TEST), t.useProgram(this.#A), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.#E), t.uniform1i(this.#X, 0), t.uniform1f(this.#H, this.#_ ? 0 : this.#v), t.uniform2f(this.#V, this.canvas.width, this.canvas.height), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.bindVertexArray(this.#F), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindVertexArray(null), t.enable(t.DEPTH_TEST);
2739
+ ) : (t.bindVertexArray(this.#a), t.drawElements(t.TRIANGLES, this.#T, t.UNSIGNED_INT, 0), t.bindVertexArray(null)), (this.#n || this.#e) && (t.depthMask(!0), t.depthFunc(t.LESS)), t.bindFramebuffer(t.FRAMEBUFFER, null), t.disable(t.DEPTH_TEST), t.useProgram(this.#M), t.activeTexture(t.TEXTURE0), t.bindTexture(t.TEXTURE_2D, this.#x), t.uniform1i(this.#X, 0), t.uniform1f(this.#H, this.#_ ? 0 : this.#v), t.uniform2f(this.#V, this.canvas.width, this.canvas.height), t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), t.bindVertexArray(this.#F), t.drawArrays(t.TRIANGLE_STRIP, 0, 4), t.bindVertexArray(null), t.enable(t.DEPTH_TEST);
2734
2740
  }
2735
2741
  getColorAtUV(t, n) {
2736
2742
  if (!Number.isFinite(t) || !Number.isFinite(n))
2737
2743
  throw new Error("x and y must be finite numbers");
2738
2744
  if (t < 0 || t > 1 || n < 0 || n > 1) throw new Error("x and y must be in the range [0, 1]");
2739
- this.flushScheduledPaint(), this.renderFrame();
2745
+ this.animationFrameId !== null && (this.flushScheduledPaint(), this.renderFrame());
2740
2746
  const e = this.glContext, a = Math.min(
2741
2747
  this.canvas.width - 1,
2742
2748
  Math.max(0, Math.round(t * (this.canvas.width - 1)))
@@ -2744,7 +2750,7 @@ class Ht extends lt {
2744
2750
  this.canvas.height - 1,
2745
2751
  Math.max(0, Math.round((1 - n) * (this.canvas.height - 1)))
2746
2752
  );
2747
- e.bindFramebuffer(e.FRAMEBUFFER, this.#x);
2753
+ e.bindFramebuffer(e.FRAMEBUFFER, this.#E);
2748
2754
  const s = new Uint8Array(4);
2749
2755
  return e.readPixels(a, o, 1, 1, e.RGBA, e.UNSIGNED_BYTE, s), e.bindFramebuffer(e.FRAMEBUFFER, null), s[3] === 0 ? null : [s[0] / 255, s[1] / 255, s[2] / 255];
2750
2756
  }
@@ -2755,17 +2761,17 @@ class Ht extends lt {
2755
2761
  if (!this.beginDestroy()) return;
2756
2762
  this.#C !== null && (window.clearTimeout(this.#C), this.#C = null);
2757
2763
  const t = this.glContext;
2758
- this.#A && t.deleteProgram(this.#A), this.#l && t.deleteProgram(this.#l), this.#F && t.deleteVertexArray(this.#F), this.#B && t.deleteBuffer(this.#B), this.#E && t.deleteTexture(this.#E), this.#L && t.deleteRenderbuffer(this.#L), this.#x && t.deleteFramebuffer(this.#x), this.#t && t.deleteProgram(this.#t), this.#r && t.deleteBuffer(this.#r), this.#u && t.deleteBuffer(this.#u), this.#a && t.deleteVertexArray(this.#a), this.destroyBaseResources();
2764
+ this.#M && t.deleteProgram(this.#M), this.#l && t.deleteProgram(this.#l), this.#F && t.deleteVertexArray(this.#F), this.#B && t.deleteBuffer(this.#B), this.#x && t.deleteTexture(this.#x), this.#L && t.deleteRenderbuffer(this.#L), this.#E && t.deleteFramebuffer(this.#E), this.#t && t.deleteProgram(this.#t), this.#r && t.deleteBuffer(this.#r), this.#u && t.deleteBuffer(this.#u), this.#a && t.deleteVertexArray(this.#a), this.destroyBaseResources();
2759
2765
  }
2760
2766
  set colorModel(t) {
2761
- if (!(t in x)) throw new Error(`colorModel '${t}' is not supported`);
2767
+ if (!(t in E)) throw new Error(`colorModel '${t}' is not supported`);
2762
2768
  this.#o = t, this.#b = !0, this.#R = !0, this.schedulePaint();
2763
2769
  }
2764
2770
  get colorModel() {
2765
2771
  return this.#o;
2766
2772
  }
2767
2773
  set distanceMetric(t) {
2768
- if (!(t in E))
2774
+ if (!(t in x))
2769
2775
  throw new Error(`distanceMetric '${t}' is not supported`);
2770
2776
  this.#c = t, this.#b = !0, this.schedulePaint();
2771
2777
  }