@lovo/matter 0.4.1 → 0.6.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/dist/index.cjs CHANGED
@@ -15,7 +15,7 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
19
19
 
20
20
  // src/index.ts
21
21
  var index_exports = {};
@@ -29,29 +29,68 @@ __export(index_exports, {
29
29
  createVisibilityWatcher: () => createVisibilityWatcher,
30
30
  cursorRipple: () => cursorRipple,
31
31
  displace: () => displace,
32
- fbm: () => fbm,
32
+ dither: () => dither,
33
+ elapsedTime: () => elapsedTime,
33
34
  filmGrain: () => filmGrain,
35
+ fractalNoise: () => fractalNoise,
34
36
  getReducedMotionPolicy: () => getReducedMotionPolicy,
35
37
  getReducedMotionTimeScale: () => getReducedMotionTimeScale,
36
- noise: () => noise,
38
+ mixColor: () => mixColor,
39
+ oklabToLinearSrgb: () => oklabToLinearSrgb,
40
+ oklchToLinearSrgb: () => oklchToLinearSrgb,
41
+ parseColorString: () => parseColorString,
37
42
  quantize: () => quantize,
38
- sdfCircle: () => sdfCircle,
39
43
  setReducedMotionPolicy: () => setReducedMotionPolicy,
40
- time: () => time,
44
+ signedDistanceFieldCircle: () => signedDistanceFieldCircle,
45
+ simplexNoise: () => simplexNoise,
46
+ srgbChannelToLinear: () => srgbChannelToLinear,
41
47
  voronoi: () => voronoi
42
48
  });
43
49
  module.exports = __toCommonJS(index_exports);
44
50
 
45
51
  // src/runtime/create-renderer/create-renderer.ts
46
- var import_three = require("three");
52
+ var import_three2 = require("three");
47
53
  var import_webgpu = require("three/webgpu");
54
+
55
+ // src/runtime/create-renderer/gamut.ts
56
+ var import_three = require("three");
57
+ var import_ColorSpaces = require("three/examples/jsm/math/ColorSpaces.js");
58
+ import_three.ColorManagement.define({
59
+ [import_ColorSpaces.DisplayP3ColorSpace]: import_ColorSpaces.DisplayP3ColorSpaceImpl,
60
+ [import_ColorSpaces.LinearDisplayP3ColorSpace]: import_ColorSpaces.LinearDisplayP3ColorSpaceImpl
61
+ });
62
+ function gamutToColorSpace(gamut) {
63
+ return gamut === "p3" ? import_ColorSpaces.DisplayP3ColorSpace : import_three.SRGBColorSpace;
64
+ }
65
+ function hasWebGpuBackendInternals(backend) {
66
+ if (typeof backend !== "object" || backend === null) return false;
67
+ if (!("device" in backend) || !("context" in backend)) return false;
68
+ const { device, context } = backend;
69
+ return typeof device === "object" && device !== null && typeof context === "object" && context !== null && "configure" in context && typeof context.configure === "function";
70
+ }
71
+ function applyCanvasGamut(renderer, backend, gamut) {
72
+ if (gamut !== "p3" || backend !== "webgpu") return;
73
+ if (typeof navigator === "undefined" || !("gpu" in navigator)) return;
74
+ const webGpuBackend = renderer.backend;
75
+ if (!hasWebGpuBackendInternals(webGpuBackend)) return;
76
+ webGpuBackend.context.configure({
77
+ device: webGpuBackend.device,
78
+ format: navigator.gpu.getPreferredCanvasFormat(),
79
+ usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC,
80
+ alphaMode: "premultiplied",
81
+ colorSpace: "display-p3"
82
+ });
83
+ }
84
+
85
+ // src/runtime/create-renderer/create-renderer.ts
48
86
  async function createRenderer(canvas, opts = {}) {
49
87
  const {
50
88
  antialias = true,
51
89
  forceWebGL = false,
52
90
  clearColor = 0,
53
91
  clearAlpha = 0,
54
- maxDPR = 2
92
+ maxDPR = 2,
93
+ gamut = "srgb"
55
94
  } = opts;
56
95
  const three = new import_webgpu.WebGPURenderer({
57
96
  canvas,
@@ -59,19 +98,24 @@ async function createRenderer(canvas, opts = {}) {
59
98
  forceWebGL
60
99
  });
61
100
  await three.init();
101
+ three.outputColorSpace = gamutToColorSpace(gamut);
62
102
  three.setPixelRatio(Math.min(window.devicePixelRatio, maxDPR));
63
- const resolvedClearColor = clearColor instanceof import_three.Color ? clearColor : new import_three.Color(clearColor);
103
+ const resolvedClearColor = clearColor instanceof import_three2.Color ? clearColor : new import_three2.Color(clearColor);
64
104
  three.setClearColor(resolvedClearColor, clearAlpha);
105
+ const rendererSize = new import_three2.Vector2();
65
106
  const resize = () => {
66
- const w = canvas.clientWidth;
67
- const h = canvas.clientHeight;
68
- if (canvas.width !== w * three.getPixelRatio() || canvas.height !== h * three.getPixelRatio()) {
69
- three.setSize(w, h, false);
107
+ const canvasWidth = canvas.clientWidth;
108
+ const canvasHeight = canvas.clientHeight;
109
+ if (canvasWidth === 0 || canvasHeight === 0) return;
110
+ three.getSize(rendererSize);
111
+ if (rendererSize.width !== canvasWidth || rendererSize.height !== canvasHeight) {
112
+ three.setSize(canvasWidth, canvasHeight, false);
70
113
  }
71
114
  };
72
115
  resize();
73
116
  const isWebGL = "isWebGLBackend" in three.backend && three.backend.isWebGLBackend === true;
74
117
  const backend = forceWebGL || isWebGL ? "webgl2" : "webgpu";
118
+ applyCanvasGamut(three, backend, gamut);
75
119
  return {
76
120
  three,
77
121
  backend,
@@ -100,16 +144,19 @@ var CursorInput = class {
100
144
  this.element = element;
101
145
  this.handleMouseMove = (e) => {
102
146
  if (!(e instanceof MouseEvent)) return;
103
- const me = e;
147
+ const mouseEvent = e;
104
148
  if (this.element) {
105
- const r = this.element.getBoundingClientRect();
106
- const w = r.width || 1;
107
- const h = r.height || 1;
108
- this.target = [(me.clientX - r.left) / w, (me.clientY - r.top) / h];
149
+ const elementRect = this.element.getBoundingClientRect();
150
+ const elementWidth = elementRect.width || 1;
151
+ const elementHeight = elementRect.height || 1;
152
+ this.target = [
153
+ (mouseEvent.clientX - elementRect.left) / elementWidth,
154
+ (mouseEvent.clientY - elementRect.top) / elementHeight
155
+ ];
109
156
  } else {
110
- const w = typeof window !== "undefined" && window.innerWidth || 1;
111
- const h = typeof window !== "undefined" && window.innerHeight || 1;
112
- this.target = [me.clientX / w, me.clientY / h];
157
+ const viewportWidth = typeof window !== "undefined" && window.innerWidth || 1;
158
+ const viewportHeight = typeof window !== "undefined" && window.innerHeight || 1;
159
+ this.target = [mouseEvent.clientX / viewportWidth, mouseEvent.clientY / viewportHeight];
113
160
  }
114
161
  this.targetDirty = true;
115
162
  };
@@ -120,9 +167,9 @@ var CursorInput = class {
120
167
  return this.value;
121
168
  }
122
169
  /** Subscribe to change events. Returns an unsubscribe function. */
123
- on(_event, cb) {
124
- this.listeners.add(cb);
125
- return () => this.listeners.delete(cb);
170
+ on(_eventType, changeListener) {
171
+ this.listeners.add(changeListener);
172
+ return () => this.listeners.delete(changeListener);
126
173
  }
127
174
  /**
128
175
  * Advance the smoothing one tick. Called by the host scheduler; not
@@ -151,60 +198,396 @@ var CursorInput = class {
151
198
  this.listeners.clear();
152
199
  }
153
200
  };
154
- var clamp01 = (n) => Math.max(0, Math.min(1, n));
155
- var lerp = (a, b, t) => a + (b - a) * t;
201
+ var clamp01 = (value) => Math.max(0, Math.min(1, value));
202
+ var lerp = (startValue, endValue, blendFactor) => startValue + (endValue - startValue) * blendFactor;
156
203
 
157
204
  // src/primitives/color-ramp/color-ramp.ts
205
+ var import_tsl9 = require("three/tsl");
206
+
207
+ // src/primitives/color-space/hue.ts
158
208
  var import_tsl = require("three/tsl");
209
+ var EQUAL_HUE_EPSILON = 1e-6;
210
+ var shortestArcHue = (h1, h2, t, period) => {
211
+ const half = period / 2;
212
+ const delta = (0, import_tsl.mod)(h2.sub(h1).add(half), period).sub(half);
213
+ return h1.add(delta.mul(t));
214
+ };
215
+ var longestArcHue = (h1, h2, t, period) => {
216
+ const half = period / 2;
217
+ const short = (0, import_tsl.mod)(h2.sub(h1).add(half), period).sub(half);
218
+ const delta = short.sub((0, import_tsl.sign)(short).mul(period));
219
+ return h1.add(delta.mul(t));
220
+ };
221
+ var increasingArcHue = (h1, h2, t, period) => {
222
+ const delta = (0, import_tsl.mod)(h2.sub(h1), period);
223
+ return h1.add(delta.mul(t));
224
+ };
225
+ var decreasingArcHue = (h1, h2, t, period) => {
226
+ const up = (0, import_tsl.mod)(h2.sub(h1), period);
227
+ const delta = up.sub((0, import_tsl.step)(EQUAL_HUE_EPSILON, up).mul(period));
228
+ return h1.add(delta.mul(t));
229
+ };
230
+ var hueArcInterpolators = {
231
+ shorter: shortestArcHue,
232
+ longer: longestArcHue,
233
+ increasing: increasingArcHue,
234
+ decreasing: decreasingArcHue
235
+ };
236
+
237
+ // src/primitives/color-space/hsl.ts
238
+ var import_tsl3 = require("three/tsl");
239
+
240
+ // src/primitives/color-space/transfer.ts
159
241
  var import_tsl2 = require("three/tsl");
160
- function colorRamp(t, stops) {
242
+ function srgbChannelToLinear(channel) {
243
+ return channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
244
+ }
245
+ function srgbToLinear(srgb) {
246
+ const value = (0, import_tsl2.pow)(srgb, 1);
247
+ const lowSegment = value.div(12.92);
248
+ const highSegment = (0, import_tsl2.pow)(value.add(0.055).div(1.055), 2.4);
249
+ return (0, import_tsl2.mix)(lowSegment, highSegment, (0, import_tsl2.step)(0.04045, value));
250
+ }
251
+ function linearToSrgb(linear) {
252
+ const value = (0, import_tsl2.pow)(linear, 1);
253
+ const lowSegment = value.mul(12.92);
254
+ const highSegment = (0, import_tsl2.pow)(value, 1 / 2.4).mul(1.055).sub(0.055);
255
+ return (0, import_tsl2.mix)(lowSegment, highSegment, (0, import_tsl2.step)(31308e-7, value));
256
+ }
257
+
258
+ // src/primitives/color-space/hsl.ts
259
+ var EPSILON = 1e-10;
260
+ function gammaRgbHue(c) {
261
+ const p = (0, import_tsl3.mix)((0, import_tsl3.vec4)(c.b, c.g, -1 / 3, 2 / 3), (0, import_tsl3.vec4)(c.g, c.b, 0, -1 / 3), (0, import_tsl3.step)(c.b, c.g));
262
+ const q = (0, import_tsl3.mix)((0, import_tsl3.vec4)(p.x, p.y, p.w, c.r), (0, import_tsl3.vec4)(c.r, p.y, p.z, p.x), (0, import_tsl3.step)(p.x, c.r));
263
+ const chroma = q.x.sub((0, import_tsl3.min)(q.w, q.y));
264
+ return (0, import_tsl3.abs)(q.z.add(q.w.sub(q.y).div(chroma.mul(6).add(EPSILON))));
265
+ }
266
+ function gammaRgbToHsl(c) {
267
+ const maxChannel = (0, import_tsl3.max)(c.r, (0, import_tsl3.max)(c.g, c.b));
268
+ const minChannel = (0, import_tsl3.min)(c.r, (0, import_tsl3.min)(c.g, c.b));
269
+ const lightness = maxChannel.add(minChannel).mul(0.5);
270
+ const chroma = maxChannel.sub(minChannel);
271
+ const saturation = chroma.div((0, import_tsl3.abs)(lightness.mul(2).sub(1)).oneMinus().add(EPSILON));
272
+ return (0, import_tsl3.vec3)(gammaRgbHue(c), saturation, lightness);
273
+ }
274
+ function hslToGammaRgb(hsl) {
275
+ const hue = hsl.x;
276
+ const saturation = hsl.y;
277
+ const lightness = hsl.z;
278
+ const chroma = (0, import_tsl3.abs)(lightness.mul(2).sub(1)).oneMinus().mul(saturation);
279
+ const ramp = (0, import_tsl3.abs)(
280
+ (0, import_tsl3.fract)((0, import_tsl3.vec3)(hue).add((0, import_tsl3.vec3)(1, 2 / 3, 1 / 3))).mul(6).sub((0, import_tsl3.vec3)(3))
281
+ );
282
+ const hueRgb = (0, import_tsl3.clamp)(ramp.sub((0, import_tsl3.vec3)(1)), 0, 1);
283
+ return hueRgb.sub(0.5).mul(chroma).add(lightness);
284
+ }
285
+ var hslSpace = {
286
+ // Clamp into sRGB before the gamma transfer: HSL is an sRGB-gamut concept, and
287
+ // the sRGB OETF's pow() can't be WGSL const-evaluated on the negative channels
288
+ // of an out-of-sRGB (wide-gamut) stop color — that crashed the shader compile.
289
+ fromLinear: (rgb) => gammaRgbToHsl(linearToSrgb((0, import_tsl3.clamp)(rgb, 0, 1))),
290
+ toLinear: (hsl) => srgbToLinear(hslToGammaRgb(hsl)),
291
+ lerp: (a, b, t, hue) => (0, import_tsl3.vec3)(hue(a.x, b.x, t, 1), (0, import_tsl3.mix)(a.y, b.y, t), (0, import_tsl3.mix)(a.z, b.z, t))
292
+ };
293
+
294
+ // src/primitives/color-space/hsv.ts
295
+ var import_tsl4 = require("three/tsl");
296
+ var EPSILON2 = 1e-10;
297
+ function gammaRgbToHsv(c) {
298
+ const p = (0, import_tsl4.mix)((0, import_tsl4.vec4)(c.b, c.g, -1 / 3, 2 / 3), (0, import_tsl4.vec4)(c.g, c.b, 0, -1 / 3), (0, import_tsl4.step)(c.b, c.g));
299
+ const q = (0, import_tsl4.mix)((0, import_tsl4.vec4)(p.x, p.y, p.w, c.r), (0, import_tsl4.vec4)(c.r, p.y, p.z, p.x), (0, import_tsl4.step)(p.x, c.r));
300
+ const chroma = q.x.sub((0, import_tsl4.min)(q.w, q.y));
301
+ const hue = (0, import_tsl4.abs)(q.z.add(q.w.sub(q.y).div(chroma.mul(6).add(EPSILON2))));
302
+ const saturation = chroma.div(q.x.add(EPSILON2));
303
+ return (0, import_tsl4.vec3)(hue, saturation, q.x);
304
+ }
305
+ function hsvToGammaRgb(hsv) {
306
+ const hue = hsv.x;
307
+ const saturation = hsv.y;
308
+ const value = hsv.z;
309
+ const ramp = (0, import_tsl4.abs)(
310
+ (0, import_tsl4.fract)((0, import_tsl4.vec3)(hue).add((0, import_tsl4.vec3)(1, 2 / 3, 1 / 3))).mul(6).sub((0, import_tsl4.vec3)(3))
311
+ );
312
+ return (0, import_tsl4.mix)((0, import_tsl4.vec3)(1), (0, import_tsl4.clamp)(ramp.sub((0, import_tsl4.vec3)(1)), 0, 1), saturation).mul(value);
313
+ }
314
+ var hsvSpace = {
315
+ // Clamp into sRGB before the gamma transfer: HSV is an sRGB-gamut concept, and
316
+ // the sRGB OETF's pow() can't be WGSL const-evaluated on the negative channels
317
+ // of an out-of-sRGB (wide-gamut) stop color — that crashed the shader compile.
318
+ fromLinear: (rgb) => gammaRgbToHsv(linearToSrgb((0, import_tsl4.clamp)(rgb, 0, 1))),
319
+ toLinear: (hsv) => srgbToLinear(hsvToGammaRgb(hsv)),
320
+ lerp: (a, b, t, hue) => (0, import_tsl4.vec3)(hue(a.x, b.x, t, 1), (0, import_tsl4.mix)(a.y, b.y, t), (0, import_tsl4.mix)(a.z, b.z, t))
321
+ };
322
+
323
+ // src/primitives/color-space/lch.ts
324
+ var import_tsl5 = require("three/tsl");
325
+ var TWO_PI = Math.PI * 2;
326
+ var WHITE_X = 0.95047;
327
+ var WHITE_Y = 1;
328
+ var WHITE_Z = 1.08883;
329
+ var EPSILON3 = 216 / 24389;
330
+ var KAPPA = 24389 / 27;
331
+ function labForward(ratio) {
332
+ const linearPart = ratio.mul(KAPPA).add(16).div(116);
333
+ const cubeRootPart = (0, import_tsl5.cbrt)(ratio);
334
+ return (0, import_tsl5.mix)(linearPart, cubeRootPart, (0, import_tsl5.step)(EPSILON3, ratio));
335
+ }
336
+ function labInverse(f) {
337
+ const cubed = f.mul(f).mul(f);
338
+ const linearPart = f.mul(116).sub(16).div(KAPPA);
339
+ return (0, import_tsl5.mix)(linearPart, cubed, (0, import_tsl5.step)(EPSILON3, cubed));
340
+ }
341
+ function linearToLch(rgb) {
342
+ const r = rgb.r;
343
+ const g = rgb.g;
344
+ const b = rgb.b;
345
+ const x = r.mul(0.4123907993).add(g.mul(0.3575843394)).add(b.mul(0.1804807884));
346
+ const y = r.mul(0.2126390059).add(g.mul(0.7151686788)).add(b.mul(0.0721923154));
347
+ const z = r.mul(0.0193308187).add(g.mul(0.1191947798)).add(b.mul(0.9505321522));
348
+ const fx = labForward(x.div(WHITE_X));
349
+ const fy = labForward(y.div(WHITE_Y));
350
+ const fz = labForward(z.div(WHITE_Z));
351
+ const lightness = fy.mul(116).sub(16);
352
+ const greenRed = fx.sub(fy).mul(500);
353
+ const blueYellow = fy.sub(fz).mul(200);
354
+ const chroma = (0, import_tsl5.length)((0, import_tsl5.vec2)(greenRed, blueYellow));
355
+ const hue = (0, import_tsl5.atan2)(blueYellow, greenRed);
356
+ return (0, import_tsl5.vec3)(lightness, chroma, hue);
357
+ }
358
+ function lchToLinear(lch) {
359
+ const lightness = lch.x;
360
+ const chroma = lch.y;
361
+ const hue = lch.z;
362
+ const greenRed = chroma.mul((0, import_tsl5.cos)(hue));
363
+ const blueYellow = chroma.mul((0, import_tsl5.sin)(hue));
364
+ const fy = lightness.add(16).div(116);
365
+ const fx = fy.add(greenRed.div(500));
366
+ const fz = fy.sub(blueYellow.div(200));
367
+ const x = labInverse(fx).mul(WHITE_X);
368
+ const y = labInverse(fy).mul(WHITE_Y);
369
+ const z = labInverse(fz).mul(WHITE_Z);
370
+ const r = x.mul(3.2409699419).sub(y.mul(1.5373831776)).sub(z.mul(0.4986107603));
371
+ const g = x.mul(-0.9692436363).add(y.mul(1.8759675015)).add(z.mul(0.0415550574));
372
+ const b = x.mul(0.0556300797).sub(y.mul(0.2039769589)).add(z.mul(1.0569715142));
373
+ return (0, import_tsl5.vec3)(r, g, b);
374
+ }
375
+ var lchSpace = {
376
+ fromLinear: linearToLch,
377
+ toLinear: lchToLinear,
378
+ lerp: (a, b, t, hue) => (0, import_tsl5.vec3)((0, import_tsl5.mix)(a.x, b.x, t), (0, import_tsl5.mix)(a.y, b.y, t), hue(a.z, b.z, t, TWO_PI))
379
+ };
380
+
381
+ // src/primitives/color-space/linear.ts
382
+ var import_tsl6 = require("three/tsl");
383
+ var linearSpace = {
384
+ fromLinear: (rgb) => (0, import_tsl6.vec3)(rgb),
385
+ toLinear: (coords) => (0, import_tsl6.vec3)(coords),
386
+ lerp: (a, b, t) => (0, import_tsl6.mix)(a, b, t)
387
+ };
388
+
389
+ // src/primitives/color-space/oklab.ts
390
+ var import_tsl7 = require("three/tsl");
391
+ function linearToOklab(rgb) {
392
+ const r = rgb.r;
393
+ const g = rgb.g;
394
+ const b = rgb.b;
395
+ const longCone = r.mul(0.4122214708).add(g.mul(0.5363325363)).add(b.mul(0.0514459929));
396
+ const mediumCone = r.mul(0.2119034982).add(g.mul(0.6806995451)).add(b.mul(0.1073969566));
397
+ const shortCone = r.mul(0.0883024619).add(g.mul(0.2817188376)).add(b.mul(0.6299787005));
398
+ const longRoot = (0, import_tsl7.cbrt)(longCone);
399
+ const mediumRoot = (0, import_tsl7.cbrt)(mediumCone);
400
+ const shortRoot = (0, import_tsl7.cbrt)(shortCone);
401
+ const lightness = longRoot.mul(0.2104542553).add(mediumRoot.mul(0.793617785)).sub(shortRoot.mul(0.0040720468));
402
+ const greenRed = longRoot.mul(1.9779984951).sub(mediumRoot.mul(2.428592205)).add(shortRoot.mul(0.4505937099));
403
+ const blueYellow = longRoot.mul(0.0259040371).add(mediumRoot.mul(0.7827717662)).sub(shortRoot.mul(0.808675766));
404
+ return (0, import_tsl7.vec3)(lightness, greenRed, blueYellow);
405
+ }
406
+ function oklabToLinear(lab) {
407
+ const lightness = lab.x;
408
+ const greenRed = lab.y;
409
+ const blueYellow = lab.z;
410
+ const longRoot = lightness.add(greenRed.mul(0.3963377774)).add(blueYellow.mul(0.2158037573));
411
+ const mediumRoot = lightness.sub(greenRed.mul(0.1055613458)).sub(blueYellow.mul(0.0638541728));
412
+ const shortRoot = lightness.sub(greenRed.mul(0.0894841775)).sub(blueYellow.mul(1.291485548));
413
+ const longCone = longRoot.mul(longRoot).mul(longRoot);
414
+ const mediumCone = mediumRoot.mul(mediumRoot).mul(mediumRoot);
415
+ const shortCone = shortRoot.mul(shortRoot).mul(shortRoot);
416
+ const r = longCone.mul(4.0767416621).sub(mediumCone.mul(3.3077115913)).add(shortCone.mul(0.2309699292));
417
+ const g = longCone.mul(-1.2684380046).add(mediumCone.mul(2.6097574011)).sub(shortCone.mul(0.3413193965));
418
+ const b = longCone.mul(-0.0041960863).sub(mediumCone.mul(0.7034186147)).add(shortCone.mul(1.707614701));
419
+ return (0, import_tsl7.vec3)(r, g, b);
420
+ }
421
+ var oklabSpace = {
422
+ fromLinear: linearToOklab,
423
+ toLinear: oklabToLinear,
424
+ lerp: (a, b, t) => (0, import_tsl7.mix)(a, b, t)
425
+ };
426
+
427
+ // src/primitives/color-space/oklch.ts
428
+ var import_tsl8 = require("three/tsl");
429
+ var TWO_PI2 = Math.PI * 2;
430
+ function linearToOklch(rgb) {
431
+ const lab = linearToOklab(rgb);
432
+ const lightness = lab.x;
433
+ const greenRed = lab.y;
434
+ const blueYellow = lab.z;
435
+ const chroma = (0, import_tsl8.length)((0, import_tsl8.vec2)(greenRed, blueYellow));
436
+ const hue = (0, import_tsl8.atan2)(blueYellow, greenRed);
437
+ return (0, import_tsl8.vec3)(lightness, chroma, hue);
438
+ }
439
+ function oklchToLinear(lch) {
440
+ const lightness = lch.x;
441
+ const chroma = lch.y;
442
+ const hue = lch.z;
443
+ const greenRed = chroma.mul((0, import_tsl8.cos)(hue));
444
+ const blueYellow = chroma.mul((0, import_tsl8.sin)(hue));
445
+ return oklabToLinear((0, import_tsl8.vec3)(lightness, greenRed, blueYellow));
446
+ }
447
+ var oklchSpace = {
448
+ fromLinear: linearToOklch,
449
+ toLinear: oklchToLinear,
450
+ lerp: (a, b, t, hue) => (0, import_tsl8.vec3)((0, import_tsl8.mix)(a.x, b.x, t), (0, import_tsl8.mix)(a.y, b.y, t), hue(a.z, b.z, t, TWO_PI2))
451
+ };
452
+
453
+ // src/primitives/color-space/registry.ts
454
+ var colorSpaces = {
455
+ linear: linearSpace,
456
+ oklab: oklabSpace,
457
+ oklch: oklchSpace,
458
+ lch: lchSpace,
459
+ hsl: hslSpace,
460
+ hsv: hsvSpace
461
+ };
462
+
463
+ // src/primitives/color-ramp/color-ramp.ts
464
+ function colorRamp(t, stops, colorSpace = "linear", hueInterpolation = "shorter") {
465
+ const space = colorSpaces[colorSpace];
466
+ const hue = hueArcInterpolators[hueInterpolation];
161
467
  const first = stops[0];
162
- if (first === void 0) return (0, import_tsl.vec3)(0, 0, 0);
163
- if (stops.length === 1) return (0, import_tsl.mix)(first.color, first.color, 0);
164
- let result = (0, import_tsl.mix)(first.color, first.color, 0);
468
+ if (first === void 0) return (0, import_tsl9.vec3)(0, 0, 0);
469
+ const firstCoords = space.fromLinear((0, import_tsl9.vec3)(first.color));
470
+ if (stops.length === 1) return space.toLinear(firstCoords);
471
+ let resultCoords = firstCoords;
165
472
  for (let i = 1; i < stops.length; i += 1) {
166
- const prev = stops[i - 1];
473
+ const previousStop = stops[i - 1];
167
474
  const next = stops[i];
168
- if (prev === void 0 || next === void 0) continue;
169
- const span = next.position - prev.position;
170
- if (span <= 0) continue;
171
- const localT = (0, import_tsl2.clamp)((0, import_tsl2.div)((0, import_tsl2.sub)(t, prev.position), span), 0, 1);
172
- result = (0, import_tsl.mix)(result, next.color, localT);
475
+ if (previousStop === void 0 || next === void 0) continue;
476
+ const positionSpan = next.position - previousStop.position;
477
+ if (positionSpan <= 0) continue;
478
+ const localT = (0, import_tsl9.clamp)((0, import_tsl9.div)((0, import_tsl9.sub)(t, previousStop.position), positionSpan), 0, 1);
479
+ const nextCoords = space.fromLinear((0, import_tsl9.vec3)(next.color));
480
+ resultCoords = space.lerp(resultCoords, nextCoords, localT, hue);
173
481
  }
174
- return result;
482
+ return space.toLinear(resultCoords);
483
+ }
484
+
485
+ // src/primitives/color-space/mix-color.ts
486
+ var import_tsl10 = require("three/tsl");
487
+ function mixColor(colorA, colorB, t, colorSpace = "oklab", hueInterpolation = "shorter") {
488
+ const space = colorSpaces[colorSpace];
489
+ const hue = hueArcInterpolators[hueInterpolation];
490
+ const a = space.fromLinear((0, import_tsl10.vec3)(colorA));
491
+ const b = space.fromLinear((0, import_tsl10.vec3)(colorB));
492
+ return space.toLinear(space.lerp(a, b, t, hue));
493
+ }
494
+
495
+ // src/primitives/color-space/cpu-convert.ts
496
+ function oklabToLinearSrgb(lightness, greenRed, blueYellow) {
497
+ const longRoot = lightness + 0.3963377774 * greenRed + 0.2158037573 * blueYellow;
498
+ const mediumRoot = lightness - 0.1055613458 * greenRed - 0.0638541728 * blueYellow;
499
+ const shortRoot = lightness - 0.0894841775 * greenRed - 1.291485548 * blueYellow;
500
+ const longCone = longRoot * longRoot * longRoot;
501
+ const mediumCone = mediumRoot * mediumRoot * mediumRoot;
502
+ const shortCone = shortRoot * shortRoot * shortRoot;
503
+ const red = 4.0767416621 * longCone - 3.3077115913 * mediumCone + 0.2309699292 * shortCone;
504
+ const green = -1.2684380046 * longCone + 2.6097574011 * mediumCone - 0.3413193965 * shortCone;
505
+ const blue = -0.0041960863 * longCone - 0.7034186147 * mediumCone + 1.707614701 * shortCone;
506
+ return [red, green, blue];
507
+ }
508
+ function oklchToLinearSrgb(lightness, chroma, hueDegrees) {
509
+ const hueRadians = hueDegrees * Math.PI / 180;
510
+ const greenRed = chroma * Math.cos(hueRadians);
511
+ const blueYellow = chroma * Math.sin(hueRadians);
512
+ return oklabToLinearSrgb(lightness, greenRed, blueYellow);
513
+ }
514
+ function parseComponent(token, scale) {
515
+ const trimmed = token.trim();
516
+ if (trimmed.endsWith("%")) {
517
+ return parseFloat(trimmed.slice(0, -1)) / 100 * scale;
518
+ }
519
+ return parseFloat(trimmed);
520
+ }
521
+ function functionArgs(input, prefix) {
522
+ const inner = input.slice(prefix.length, input.lastIndexOf(")"));
523
+ const beforeAlpha = inner.split("/")[0] ?? "";
524
+ return beforeAlpha.trim().split(/[\s,]+/).filter((token) => token.length > 0);
525
+ }
526
+ function parseColorString(input) {
527
+ const value = input.trim();
528
+ if (value.startsWith("#")) {
529
+ const hex = value.slice(1);
530
+ return [
531
+ srgbChannelToLinear(parseInt(hex.slice(0, 2), 16) / 255),
532
+ srgbChannelToLinear(parseInt(hex.slice(2, 4), 16) / 255),
533
+ srgbChannelToLinear(parseInt(hex.slice(4, 6), 16) / 255)
534
+ ];
535
+ }
536
+ if (value.startsWith("oklch(")) {
537
+ const [lightnessToken, chromaToken, hueToken] = functionArgs(value, "oklch(");
538
+ if (lightnessToken === void 0 || chromaToken === void 0 || hueToken === void 0) {
539
+ throw new Error(`Invalid oklch() color: "${input}"`);
540
+ }
541
+ const lightness = parseComponent(lightnessToken, 1);
542
+ const chroma = parseComponent(chromaToken, 0.4);
543
+ const hueDegrees = parseFloat(hueToken.replace(/deg$/, ""));
544
+ return oklchToLinearSrgb(lightness, chroma, hueDegrees);
545
+ }
546
+ if (value.startsWith("oklab(")) {
547
+ const [lightnessToken, aToken, bToken] = functionArgs(value, "oklab(");
548
+ if (lightnessToken === void 0 || aToken === void 0 || bToken === void 0) {
549
+ throw new Error(`Invalid oklab() color: "${input}"`);
550
+ }
551
+ return oklabToLinearSrgb(
552
+ parseComponent(lightnessToken, 1),
553
+ parseComponent(aToken, 0.4),
554
+ parseComponent(bToken, 0.4)
555
+ );
556
+ }
557
+ throw new Error(`Unsupported color syntax: "${input}". Use #rrggbb, oklch(...), or oklab(...).`);
175
558
  }
176
559
 
177
560
  // src/primitives/noise/noise.ts
178
- var import_tsl3 = require("three/tsl");
179
- function noise(p) {
180
- return (0, import_tsl3.mx_noise_float)(p);
561
+ var import_tsl11 = require("three/tsl");
562
+ function simplexNoise(p) {
563
+ return (0, import_tsl11.mx_noise_float)(p);
181
564
  }
182
565
 
183
566
  // src/primitives/fbm/fbm.ts
184
- var import_tsl4 = require("three/tsl");
185
- function fbm(p, opts = {}) {
567
+ var import_tsl12 = require("three/tsl");
568
+ function fractalNoise(p, opts = {}) {
186
569
  const octaves = opts.octaves ?? 4;
187
570
  const lacunarity = opts.lacunarity ?? 2;
188
571
  const gain = opts.gain ?? 0.5;
189
- let sum = noise(p);
190
- let amp = 1;
191
- let freq = 1;
192
- let total = amp;
572
+ let sum = simplexNoise(p);
573
+ let amplitude = 1;
574
+ let frequency = 1;
575
+ let total = amplitude;
193
576
  for (let i = 1; i < octaves; i += 1) {
194
- freq *= lacunarity;
195
- amp *= gain;
196
- total += amp;
197
- const pAtFreq = (0, import_tsl4.add)((0, import_tsl4.mul)(p, freq), i * 100);
198
- const layer = noise(pAtFreq).mul(amp);
577
+ frequency *= lacunarity;
578
+ amplitude *= gain;
579
+ total += amplitude;
580
+ const pAtFreq = (0, import_tsl12.add)((0, import_tsl12.mul)(p, frequency), i * 100);
581
+ const layer = simplexNoise(pAtFreq).mul(amplitude);
199
582
  sum = sum.add(layer);
200
583
  }
201
584
  return sum.div(total);
202
585
  }
203
586
 
204
587
  // src/primitives/voronoi/voronoi.ts
205
- var import_tsl5 = require("three/tsl");
588
+ var import_tsl13 = require("three/tsl");
206
589
  function voronoi(p) {
207
- return (0, import_tsl5.mx_worley_noise_float)(p);
590
+ return (0, import_tsl13.mx_worley_noise_float)(p);
208
591
  }
209
592
 
210
593
  // src/primitives/quantize/quantize.ts
@@ -212,30 +595,30 @@ function quantize(t, steps) {
212
595
  if (steps <= 1) {
213
596
  return t.mul(0);
214
597
  }
215
- const denom = steps - 1;
216
- return t.mul(denom).add(0.5).floor().div(denom);
598
+ const denominator = steps - 1;
599
+ return t.mul(denominator).add(0.5).floor().div(denominator);
217
600
  }
218
601
 
219
602
  // src/primitives/sdf-circle/sdf-circle.ts
220
- var import_tsl6 = require("three/tsl");
221
- function sdfCircle(p, radius) {
222
- return (0, import_tsl6.length)(p).sub(radius);
603
+ var import_tsl14 = require("three/tsl");
604
+ function signedDistanceFieldCircle(p, radius) {
605
+ return (0, import_tsl14.length)(p).sub(radius);
223
606
  }
224
607
 
225
608
  // src/primitives/displace/displace.ts
226
- var import_tsl7 = require("three/tsl");
609
+ var import_tsl15 = require("three/tsl");
227
610
  function displace(p, by) {
228
- return (0, import_tsl7.add)(p, by);
611
+ return (0, import_tsl15.add)(p, by);
229
612
  }
230
613
 
231
614
  // src/primitives/cursor-ripple/cursor-ripple.ts
232
- var import_tsl10 = require("three/tsl");
615
+ var import_tsl18 = require("three/tsl");
233
616
 
234
617
  // src/primitives/time/time.ts
235
- var import_tsl9 = require("three/tsl");
618
+ var import_tsl17 = require("three/tsl");
236
619
 
237
620
  // src/runtime/reduced-motion/reduced-motion.ts
238
- var import_tsl8 = require("three/tsl");
621
+ var import_tsl16 = require("three/tsl");
239
622
  var state = {
240
623
  policy: "auto",
241
624
  watchers: /* @__PURE__ */ new Set()
@@ -243,7 +626,7 @@ var state = {
243
626
  function setReducedMotionPolicy(policy) {
244
627
  if (state.policy === policy) return;
245
628
  state.policy = policy;
246
- for (const w of state.watchers) w.recompute();
629
+ for (const watcher of state.watchers) watcher.recompute();
247
630
  }
248
631
  function getReducedMotionPolicy() {
249
632
  return state.policy;
@@ -264,8 +647,8 @@ function createReducedMotionWatcher() {
264
647
  if (typeof matchMedia !== "function") {
265
648
  return {
266
649
  scale: () => computeScale(false),
267
- subscribe: (cb) => {
268
- void cb;
650
+ subscribe: (listener) => {
651
+ void listener;
269
652
  return () => {
270
653
  };
271
654
  },
@@ -274,33 +657,33 @@ function createReducedMotionWatcher() {
274
657
  }
275
658
  };
276
659
  }
277
- const mql = matchMedia("(prefers-reduced-motion: reduce)");
278
- const subs = /* @__PURE__ */ new Set();
279
- let last = computeScale(mql.matches);
660
+ const mediaQueryList = matchMedia("(prefers-reduced-motion: reduce)");
661
+ const subscriptions = /* @__PURE__ */ new Set();
662
+ let lastComputedScale = computeScale(mediaQueryList.matches);
280
663
  const onChange = () => {
281
- const next = computeScale(mql.matches);
282
- if (next !== last) {
283
- last = next;
284
- for (const cb of subs) cb(next);
664
+ const next = computeScale(mediaQueryList.matches);
665
+ if (next !== lastComputedScale) {
666
+ lastComputedScale = next;
667
+ for (const listener of subscriptions) listener(next);
285
668
  }
286
669
  };
287
- mql.addEventListener("change", onChange);
670
+ mediaQueryList.addEventListener("change", onChange);
288
671
  const watcher = {
289
- scale: () => last,
290
- subscribe(cb) {
291
- subs.add(cb);
292
- return () => subs.delete(cb);
672
+ scale: () => lastComputedScale,
673
+ subscribe(listener) {
674
+ subscriptions.add(listener);
675
+ return () => subscriptions.delete(listener);
293
676
  },
294
677
  recompute() {
295
- const next = computeScale(mql.matches);
296
- if (next !== last) {
297
- last = next;
298
- for (const cb of subs) cb(next);
678
+ const next = computeScale(mediaQueryList.matches);
679
+ if (next !== lastComputedScale) {
680
+ lastComputedScale = next;
681
+ for (const listener of subscriptions) listener(next);
299
682
  }
300
683
  },
301
684
  dispose() {
302
- mql.removeEventListener("change", onChange);
303
- subs.clear();
685
+ mediaQueryList.removeEventListener("change", onChange);
686
+ subscriptions.clear();
304
687
  state.watchers.delete(watcher);
305
688
  }
306
689
  };
@@ -312,7 +695,7 @@ var globalWatcher = null;
312
695
  function getReducedMotionTimeScale() {
313
696
  if (globalScaleUniform === null) {
314
697
  globalWatcher = createReducedMotionWatcher();
315
- globalScaleUniform = (0, import_tsl8.uniform)(globalWatcher.scale());
698
+ globalScaleUniform = (0, import_tsl16.uniform)(globalWatcher.scale());
316
699
  globalWatcher.subscribe((s) => {
317
700
  if (globalScaleUniform === null) return;
318
701
  globalScaleUniform.value = s;
@@ -322,7 +705,7 @@ function getReducedMotionTimeScale() {
322
705
  }
323
706
 
324
707
  // src/primitives/time/time.ts
325
- var time = import_tsl9.time.mul(getReducedMotionTimeScale());
708
+ var elapsedTime = import_tsl17.time.mul(getReducedMotionTimeScale());
326
709
 
327
710
  // src/primitives/cursor-ripple/cursor-ripple.ts
328
711
  function cursorRipple(p, center, opts = {}) {
@@ -330,20 +713,31 @@ function cursorRipple(p, center, opts = {}) {
330
713
  const frequency = opts.frequency ?? 30;
331
714
  const speed = opts.speed ?? 6;
332
715
  const amplitude = opts.amplitude ?? 0.5;
333
- const d = (0, import_tsl10.length)((0, import_tsl10.sub)(p, center));
334
- const wave = (0, import_tsl10.sin)(d.mul(frequency).sub(time.mul(speed)));
335
- const decay = (0, import_tsl10.smoothstep)(reach, 0, d);
716
+ const d = (0, import_tsl18.length)((0, import_tsl18.sub)(p, center));
717
+ const wave = (0, import_tsl18.sin)(d.mul(frequency).sub(elapsedTime.mul(speed)));
718
+ const decay = (0, import_tsl18.smoothstep)(reach, 0, d);
336
719
  return wave.mul(amplitude).mul(decay);
337
720
  }
338
721
 
339
722
  // src/primitives/film-grain/film-grain.ts
340
- var import_tsl11 = require("three/tsl");
341
- function filmGrain(uvNode, intensity, timeOffset = 0) {
342
- const HASH_C1 = (0, import_tsl11.vec2)(2127.1, 81.17);
343
- const HASH_C2 = (0, import_tsl11.vec2)(1269.5, 283.37);
344
- const base = (0, import_tsl11.vec2)(uvNode.dot(HASH_C1).add(timeOffset), uvNode.dot(HASH_C2).add(timeOffset));
345
- const hash = (0, import_tsl11.fract)((0, import_tsl11.sin)(base).mul(43758.5453));
346
- return (0, import_tsl11.length)(hash).sub(0.765).mul(intensity);
723
+ var import_tsl19 = require("three/tsl");
724
+ function filmGrain(intensity, timeOffset = 0) {
725
+ const pixel = import_tsl19.screenCoordinate.xy.floor();
726
+ const seed = pixel.x.toUint().mul(1973).add(pixel.y.toUint().mul(9277)).add((0, import_tsl19.mul)(timeOffset, 26699).toUint());
727
+ return (0, import_tsl19.hash)(seed).sub(0.5).mul(intensity);
728
+ }
729
+
730
+ // src/primitives/dither/dither.ts
731
+ var import_tsl20 = require("three/tsl");
732
+ function hash21(coord) {
733
+ return (0, import_tsl20.fract)((0, import_tsl20.sin)((0, import_tsl20.dot)(coord, (0, import_tsl20.vec2)(12.9898, 78.233))).mul(43758.5453));
734
+ }
735
+ function dither(color, coord, amount = 1 / 255) {
736
+ const pixelCoord = (0, import_tsl20.vec2)(coord);
737
+ const firstHash = hash21(pixelCoord);
738
+ const secondHash = hash21(pixelCoord.add((0, import_tsl20.vec2)(0.5, 0.5)));
739
+ const triangularNoise = firstHash.sub(secondHash).mul(0.5);
740
+ return (0, import_tsl20.vec3)(color).add(triangularNoise.mul(amount));
347
741
  }
348
742
 
349
743
  // src/runtime/visibility/visibility.ts
@@ -357,21 +751,21 @@ function createVisibilityWatcher() {
357
751
  }
358
752
  };
359
753
  }
360
- const subs = /* @__PURE__ */ new Set();
754
+ const subscriptions = /* @__PURE__ */ new Set();
361
755
  const onChange = () => {
362
- const v = document.visibilityState === "visible";
363
- for (const cb of subs) cb(v);
756
+ const isVisible = document.visibilityState === "visible";
757
+ for (const listener of subscriptions) listener(isVisible);
364
758
  };
365
759
  document.addEventListener("visibilitychange", onChange);
366
760
  return {
367
761
  isVisible: () => document.visibilityState === "visible",
368
- subscribe(cb) {
369
- subs.add(cb);
370
- return () => subs.delete(cb);
762
+ subscribe(listener) {
763
+ subscriptions.add(listener);
764
+ return () => subscriptions.delete(listener);
371
765
  },
372
766
  dispose() {
373
767
  document.removeEventListener("visibilitychange", onChange);
374
- subs.clear();
768
+ subscriptions.clear();
375
769
  }
376
770
  };
377
771
  }
@@ -387,27 +781,27 @@ function createIntersectionWatcher(canvas) {
387
781
  }
388
782
  };
389
783
  }
390
- const subs = /* @__PURE__ */ new Set();
784
+ const subscriptions = /* @__PURE__ */ new Set();
391
785
  let inView = true;
392
- const obs = new IntersectionObserver(
786
+ const observer = new IntersectionObserver(
393
787
  (entries) => {
394
- const next = entries.some((e) => e.isIntersecting);
788
+ const next = entries.some((entry) => entry.isIntersecting);
395
789
  if (next === inView) return;
396
790
  inView = next;
397
- for (const cb of subs) cb(inView);
791
+ for (const listener of subscriptions) listener(inView);
398
792
  },
399
793
  { threshold: 0 }
400
794
  );
401
- obs.observe(canvas);
795
+ observer.observe(canvas);
402
796
  return {
403
797
  isInView: () => inView,
404
- subscribe(cb) {
405
- subs.add(cb);
406
- return () => subs.delete(cb);
798
+ subscribe(listener) {
799
+ subscriptions.add(listener);
800
+ return () => subscriptions.delete(listener);
407
801
  },
408
802
  dispose() {
409
- obs.disconnect();
410
- subs.clear();
803
+ observer.disconnect();
804
+ subscriptions.clear();
411
805
  }
412
806
  };
413
807
  }
@@ -418,10 +812,19 @@ var FrameScheduler = class {
418
812
  rafId = null;
419
813
  running = false;
420
814
  paused = false;
421
- idle = false;
422
815
  flushPending = false;
423
816
  startedAt = 0;
424
817
  lastTickAt = 0;
818
+ // Reference-counted idle voting. The scheduler is idle only when at least
819
+ // one component has voted idle AND no component has voted animated. This
820
+ // prevents a static component (e.g. LinearGradient speed=0) from halting
821
+ // the loop while an animated overlay (e.g. FilmGrain) is still running.
822
+ idleVotes = 0;
823
+ animatedVotes = 0;
824
+ /** True when all participating components prefer idle and none need animation. */
825
+ get idle() {
826
+ return this.idleVotes > 0 && this.animatedVotes === 0;
827
+ }
425
828
  /** Activate the scheduler. The rAF loop starts on the first client added. */
426
829
  start() {
427
830
  this.running = true;
@@ -457,19 +860,39 @@ var FrameScheduler = class {
457
860
  this.clients.clear();
458
861
  }
459
862
  /**
460
- * Mark the scheduler idle. The next tick still fires (a final flush so
461
- * uniform changes that triggered the idle state are rendered), then the
462
- * rAF loop halts. Use `requestRender()` or `setIdle(false)` to wake.
863
+ * Cast a vote on whether the scheduler should be idle.
864
+ *
865
+ * `setIdle(true)` increments the idle-vote count; the returned cleanup
866
+ * decrements it. `setIdle(false)` increments the animated-vote count;
867
+ * its cleanup decrements that. The scheduler halts (after one flush tick)
868
+ * only when `idleVotes > 0 && animatedVotes === 0`.
869
+ *
870
+ * Callers are responsible for calling the returned cleanup on unmount.
871
+ * Use `requestRender()` or cast a `setIdle(false)` vote to wake the loop
872
+ * without permanently registering an animated preference.
463
873
  */
464
874
  setIdle(idle) {
465
- if (this.idle === idle) return;
466
- this.idle = idle;
467
875
  if (idle) {
468
- this.flushPending = true;
469
- this.maybeQueue();
876
+ const wasIdle = this.idle;
877
+ this.idleVotes += 1;
878
+ const nowIdle = this.idle;
879
+ if (!wasIdle && nowIdle) this.onBecameIdle();
880
+ return () => {
881
+ const prevIdle = this.idle;
882
+ this.idleVotes = Math.max(0, this.idleVotes - 1);
883
+ const afterIdle = this.idle;
884
+ if (prevIdle && !afterIdle) this.onBecameAnimated();
885
+ };
470
886
  } else {
471
- this.flushPending = false;
472
- this.maybeQueue();
887
+ const wasIdle = this.idle;
888
+ this.animatedVotes += 1;
889
+ if (wasIdle) this.onBecameAnimated();
890
+ return () => {
891
+ const prevIdle = this.idle;
892
+ this.animatedVotes = Math.max(0, this.animatedVotes - 1);
893
+ const nowIdle = this.idle;
894
+ if (!prevIdle && nowIdle) this.onBecameIdle();
895
+ };
473
896
  }
474
897
  }
475
898
  /** Force a single tick while idle. Useful for prop-change invalidation. */
@@ -478,6 +901,14 @@ var FrameScheduler = class {
478
901
  this.flushPending = true;
479
902
  this.maybeQueue();
480
903
  }
904
+ onBecameIdle() {
905
+ this.flushPending = true;
906
+ this.maybeQueue();
907
+ }
908
+ onBecameAnimated() {
909
+ this.flushPending = false;
910
+ this.maybeQueue();
911
+ }
481
912
  maybeQueue() {
482
913
  if (this.rafId !== null) return;
483
914
  if (!this.running) return;
@@ -520,15 +951,21 @@ var FrameScheduler = class {
520
951
  createVisibilityWatcher,
521
952
  cursorRipple,
522
953
  displace,
523
- fbm,
954
+ dither,
955
+ elapsedTime,
524
956
  filmGrain,
957
+ fractalNoise,
525
958
  getReducedMotionPolicy,
526
959
  getReducedMotionTimeScale,
527
- noise,
960
+ mixColor,
961
+ oklabToLinearSrgb,
962
+ oklchToLinearSrgb,
963
+ parseColorString,
528
964
  quantize,
529
- sdfCircle,
530
965
  setReducedMotionPolicy,
531
- time,
966
+ signedDistanceFieldCircle,
967
+ simplexNoise,
968
+ srgbChannelToLinear,
532
969
  voronoi
533
970
  });
534
971
  //# sourceMappingURL=index.cjs.map