@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/CHANGELOG.md +28 -0
- package/README.md +3 -3
- package/dist/index.cjs +563 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +104 -58
- package/dist/index.d.ts +104 -58
- package/dist/index.js +547 -111
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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 = (
|
|
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
|
-
|
|
32
|
+
dither: () => dither,
|
|
33
|
+
elapsedTime: () => elapsedTime,
|
|
33
34
|
filmGrain: () => filmGrain,
|
|
35
|
+
fractalNoise: () => fractalNoise,
|
|
34
36
|
getReducedMotionPolicy: () => getReducedMotionPolicy,
|
|
35
37
|
getReducedMotionTimeScale: () => getReducedMotionTimeScale,
|
|
36
|
-
|
|
38
|
+
mixColor: () => mixColor,
|
|
39
|
+
oklabToLinearSrgb: () => oklabToLinearSrgb,
|
|
40
|
+
oklchToLinearSrgb: () => oklchToLinearSrgb,
|
|
41
|
+
parseColorString: () => parseColorString,
|
|
37
42
|
quantize: () => quantize,
|
|
38
|
-
sdfCircle: () => sdfCircle,
|
|
39
43
|
setReducedMotionPolicy: () => setReducedMotionPolicy,
|
|
40
|
-
|
|
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
|
|
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
|
|
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
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
|
|
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
|
|
147
|
+
const mouseEvent = e;
|
|
104
148
|
if (this.element) {
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
this.target = [
|
|
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
|
|
111
|
-
const
|
|
112
|
-
this.target = [
|
|
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(
|
|
124
|
-
this.listeners.add(
|
|
125
|
-
return () => this.listeners.delete(
|
|
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 = (
|
|
155
|
-
var lerp = (
|
|
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
|
|
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,
|
|
163
|
-
|
|
164
|
-
|
|
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
|
|
473
|
+
const previousStop = stops[i - 1];
|
|
167
474
|
const next = stops[i];
|
|
168
|
-
if (
|
|
169
|
-
const
|
|
170
|
-
if (
|
|
171
|
-
const localT = (0,
|
|
172
|
-
|
|
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
|
|
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
|
|
179
|
-
function
|
|
180
|
-
return (0,
|
|
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
|
|
185
|
-
function
|
|
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 =
|
|
190
|
-
let
|
|
191
|
-
let
|
|
192
|
-
let total =
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
total +=
|
|
197
|
-
const pAtFreq = (0,
|
|
198
|
-
const layer =
|
|
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
|
|
588
|
+
var import_tsl13 = require("three/tsl");
|
|
206
589
|
function voronoi(p) {
|
|
207
|
-
return (0,
|
|
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
|
|
216
|
-
return t.mul(
|
|
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
|
|
221
|
-
function
|
|
222
|
-
return (0,
|
|
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
|
|
609
|
+
var import_tsl15 = require("three/tsl");
|
|
227
610
|
function displace(p, by) {
|
|
228
|
-
return (0,
|
|
611
|
+
return (0, import_tsl15.add)(p, by);
|
|
229
612
|
}
|
|
230
613
|
|
|
231
614
|
// src/primitives/cursor-ripple/cursor-ripple.ts
|
|
232
|
-
var
|
|
615
|
+
var import_tsl18 = require("three/tsl");
|
|
233
616
|
|
|
234
617
|
// src/primitives/time/time.ts
|
|
235
|
-
var
|
|
618
|
+
var import_tsl17 = require("three/tsl");
|
|
236
619
|
|
|
237
620
|
// src/runtime/reduced-motion/reduced-motion.ts
|
|
238
|
-
var
|
|
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
|
|
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: (
|
|
268
|
-
void
|
|
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
|
|
278
|
-
const
|
|
279
|
-
let
|
|
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(
|
|
282
|
-
if (next !==
|
|
283
|
-
|
|
284
|
-
for (const
|
|
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
|
-
|
|
670
|
+
mediaQueryList.addEventListener("change", onChange);
|
|
288
671
|
const watcher = {
|
|
289
|
-
scale: () =>
|
|
290
|
-
subscribe(
|
|
291
|
-
|
|
292
|
-
return () =>
|
|
672
|
+
scale: () => lastComputedScale,
|
|
673
|
+
subscribe(listener) {
|
|
674
|
+
subscriptions.add(listener);
|
|
675
|
+
return () => subscriptions.delete(listener);
|
|
293
676
|
},
|
|
294
677
|
recompute() {
|
|
295
|
-
const next = computeScale(
|
|
296
|
-
if (next !==
|
|
297
|
-
|
|
298
|
-
for (const
|
|
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
|
-
|
|
303
|
-
|
|
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,
|
|
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
|
|
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,
|
|
334
|
-
const wave = (0,
|
|
335
|
-
const decay = (0,
|
|
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
|
|
341
|
-
function filmGrain(
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
|
754
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
361
755
|
const onChange = () => {
|
|
362
|
-
const
|
|
363
|
-
for (const
|
|
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(
|
|
369
|
-
|
|
370
|
-
return () =>
|
|
762
|
+
subscribe(listener) {
|
|
763
|
+
subscriptions.add(listener);
|
|
764
|
+
return () => subscriptions.delete(listener);
|
|
371
765
|
},
|
|
372
766
|
dispose() {
|
|
373
767
|
document.removeEventListener("visibilitychange", onChange);
|
|
374
|
-
|
|
768
|
+
subscriptions.clear();
|
|
375
769
|
}
|
|
376
770
|
};
|
|
377
771
|
}
|
|
@@ -387,27 +781,27 @@ function createIntersectionWatcher(canvas) {
|
|
|
387
781
|
}
|
|
388
782
|
};
|
|
389
783
|
}
|
|
390
|
-
const
|
|
784
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
391
785
|
let inView = true;
|
|
392
|
-
const
|
|
786
|
+
const observer = new IntersectionObserver(
|
|
393
787
|
(entries) => {
|
|
394
|
-
const next = entries.some((
|
|
788
|
+
const next = entries.some((entry) => entry.isIntersecting);
|
|
395
789
|
if (next === inView) return;
|
|
396
790
|
inView = next;
|
|
397
|
-
for (const
|
|
791
|
+
for (const listener of subscriptions) listener(inView);
|
|
398
792
|
},
|
|
399
793
|
{ threshold: 0 }
|
|
400
794
|
);
|
|
401
|
-
|
|
795
|
+
observer.observe(canvas);
|
|
402
796
|
return {
|
|
403
797
|
isInView: () => inView,
|
|
404
|
-
subscribe(
|
|
405
|
-
|
|
406
|
-
return () =>
|
|
798
|
+
subscribe(listener) {
|
|
799
|
+
subscriptions.add(listener);
|
|
800
|
+
return () => subscriptions.delete(listener);
|
|
407
801
|
},
|
|
408
802
|
dispose() {
|
|
409
|
-
|
|
410
|
-
|
|
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
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
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
|
-
|
|
469
|
-
this.
|
|
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
|
-
|
|
472
|
-
this.
|
|
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
|
-
|
|
954
|
+
dither,
|
|
955
|
+
elapsedTime,
|
|
524
956
|
filmGrain,
|
|
957
|
+
fractalNoise,
|
|
525
958
|
getReducedMotionPolicy,
|
|
526
959
|
getReducedMotionTimeScale,
|
|
527
|
-
|
|
960
|
+
mixColor,
|
|
961
|
+
oklabToLinearSrgb,
|
|
962
|
+
oklchToLinearSrgb,
|
|
963
|
+
parseColorString,
|
|
528
964
|
quantize,
|
|
529
|
-
sdfCircle,
|
|
530
965
|
setReducedMotionPolicy,
|
|
531
|
-
|
|
966
|
+
signedDistanceFieldCircle,
|
|
967
|
+
simplexNoise,
|
|
968
|
+
srgbChannelToLinear,
|
|
532
969
|
voronoi
|
|
533
970
|
});
|
|
534
971
|
//# sourceMappingURL=index.cjs.map
|