@shopify/klint 0.3.0 → 0.4.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 +86 -62
- package/dist/{Klint-CsVzll4n.d.cts → Klint-DqYL-aGU.d.cts} +204 -332
- package/dist/{Klint-CsVzll4n.d.ts → Klint-DqYL-aGU.d.ts} +204 -332
- package/dist/index.cjs +872 -1184
- package/dist/index.d.cts +3 -29
- package/dist/index.d.ts +3 -29
- package/dist/index.js +868 -1184
- package/dist/plugins/index.cjs +606 -466
- package/dist/plugins/index.d.cts +440 -154
- package/dist/plugins/index.d.ts +440 -154
- package/dist/plugins/index.js +593 -466
- package/package.json +1 -1
- package/dist/chunk-3RG5ZIWI.js +0 -10
package/dist/index.cjs
CHANGED
|
@@ -40,11 +40,12 @@ __export(index_exports, {
|
|
|
40
40
|
KlintCoreFunctions: () => KlintCoreFunctions,
|
|
41
41
|
KlintFunctions: () => KlintFunctions,
|
|
42
42
|
Noise: () => Noise_default,
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
Pixels: () => Pixels,
|
|
44
|
+
Quadtree: () => Quadtree_default,
|
|
45
|
+
Rectangle: () => Rectangle,
|
|
45
46
|
Strip: () => Strip_default,
|
|
46
47
|
Text: () => Text_default,
|
|
47
|
-
|
|
48
|
+
Timeline: () => Timeline,
|
|
48
49
|
Vector: () => Vector_default,
|
|
49
50
|
useKlint: () => useKlint,
|
|
50
51
|
useProps: () => useProps,
|
|
@@ -97,33 +98,23 @@ var CONFIG_PROPS = [
|
|
|
97
98
|
"__fillRule",
|
|
98
99
|
"__isPlaying"
|
|
99
100
|
];
|
|
100
|
-
function useAnimate(contextRef, draw, isVisible
|
|
101
|
+
function useAnimate(contextRef, draw, isVisible) {
|
|
101
102
|
const animationFrameId = (0, import_react.useRef)(0);
|
|
102
|
-
const frameTimeHistoryRef = (0, import_react.useRef)([]);
|
|
103
|
-
const frameStartTimeRef = (0, import_react.useRef)(0);
|
|
104
|
-
const frameCountRef = (0, import_react.useRef)(0);
|
|
105
|
-
const lastFpsUpdateRef = (0, import_react.useRef)(0);
|
|
106
|
-
const droppedFramesRef = (0, import_react.useRef)(0);
|
|
107
103
|
const animate = (0, import_react.useCallback)(
|
|
108
104
|
(timestamp = 0) => {
|
|
109
105
|
if (!contextRef.current || !isVisible) return;
|
|
110
106
|
if (!contextRef.current.__isReadyToDraw) return;
|
|
111
|
-
if (!contextRef.current.__isPlaying)
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
107
|
+
if (!contextRef.current.__isPlaying) return;
|
|
114
108
|
const context = contextRef.current;
|
|
115
109
|
const now = timestamp;
|
|
116
110
|
const target = 1e3 / context.fps;
|
|
117
111
|
if (!context.__lastTargetTime) {
|
|
118
112
|
context.__lastTargetTime = now;
|
|
119
113
|
context.__lastRealTime = now;
|
|
120
|
-
frameStartTimeRef.current = now;
|
|
121
|
-
lastFpsUpdateRef.current = now;
|
|
122
114
|
}
|
|
123
115
|
const sinceLast = now - context.__lastTargetTime;
|
|
124
116
|
const epsilon = 5;
|
|
125
117
|
if (sinceLast >= target - epsilon) {
|
|
126
|
-
const frameStart = enablePerformanceTracking && context.__performance ? performance.now() : 0;
|
|
127
118
|
context.deltaTime = now - context.__lastRealTime;
|
|
128
119
|
draw(context);
|
|
129
120
|
if (context.time > 1e7) context.time = 0;
|
|
@@ -132,40 +123,10 @@ function useAnimate(contextRef, draw, isVisible, enablePerformanceTracking = fal
|
|
|
132
123
|
context.frame++;
|
|
133
124
|
context.__lastTargetTime = now;
|
|
134
125
|
context.__lastRealTime = now;
|
|
135
|
-
if (enablePerformanceTracking && context.__performance) {
|
|
136
|
-
const frameTime = performance.now() - frameStart;
|
|
137
|
-
const targetFrameTime = 1e3 / context.fps;
|
|
138
|
-
frameTimeHistoryRef.current.push(frameTime);
|
|
139
|
-
if (frameTimeHistoryRef.current.length > 60) {
|
|
140
|
-
frameTimeHistoryRef.current.shift();
|
|
141
|
-
}
|
|
142
|
-
const avgFrameTime = frameTimeHistoryRef.current.reduce((a, b) => a + b, 0) / frameTimeHistoryRef.current.length;
|
|
143
|
-
context.__performance.frameTime = frameTime;
|
|
144
|
-
context.__performance.averageFrameTime = avgFrameTime;
|
|
145
|
-
context.__performance.minFrameTime = Math.min(
|
|
146
|
-
...frameTimeHistoryRef.current
|
|
147
|
-
);
|
|
148
|
-
context.__performance.maxFrameTime = Math.max(
|
|
149
|
-
...frameTimeHistoryRef.current
|
|
150
|
-
);
|
|
151
|
-
if (frameTime > targetFrameTime * 1.1) {
|
|
152
|
-
droppedFramesRef.current++;
|
|
153
|
-
}
|
|
154
|
-
context.__performance.droppedFrames = droppedFramesRef.current;
|
|
155
|
-
frameCountRef.current++;
|
|
156
|
-
if (now - lastFpsUpdateRef.current >= 1e3) {
|
|
157
|
-
context.__performance.fps = frameCountRef.current;
|
|
158
|
-
frameCountRef.current = 0;
|
|
159
|
-
lastFpsUpdateRef.current = now;
|
|
160
|
-
if (typeof performance !== "undefined" && performance.memory) {
|
|
161
|
-
context.__performance.memoryUsage = performance.memory.usedJSHeapSize / 1048576;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
126
|
}
|
|
166
127
|
animationFrameId.current = requestAnimationFrame(animate);
|
|
167
128
|
},
|
|
168
|
-
[draw, isVisible, contextRef
|
|
129
|
+
[draw, isVisible, contextRef]
|
|
169
130
|
);
|
|
170
131
|
return {
|
|
171
132
|
animate,
|
|
@@ -178,8 +139,7 @@ function Klint({
|
|
|
178
139
|
draw,
|
|
179
140
|
options = {},
|
|
180
141
|
preload,
|
|
181
|
-
onVisible
|
|
182
|
-
enablePerformanceTracking = false
|
|
142
|
+
onVisible
|
|
183
143
|
}) {
|
|
184
144
|
const canvasRef = (0, import_react.useRef)(null);
|
|
185
145
|
const containerRef = (0, import_react.useRef)(null);
|
|
@@ -190,21 +150,26 @@ function Klint({
|
|
|
190
150
|
);
|
|
191
151
|
const [isVisible, setIsVisible] = (0, import_react.useState)(true);
|
|
192
152
|
(0, import_react.useEffect)(() => {
|
|
153
|
+
const resetContext = () => {
|
|
154
|
+
if (contextRef.current) {
|
|
155
|
+
const ctx = contextRef.current;
|
|
156
|
+
ctx.__isPlaying = false;
|
|
157
|
+
ctx.frame = 0;
|
|
158
|
+
ctx.time = 0;
|
|
159
|
+
ctx.__offscreens?.clear();
|
|
160
|
+
ctx.__startedShape = false;
|
|
161
|
+
ctx.__currentShape = null;
|
|
162
|
+
ctx.__startedContour = false;
|
|
163
|
+
ctx.__currentContours = null;
|
|
164
|
+
ctx.__currentContour = null;
|
|
165
|
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
193
168
|
if (typeof import_meta !== "undefined" && import_meta.hot) {
|
|
194
|
-
import_meta.hot.dispose(
|
|
195
|
-
console.log("[Klint] Component unmounting due to HMR");
|
|
196
|
-
if (contextRef.current) {
|
|
197
|
-
contextRef.current.__isPlaying = false;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
169
|
+
import_meta.hot.dispose(resetContext);
|
|
200
170
|
}
|
|
201
171
|
if (typeof module !== "undefined" && module.hot) {
|
|
202
|
-
module.hot.dispose(
|
|
203
|
-
console.log("[Klint] Component unmounting due to Webpack HMR");
|
|
204
|
-
if (contextRef.current) {
|
|
205
|
-
contextRef.current.__isPlaying = false;
|
|
206
|
-
}
|
|
207
|
-
});
|
|
172
|
+
module.hot.dispose(resetContext);
|
|
208
173
|
}
|
|
209
174
|
}, []);
|
|
210
175
|
const __options = {
|
|
@@ -213,12 +178,7 @@ function Klint({
|
|
|
213
178
|
};
|
|
214
179
|
const [toStaticImage, setStaticImage] = (0, import_react.useState)(null);
|
|
215
180
|
const initContext = context?.initCoreContext;
|
|
216
|
-
const { animate, animationFrameId } = useAnimate(
|
|
217
|
-
contextRef,
|
|
218
|
-
draw,
|
|
219
|
-
isVisible,
|
|
220
|
-
enablePerformanceTracking
|
|
221
|
-
);
|
|
181
|
+
const { animate, animationFrameId } = useAnimate(contextRef, draw, isVisible);
|
|
222
182
|
const updateCanvasSize = (shouldRedraw = false) => {
|
|
223
183
|
if (!containerRef.current || !contextRef.current || !canvasRef.current)
|
|
224
184
|
return;
|
|
@@ -248,16 +208,6 @@ function Klint({
|
|
|
248
208
|
const context2 = contextRef.current;
|
|
249
209
|
if (!context2) return;
|
|
250
210
|
context2.__dpr = dpr;
|
|
251
|
-
if (enablePerformanceTracking) {
|
|
252
|
-
context2.__performance = {
|
|
253
|
-
fps: 0,
|
|
254
|
-
frameTime: 0,
|
|
255
|
-
averageFrameTime: 0,
|
|
256
|
-
minFrameTime: Infinity,
|
|
257
|
-
maxFrameTime: 0,
|
|
258
|
-
droppedFrames: 0
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
211
|
if (__options.fps && __options.fps !== context2.fps) {
|
|
262
212
|
context2.fps = __options.fps;
|
|
263
213
|
}
|
|
@@ -807,6 +757,58 @@ var Easing = class {
|
|
|
807
757
|
p = p < 0 ? 0 : p > 1 ? 1 : p;
|
|
808
758
|
return p * p * (3 - 2 * p);
|
|
809
759
|
};
|
|
760
|
+
/**
|
|
761
|
+
* Damped spring easing. Physically expressive oscillation.
|
|
762
|
+
* @param val - Progress value (0 to 1)
|
|
763
|
+
* @param tension - Spring tension (0 to 1, default 0.5). Higher = faster oscillation.
|
|
764
|
+
* @param friction - Spring friction (0 to 1, default 0.5). Higher = less damping (more bouncy).
|
|
765
|
+
*/
|
|
766
|
+
this.spring = (val, tension = 0.5, friction = 0.5) => {
|
|
767
|
+
const omega = tension * 40;
|
|
768
|
+
const zeta = 1 - friction;
|
|
769
|
+
if (zeta < 1) {
|
|
770
|
+
const omegaD = omega * Math.sqrt(1 - zeta * zeta);
|
|
771
|
+
return 1 - Math.exp(-zeta * omega * val) * (Math.cos(omegaD * val) + zeta * omega / omegaD * Math.sin(omegaD * val));
|
|
772
|
+
}
|
|
773
|
+
return 1 - (1 + omega * val) * Math.exp(-omega * val);
|
|
774
|
+
};
|
|
775
|
+
/**
|
|
776
|
+
* Staircase easing. Quantizes to N discrete steps.
|
|
777
|
+
* @param val - Progress value (0 to 1)
|
|
778
|
+
* @param n - Number of steps (default 4)
|
|
779
|
+
*/
|
|
780
|
+
this.steps = (val, n = 4) => {
|
|
781
|
+
if (n <= 0) return val;
|
|
782
|
+
return Math.floor(val * n) / n;
|
|
783
|
+
};
|
|
784
|
+
/**
|
|
785
|
+
* Frame-rate independent exponential smoothing.
|
|
786
|
+
* Use instead of naive `lerp(a, b, 0.1)` which breaks at different FPS.
|
|
787
|
+
* @param current - Current value
|
|
788
|
+
* @param target - Target value
|
|
789
|
+
* @param smoothing - Smoothing factor (higher = faster convergence)
|
|
790
|
+
* @param deltaTime - Time since last frame in seconds
|
|
791
|
+
*/
|
|
792
|
+
this.damp = (current, target, smoothing, deltaTime) => {
|
|
793
|
+
return current + (target - current) * (1 - Math.exp(-smoothing * deltaTime));
|
|
794
|
+
};
|
|
795
|
+
/**
|
|
796
|
+
* Quick rise then decay. Great for hit effects, flashes.
|
|
797
|
+
* @param val - Progress value (0 to 1)
|
|
798
|
+
* @param k - Sharpness (default 6). Higher = sharper peak.
|
|
799
|
+
*/
|
|
800
|
+
this.impulse = (val, k = 6) => {
|
|
801
|
+
const h = k * val;
|
|
802
|
+
return h * Math.exp(1 - h);
|
|
803
|
+
};
|
|
804
|
+
/**
|
|
805
|
+
* Symmetric arc. Useful for jumps, throw curves.
|
|
806
|
+
* @param val - Progress value (0 to 1)
|
|
807
|
+
* @param k - Steepness (default 1)
|
|
808
|
+
*/
|
|
809
|
+
this.parabola = (val, k = 1) => {
|
|
810
|
+
return Math.pow(4 * val * (1 - val), k);
|
|
811
|
+
};
|
|
810
812
|
this.log = () => {
|
|
811
813
|
console.log(this);
|
|
812
814
|
};
|
|
@@ -1260,17 +1262,6 @@ var Text = class {
|
|
|
1260
1262
|
};
|
|
1261
1263
|
var Text_default = Text;
|
|
1262
1264
|
|
|
1263
|
-
// src/elements/Thing.tsx
|
|
1264
|
-
var Thing = class {
|
|
1265
|
-
constructor(ctx) {
|
|
1266
|
-
this.context = ctx;
|
|
1267
|
-
}
|
|
1268
|
-
log() {
|
|
1269
|
-
console.log(this.context);
|
|
1270
|
-
}
|
|
1271
|
-
};
|
|
1272
|
-
var Thing_default = Thing;
|
|
1273
|
-
|
|
1274
1265
|
// src/elements/Grid.tsx
|
|
1275
1266
|
var Grid = class {
|
|
1276
1267
|
/**
|
|
@@ -1704,505 +1695,427 @@ var Strip = class {
|
|
|
1704
1695
|
var Strip_default = Strip;
|
|
1705
1696
|
|
|
1706
1697
|
// src/elements/Noise.tsx
|
|
1707
|
-
var
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
this.
|
|
1715
|
-
|
|
1716
|
-
[1, 1, 0],
|
|
1717
|
-
[-1, 1, 0],
|
|
1718
|
-
[1, -1, 0],
|
|
1719
|
-
[-1, -1, 0],
|
|
1720
|
-
[1, 0, 1],
|
|
1721
|
-
[-1, 0, 1],
|
|
1722
|
-
[1, 0, -1],
|
|
1723
|
-
[-1, 0, -1],
|
|
1724
|
-
[0, 1, 1],
|
|
1725
|
-
[0, -1, 1],
|
|
1726
|
-
[0, 1, -1],
|
|
1727
|
-
[0, -1, -1]
|
|
1728
|
-
];
|
|
1729
|
-
this.grad4 = [
|
|
1730
|
-
[0, 1, 1, 1],
|
|
1731
|
-
[0, 1, 1, -1],
|
|
1732
|
-
[0, 1, -1, 1],
|
|
1733
|
-
[0, 1, -1, -1],
|
|
1734
|
-
[0, -1, 1, 1],
|
|
1735
|
-
[0, -1, 1, -1],
|
|
1736
|
-
[0, -1, -1, 1],
|
|
1737
|
-
[0, -1, -1, -1],
|
|
1738
|
-
[1, 0, 1, 1],
|
|
1739
|
-
[1, 0, 1, -1],
|
|
1740
|
-
[1, 0, -1, 1],
|
|
1741
|
-
[1, 0, -1, -1],
|
|
1742
|
-
[-1, 0, 1, 1],
|
|
1743
|
-
[-1, 0, 1, -1],
|
|
1744
|
-
[-1, 0, -1, 1],
|
|
1745
|
-
[-1, 0, -1, -1],
|
|
1746
|
-
[1, 1, 0, 1],
|
|
1747
|
-
[1, 1, 0, -1],
|
|
1748
|
-
[1, -1, 0, 1],
|
|
1749
|
-
[1, -1, 0, -1],
|
|
1750
|
-
[-1, 1, 0, 1],
|
|
1751
|
-
[-1, 1, 0, -1],
|
|
1752
|
-
[-1, -1, 0, 1],
|
|
1753
|
-
[-1, -1, 0, -1],
|
|
1754
|
-
[1, 1, 1, 0],
|
|
1755
|
-
[1, 1, -1, 0],
|
|
1756
|
-
[1, -1, 1, 0],
|
|
1757
|
-
[1, -1, -1, 0],
|
|
1758
|
-
[-1, 1, 1, 0],
|
|
1759
|
-
[-1, 1, -1, 0],
|
|
1760
|
-
[-1, -1, 1, 0],
|
|
1761
|
-
[-1, -1, -1, 0]
|
|
1762
|
-
];
|
|
1763
|
-
this.currentSeed = Math.random();
|
|
1764
|
-
this.F2 = 0.5 * (Math.sqrt(3) - 1);
|
|
1765
|
-
this.G2 = (3 - Math.sqrt(3)) / 6;
|
|
1766
|
-
this.F3 = 1 / 3;
|
|
1767
|
-
this.G3 = 1 / 6;
|
|
1768
|
-
this.F4 = (Math.sqrt(5) - 1) / 4;
|
|
1769
|
-
this.G4 = (5 - Math.sqrt(5)) / 20;
|
|
1770
|
-
this.context = ctx;
|
|
1771
|
-
this.buildPermutationTable();
|
|
1698
|
+
var _Noise = class _Noise {
|
|
1699
|
+
constructor(_ctx) {
|
|
1700
|
+
this._seed = Math.random();
|
|
1701
|
+
this.p = new Uint8Array(512);
|
|
1702
|
+
this.buildPerm();
|
|
1703
|
+
}
|
|
1704
|
+
rng() {
|
|
1705
|
+
const x = Math.sin(this._seed++) * 1e4;
|
|
1706
|
+
return x - Math.floor(x);
|
|
1772
1707
|
}
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1708
|
+
buildPerm() {
|
|
1709
|
+
const t = new Uint8Array(256);
|
|
1710
|
+
for (let i = 0; i < 256; i++) t[i] = i;
|
|
1711
|
+
for (let i = 255; i > 0; i--) {
|
|
1712
|
+
const j = this.rng() * (i + 1) | 0;
|
|
1713
|
+
const tmp = t[i];
|
|
1714
|
+
t[i] = t[j];
|
|
1715
|
+
t[j] = tmp;
|
|
1780
1716
|
}
|
|
1781
|
-
let
|
|
1782
|
-
while (n > 0) {
|
|
1783
|
-
const index = Math.floor(this.random() * n--);
|
|
1784
|
-
const temp = p[n];
|
|
1785
|
-
p[n] = p[index];
|
|
1786
|
-
p[index] = temp;
|
|
1787
|
-
}
|
|
1788
|
-
this.perm = [];
|
|
1789
|
-
this.permMod12 = [];
|
|
1790
|
-
for (let i = 0; i < 512; i++) {
|
|
1791
|
-
this.perm[i] = p[i & 255];
|
|
1792
|
-
this.permMod12[i] = this.perm[i] % 12;
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
/**
|
|
1796
|
-
* Seeded random number generator
|
|
1797
|
-
*/
|
|
1798
|
-
random() {
|
|
1799
|
-
const x = Math.sin(this.currentSeed++) * 1e4;
|
|
1800
|
-
return x - Math.floor(x);
|
|
1717
|
+
for (let i = 0; i < 512; i++) this.p[i] = t[i & 255];
|
|
1801
1718
|
}
|
|
1802
|
-
/**
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
seed(seed) {
|
|
1807
|
-
this.currentSeed = seed !== void 0 ? seed : Math.random() * 1e4;
|
|
1808
|
-
this.buildPermutationTable();
|
|
1719
|
+
/** Set seed for reproducible noise */
|
|
1720
|
+
seed(s) {
|
|
1721
|
+
this._seed = s ?? Math.random() * 1e4;
|
|
1722
|
+
this.buildPerm();
|
|
1809
1723
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
*/
|
|
1813
|
-
fade(t) {
|
|
1724
|
+
// ---- Utilities ----
|
|
1725
|
+
static fade(t) {
|
|
1814
1726
|
return t * t * t * (t * (t * 6 - 15) + 10);
|
|
1815
1727
|
}
|
|
1816
|
-
|
|
1817
|
-
* Linear interpolation
|
|
1818
|
-
*/
|
|
1819
|
-
lerp(t, a, b) {
|
|
1728
|
+
static lerp(t, a, b) {
|
|
1820
1729
|
return a + t * (b - a);
|
|
1821
1730
|
}
|
|
1731
|
+
/** Improved Perlin gradient — maps 4-bit hash to one of 12 gradient directions */
|
|
1732
|
+
static grad3(h, x, y, z) {
|
|
1733
|
+
h &= 15;
|
|
1734
|
+
const u = h < 8 ? x : y;
|
|
1735
|
+
const v = h < 4 ? y : h === 12 || h === 14 ? x : z;
|
|
1736
|
+
return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
|
|
1737
|
+
}
|
|
1822
1738
|
perlin(x, y, z, w) {
|
|
1823
|
-
if (y === void 0)
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
v,
|
|
1879
|
-
this.lerp(u, grad3(aaa, xf, yf, zf), grad3(baa, xf - 1, yf, zf)),
|
|
1880
|
-
this.lerp(u, grad3(aba, xf, yf - 1, zf), grad3(bba, xf - 1, yf - 1, zf))
|
|
1739
|
+
if (y === void 0) return this.perlin1(x);
|
|
1740
|
+
if (z === void 0) return this.perlin2(x, y);
|
|
1741
|
+
if (w === void 0) return this.perlin3(x, y, z);
|
|
1742
|
+
return this.perlin4(x, y, z, w);
|
|
1743
|
+
}
|
|
1744
|
+
perlin1(x) {
|
|
1745
|
+
const p = this.p;
|
|
1746
|
+
const fx = Math.floor(x);
|
|
1747
|
+
const X = fx & 255;
|
|
1748
|
+
const xf = x - fx;
|
|
1749
|
+
const u = _Noise.fade(xf);
|
|
1750
|
+
const g = (h, d) => (h & 1) === 0 ? d : -d;
|
|
1751
|
+
return _Noise.lerp(u, g(p[X], xf), g(p[X + 1], xf - 1));
|
|
1752
|
+
}
|
|
1753
|
+
perlin2(x, y) {
|
|
1754
|
+
const { fade, lerp } = _Noise;
|
|
1755
|
+
const p = this.p;
|
|
1756
|
+
const fx = Math.floor(x), fy = Math.floor(y);
|
|
1757
|
+
const X = fx & 255, Y = fy & 255;
|
|
1758
|
+
const xf = x - fx, yf = y - fy;
|
|
1759
|
+
const u = fade(xf), v = fade(yf);
|
|
1760
|
+
const g = (h, x2, y2) => {
|
|
1761
|
+
const b = h & 3;
|
|
1762
|
+
return ((b & 1) === 0 ? x2 : -x2) + ((b & 2) === 0 ? y2 : -y2);
|
|
1763
|
+
};
|
|
1764
|
+
const aa = p[p[X] + Y], ab = p[p[X] + Y + 1];
|
|
1765
|
+
const ba = p[p[X + 1] + Y], bb = p[p[X + 1] + Y + 1];
|
|
1766
|
+
return lerp(
|
|
1767
|
+
v,
|
|
1768
|
+
lerp(u, g(aa, xf, yf), g(ba, xf - 1, yf)),
|
|
1769
|
+
lerp(u, g(ab, xf, yf - 1), g(bb, xf - 1, yf - 1))
|
|
1770
|
+
);
|
|
1771
|
+
}
|
|
1772
|
+
perlin3(x, y, z) {
|
|
1773
|
+
const { fade, lerp, grad3 } = _Noise;
|
|
1774
|
+
const p = this.p;
|
|
1775
|
+
const fx = Math.floor(x), fy = Math.floor(y), fz = Math.floor(z);
|
|
1776
|
+
const X = fx & 255, Y = fy & 255, Z = fz & 255;
|
|
1777
|
+
const xf = x - fx, yf = y - fy, zf = z - fz;
|
|
1778
|
+
const u = fade(xf), v = fade(yf), w = fade(zf);
|
|
1779
|
+
const A = p[X] + Y, B = p[X + 1] + Y;
|
|
1780
|
+
const AA = p[A] + Z, AB = p[A + 1] + Z, BA = p[B] + Z, BB = p[B + 1] + Z;
|
|
1781
|
+
return lerp(
|
|
1782
|
+
w,
|
|
1783
|
+
lerp(
|
|
1784
|
+
v,
|
|
1785
|
+
lerp(u, grad3(p[AA], xf, yf, zf), grad3(p[BA], xf - 1, yf, zf)),
|
|
1786
|
+
lerp(u, grad3(p[AB], xf, yf - 1, zf), grad3(p[BB], xf - 1, yf - 1, zf))
|
|
1787
|
+
),
|
|
1788
|
+
lerp(
|
|
1789
|
+
v,
|
|
1790
|
+
lerp(
|
|
1791
|
+
u,
|
|
1792
|
+
grad3(p[AA + 1], xf, yf, zf - 1),
|
|
1793
|
+
grad3(p[BA + 1], xf - 1, yf, zf - 1)
|
|
1881
1794
|
),
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1795
|
+
lerp(
|
|
1796
|
+
u,
|
|
1797
|
+
grad3(p[AB + 1], xf, yf - 1, zf - 1),
|
|
1798
|
+
grad3(p[BB + 1], xf - 1, yf - 1, zf - 1)
|
|
1886
1799
|
)
|
|
1887
|
-
)
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
}
|
|
1800
|
+
)
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
perlin4(x, y, z, w) {
|
|
1804
|
+
const { fade, lerp } = _Noise;
|
|
1805
|
+
const p = this.p;
|
|
1806
|
+
const fx = Math.floor(x), fy = Math.floor(y), fz = Math.floor(z), fw = Math.floor(w);
|
|
1807
|
+
const X = fx & 255, Y = fy & 255, Z = fz & 255, W = fw & 255;
|
|
1808
|
+
const xf = x - fx, yf = y - fy, zf = z - fz, wf = w - fw;
|
|
1809
|
+
const fu = fade(xf), fv = fade(yf), fW = fade(zf), ft = fade(wf);
|
|
1810
|
+
const g = (h2, x2, y2, z2, w2) => {
|
|
1811
|
+
const b = h2 & 31;
|
|
1812
|
+
const u = b < 24 ? x2 : y2;
|
|
1813
|
+
const v = b < 16 ? y2 : z2;
|
|
1814
|
+
const t = b < 8 ? z2 : w2;
|
|
1815
|
+
return ((b & 1) === 0 ? u : -u) + ((b & 2) === 0 ? v : -v) + ((b & 4) === 0 ? t : -t);
|
|
1816
|
+
};
|
|
1817
|
+
const h = (dx, dy, dz, dw) => p[p[p[p[X + dx] + Y + dy] + Z + dz] + W + dw];
|
|
1818
|
+
return lerp(
|
|
1819
|
+
ft,
|
|
1820
|
+
lerp(
|
|
1821
|
+
fW,
|
|
1822
|
+
lerp(
|
|
1823
|
+
fv,
|
|
1824
|
+
lerp(
|
|
1825
|
+
fu,
|
|
1826
|
+
g(h(0, 0, 0, 0), xf, yf, zf, wf),
|
|
1827
|
+
g(h(1, 0, 0, 0), xf - 1, yf, zf, wf)
|
|
1828
|
+
),
|
|
1829
|
+
lerp(
|
|
1830
|
+
fu,
|
|
1831
|
+
g(h(0, 1, 0, 0), xf, yf - 1, zf, wf),
|
|
1832
|
+
g(h(1, 1, 0, 0), xf - 1, yf - 1, zf, wf)
|
|
1833
|
+
)
|
|
1834
|
+
),
|
|
1835
|
+
lerp(
|
|
1836
|
+
fv,
|
|
1837
|
+
lerp(
|
|
1838
|
+
fu,
|
|
1839
|
+
g(h(0, 0, 1, 0), xf, yf, zf - 1, wf),
|
|
1840
|
+
g(h(1, 0, 1, 0), xf - 1, yf, zf - 1, wf)
|
|
1841
|
+
),
|
|
1842
|
+
lerp(
|
|
1843
|
+
fu,
|
|
1844
|
+
g(h(0, 1, 1, 0), xf, yf - 1, zf - 1, wf),
|
|
1845
|
+
g(h(1, 1, 1, 0), xf - 1, yf - 1, zf - 1, wf)
|
|
1846
|
+
)
|
|
1847
|
+
)
|
|
1848
|
+
),
|
|
1849
|
+
lerp(
|
|
1850
|
+
fW,
|
|
1851
|
+
lerp(
|
|
1852
|
+
fv,
|
|
1853
|
+
lerp(
|
|
1854
|
+
fu,
|
|
1855
|
+
g(h(0, 0, 0, 1), xf, yf, zf, wf - 1),
|
|
1856
|
+
g(h(1, 0, 0, 1), xf - 1, yf, zf, wf - 1)
|
|
1857
|
+
),
|
|
1858
|
+
lerp(
|
|
1859
|
+
fu,
|
|
1860
|
+
g(h(0, 1, 0, 1), xf, yf - 1, zf, wf - 1),
|
|
1861
|
+
g(h(1, 1, 0, 1), xf - 1, yf - 1, zf, wf - 1)
|
|
1862
|
+
)
|
|
1863
|
+
),
|
|
1864
|
+
lerp(
|
|
1865
|
+
fv,
|
|
1866
|
+
lerp(
|
|
1867
|
+
fu,
|
|
1868
|
+
g(h(0, 0, 1, 1), xf, yf, zf - 1, wf - 1),
|
|
1869
|
+
g(h(1, 0, 1, 1), xf - 1, yf, zf - 1, wf - 1)
|
|
1870
|
+
),
|
|
1871
|
+
lerp(
|
|
1872
|
+
fu,
|
|
1873
|
+
g(h(0, 1, 1, 1), xf, yf - 1, zf - 1, wf - 1),
|
|
1874
|
+
g(h(1, 1, 1, 1), xf - 1, yf - 1, zf - 1, wf - 1)
|
|
1875
|
+
)
|
|
1876
|
+
)
|
|
1877
|
+
)
|
|
1878
|
+
);
|
|
1892
1879
|
}
|
|
1893
1880
|
simplex(x, y, z, w) {
|
|
1894
|
-
if (y === void 0)
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1881
|
+
if (y === void 0) return this.perlin1(x);
|
|
1882
|
+
if (z === void 0) return this.simplex2(x, y);
|
|
1883
|
+
if (w === void 0) return this.simplex3(x, y, z);
|
|
1884
|
+
return this.simplex4(x, y, z, w);
|
|
1885
|
+
}
|
|
1886
|
+
simplex2(x, y) {
|
|
1887
|
+
const { F2, G2, grad3 } = _Noise;
|
|
1888
|
+
const p = this.p;
|
|
1889
|
+
const s = (x + y) * F2;
|
|
1890
|
+
const i = Math.floor(x + s), j = Math.floor(y + s);
|
|
1891
|
+
const t = (i + j) * G2;
|
|
1892
|
+
const x0 = x - (i - t), y0 = y - (j - t);
|
|
1893
|
+
const i1 = x0 > y0 ? 1 : 0, j1 = x0 > y0 ? 0 : 1;
|
|
1894
|
+
const x1 = x0 - i1 + G2, y1 = y0 - j1 + G2;
|
|
1895
|
+
const x2 = x0 - 1 + 2 * G2, y2 = y0 - 1 + 2 * G2;
|
|
1896
|
+
const ii = i & 255, jj = j & 255;
|
|
1897
|
+
const gi0 = p[ii + p[jj]] % 12;
|
|
1898
|
+
const gi1 = p[ii + i1 + p[jj + j1]] % 12;
|
|
1899
|
+
const gi2 = p[ii + 1 + p[jj + 1]] % 12;
|
|
1900
|
+
let n0 = 0, n1 = 0, n2 = 0;
|
|
1901
|
+
let t0 = 0.5 - x0 * x0 - y0 * y0;
|
|
1902
|
+
if (t0 >= 0) {
|
|
1903
|
+
t0 *= t0;
|
|
1904
|
+
n0 = t0 * t0 * grad3(gi0, x0, y0, 0);
|
|
1905
|
+
}
|
|
1906
|
+
let t1 = 0.5 - x1 * x1 - y1 * y1;
|
|
1907
|
+
if (t1 >= 0) {
|
|
1908
|
+
t1 *= t1;
|
|
1909
|
+
n1 = t1 * t1 * grad3(gi1, x1, y1, 0);
|
|
1910
|
+
}
|
|
1911
|
+
let t2 = 0.5 - x2 * x2 - y2 * y2;
|
|
1912
|
+
if (t2 >= 0) {
|
|
1913
|
+
t2 *= t2;
|
|
1914
|
+
n2 = t2 * t2 * grad3(gi2, x2, y2, 0);
|
|
1915
|
+
}
|
|
1916
|
+
return 70 * (n0 + n1 + n2);
|
|
1917
|
+
}
|
|
1918
|
+
simplex3(x, y, z) {
|
|
1919
|
+
const { F3, G3, grad3 } = _Noise;
|
|
1920
|
+
const p = this.p;
|
|
1921
|
+
const s = (x + y + z) * F3;
|
|
1922
|
+
const i = Math.floor(x + s), j = Math.floor(y + s), k = Math.floor(z + s);
|
|
1923
|
+
const t = (i + j + k) * G3;
|
|
1924
|
+
const x0 = x - (i - t), y0 = y - (j - t), z0 = z - (k - t);
|
|
1925
|
+
let i1, j1, k1;
|
|
1926
|
+
let i2, j2, k2;
|
|
1927
|
+
if (x0 >= y0) {
|
|
1928
|
+
if (y0 >= z0) {
|
|
1929
|
+
i1 = 1;
|
|
1930
|
+
j1 = 0;
|
|
1931
|
+
k1 = 0;
|
|
1932
|
+
i2 = 1;
|
|
1933
|
+
j2 = 1;
|
|
1934
|
+
k2 = 0;
|
|
1935
|
+
} else if (x0 >= z0) {
|
|
1908
1936
|
i1 = 1;
|
|
1909
1937
|
j1 = 0;
|
|
1938
|
+
k1 = 0;
|
|
1939
|
+
i2 = 1;
|
|
1940
|
+
j2 = 0;
|
|
1941
|
+
k2 = 1;
|
|
1910
1942
|
} else {
|
|
1911
1943
|
i1 = 0;
|
|
1912
|
-
j1 =
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
const y2 = y0 - 1 + 2 * this.G2;
|
|
1918
|
-
const ii = i & 255;
|
|
1919
|
-
const jj = j & 255;
|
|
1920
|
-
const gi0 = this.permMod12[ii + this.perm[jj]];
|
|
1921
|
-
const gi1 = this.permMod12[ii + i1 + this.perm[jj + j1]];
|
|
1922
|
-
const gi2 = this.permMod12[ii + 1 + this.perm[jj + 1]];
|
|
1923
|
-
let t0 = 0.5 - x0 * x0 - y0 * y0;
|
|
1924
|
-
if (t0 < 0) {
|
|
1925
|
-
n0 = 0;
|
|
1926
|
-
} else {
|
|
1927
|
-
t0 *= t0;
|
|
1928
|
-
n0 = t0 * t0 * this.dot2(this.grad3[gi0], x0, y0);
|
|
1929
|
-
}
|
|
1930
|
-
let t1 = 0.5 - x1 * x1 - y1 * y1;
|
|
1931
|
-
if (t1 < 0) {
|
|
1932
|
-
n1 = 0;
|
|
1933
|
-
} else {
|
|
1934
|
-
t1 *= t1;
|
|
1935
|
-
n1 = t1 * t1 * this.dot2(this.grad3[gi1], x1, y1);
|
|
1936
|
-
}
|
|
1937
|
-
let t2 = 0.5 - x2 * x2 - y2 * y2;
|
|
1938
|
-
if (t2 < 0) {
|
|
1939
|
-
n2 = 0;
|
|
1940
|
-
} else {
|
|
1941
|
-
t2 *= t2;
|
|
1942
|
-
n2 = t2 * t2 * this.dot2(this.grad3[gi2], x2, y2);
|
|
1943
|
-
}
|
|
1944
|
-
return 70 * (n0 + n1 + n2);
|
|
1945
|
-
} else if (w === void 0) {
|
|
1946
|
-
let n0 = 0, n1 = 0, n2 = 0, n3 = 0;
|
|
1947
|
-
const s = (x + y + z) * this.F3;
|
|
1948
|
-
const i = Math.floor(x + s);
|
|
1949
|
-
const j = Math.floor(y + s);
|
|
1950
|
-
const k = Math.floor(z + s);
|
|
1951
|
-
const t = (i + j + k) * this.G3;
|
|
1952
|
-
const X0 = i - t;
|
|
1953
|
-
const Y0 = j - t;
|
|
1954
|
-
const Z0 = k - t;
|
|
1955
|
-
const x0 = x - X0;
|
|
1956
|
-
const y0 = y - Y0;
|
|
1957
|
-
const z0 = z - Z0;
|
|
1958
|
-
let i1, j1, k1;
|
|
1959
|
-
let i2, j2, k2;
|
|
1960
|
-
if (x0 >= y0) {
|
|
1961
|
-
if (y0 >= z0) {
|
|
1962
|
-
i1 = 1;
|
|
1963
|
-
j1 = 0;
|
|
1964
|
-
k1 = 0;
|
|
1965
|
-
i2 = 1;
|
|
1966
|
-
j2 = 1;
|
|
1967
|
-
k2 = 0;
|
|
1968
|
-
} else if (x0 >= z0) {
|
|
1969
|
-
i1 = 1;
|
|
1970
|
-
j1 = 0;
|
|
1971
|
-
k1 = 0;
|
|
1972
|
-
i2 = 1;
|
|
1973
|
-
j2 = 0;
|
|
1974
|
-
k2 = 1;
|
|
1975
|
-
} else {
|
|
1976
|
-
i1 = 0;
|
|
1977
|
-
j1 = 0;
|
|
1978
|
-
k1 = 1;
|
|
1979
|
-
i2 = 1;
|
|
1980
|
-
j2 = 0;
|
|
1981
|
-
k2 = 1;
|
|
1982
|
-
}
|
|
1983
|
-
} else {
|
|
1984
|
-
if (y0 < z0) {
|
|
1985
|
-
i1 = 0;
|
|
1986
|
-
j1 = 0;
|
|
1987
|
-
k1 = 1;
|
|
1988
|
-
i2 = 0;
|
|
1989
|
-
j2 = 1;
|
|
1990
|
-
k2 = 1;
|
|
1991
|
-
} else if (x0 < z0) {
|
|
1992
|
-
i1 = 0;
|
|
1993
|
-
j1 = 1;
|
|
1994
|
-
k1 = 0;
|
|
1995
|
-
i2 = 0;
|
|
1996
|
-
j2 = 1;
|
|
1997
|
-
k2 = 1;
|
|
1998
|
-
} else {
|
|
1999
|
-
i1 = 0;
|
|
2000
|
-
j1 = 1;
|
|
2001
|
-
k1 = 0;
|
|
2002
|
-
i2 = 1;
|
|
2003
|
-
j2 = 1;
|
|
2004
|
-
k2 = 0;
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
|
-
const x1 = x0 - i1 + this.G3;
|
|
2008
|
-
const y1 = y0 - j1 + this.G3;
|
|
2009
|
-
const z1 = z0 - k1 + this.G3;
|
|
2010
|
-
const x2 = x0 - i2 + 2 * this.G3;
|
|
2011
|
-
const y2 = y0 - j2 + 2 * this.G3;
|
|
2012
|
-
const z2 = z0 - k2 + 2 * this.G3;
|
|
2013
|
-
const x3 = x0 - 1 + 3 * this.G3;
|
|
2014
|
-
const y3 = y0 - 1 + 3 * this.G3;
|
|
2015
|
-
const z3 = z0 - 1 + 3 * this.G3;
|
|
2016
|
-
const ii = i & 255;
|
|
2017
|
-
const jj = j & 255;
|
|
2018
|
-
const kk = k & 255;
|
|
2019
|
-
const gi0 = this.permMod12[ii + this.perm[jj + this.perm[kk]]];
|
|
2020
|
-
const gi1 = this.permMod12[ii + i1 + this.perm[jj + j1 + this.perm[kk + k1]]];
|
|
2021
|
-
const gi2 = this.permMod12[ii + i2 + this.perm[jj + j2 + this.perm[kk + k2]]];
|
|
2022
|
-
const gi3 = this.permMod12[ii + 1 + this.perm[jj + 1 + this.perm[kk + 1]]];
|
|
2023
|
-
let t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
|
|
2024
|
-
if (t0 < 0) {
|
|
2025
|
-
n0 = 0;
|
|
2026
|
-
} else {
|
|
2027
|
-
t0 *= t0;
|
|
2028
|
-
n0 = t0 * t0 * this.dot3(this.grad3[gi0], x0, y0, z0);
|
|
2029
|
-
}
|
|
2030
|
-
let t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
|
|
2031
|
-
if (t1 < 0) {
|
|
2032
|
-
n1 = 0;
|
|
2033
|
-
} else {
|
|
2034
|
-
t1 *= t1;
|
|
2035
|
-
n1 = t1 * t1 * this.dot3(this.grad3[gi1], x1, y1, z1);
|
|
1944
|
+
j1 = 0;
|
|
1945
|
+
k1 = 1;
|
|
1946
|
+
i2 = 1;
|
|
1947
|
+
j2 = 0;
|
|
1948
|
+
k2 = 1;
|
|
2036
1949
|
}
|
|
2037
|
-
|
|
2038
|
-
if (
|
|
2039
|
-
|
|
1950
|
+
} else {
|
|
1951
|
+
if (y0 < z0) {
|
|
1952
|
+
i1 = 0;
|
|
1953
|
+
j1 = 0;
|
|
1954
|
+
k1 = 1;
|
|
1955
|
+
i2 = 0;
|
|
1956
|
+
j2 = 1;
|
|
1957
|
+
k2 = 1;
|
|
1958
|
+
} else if (x0 < z0) {
|
|
1959
|
+
i1 = 0;
|
|
1960
|
+
j1 = 1;
|
|
1961
|
+
k1 = 0;
|
|
1962
|
+
i2 = 0;
|
|
1963
|
+
j2 = 1;
|
|
1964
|
+
k2 = 1;
|
|
2040
1965
|
} else {
|
|
2041
|
-
|
|
2042
|
-
|
|
1966
|
+
i1 = 0;
|
|
1967
|
+
j1 = 1;
|
|
1968
|
+
k1 = 0;
|
|
1969
|
+
i2 = 1;
|
|
1970
|
+
j2 = 1;
|
|
1971
|
+
k2 = 0;
|
|
2043
1972
|
}
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
1973
|
+
}
|
|
1974
|
+
const x1 = x0 - i1 + G3, y1 = y0 - j1 + G3, z1 = z0 - k1 + G3;
|
|
1975
|
+
const x2 = x0 - i2 + 2 * G3, y2 = y0 - j2 + 2 * G3, z2 = z0 - k2 + 2 * G3;
|
|
1976
|
+
const x3 = x0 - 1 + 3 * G3, y3 = y0 - 1 + 3 * G3, z3 = z0 - 1 + 3 * G3;
|
|
1977
|
+
const ii = i & 255, jj = j & 255, kk = k & 255;
|
|
1978
|
+
const gi0 = p[ii + p[jj + p[kk]]] % 12;
|
|
1979
|
+
const gi1 = p[ii + i1 + p[jj + j1 + p[kk + k1]]] % 12;
|
|
1980
|
+
const gi2 = p[ii + i2 + p[jj + j2 + p[kk + k2]]] % 12;
|
|
1981
|
+
const gi3 = p[ii + 1 + p[jj + 1 + p[kk + 1]]] % 12;
|
|
1982
|
+
let n = 0;
|
|
1983
|
+
let tc = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
|
|
1984
|
+
if (tc >= 0) {
|
|
1985
|
+
tc *= tc;
|
|
1986
|
+
n += tc * tc * grad3(gi0, x0, y0, z0);
|
|
1987
|
+
}
|
|
1988
|
+
tc = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
|
|
1989
|
+
if (tc >= 0) {
|
|
1990
|
+
tc *= tc;
|
|
1991
|
+
n += tc * tc * grad3(gi1, x1, y1, z1);
|
|
1992
|
+
}
|
|
1993
|
+
tc = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
|
|
1994
|
+
if (tc >= 0) {
|
|
1995
|
+
tc *= tc;
|
|
1996
|
+
n += tc * tc * grad3(gi2, x2, y2, z2);
|
|
1997
|
+
}
|
|
1998
|
+
tc = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
|
|
1999
|
+
if (tc >= 0) {
|
|
2000
|
+
tc *= tc;
|
|
2001
|
+
n += tc * tc * grad3(gi3, x3, y3, z3);
|
|
2002
|
+
}
|
|
2003
|
+
return 32 * n;
|
|
2004
|
+
}
|
|
2005
|
+
simplex4(x, y, z, w) {
|
|
2006
|
+
const { F4, G4 } = _Noise;
|
|
2007
|
+
const p = this.p;
|
|
2008
|
+
const s = (x + y + z + w) * F4;
|
|
2009
|
+
const i = Math.floor(x + s), j = Math.floor(y + s), k = Math.floor(z + s), l = Math.floor(w + s);
|
|
2010
|
+
const t = (i + j + k + l) * G4;
|
|
2011
|
+
const x0 = x - (i - t), y0 = y - (j - t), z0 = z - (k - t), w0 = w - (l - t);
|
|
2012
|
+
let rx = 0, ry = 0, rz = 0, rw = 0;
|
|
2013
|
+
if (x0 > y0) rx++;
|
|
2014
|
+
else ry++;
|
|
2015
|
+
if (x0 > z0) rx++;
|
|
2016
|
+
else rz++;
|
|
2017
|
+
if (x0 > w0) rx++;
|
|
2018
|
+
else rw++;
|
|
2019
|
+
if (y0 > z0) ry++;
|
|
2020
|
+
else rz++;
|
|
2021
|
+
if (y0 > w0) ry++;
|
|
2022
|
+
else rw++;
|
|
2023
|
+
if (z0 > w0) rz++;
|
|
2024
|
+
else rw++;
|
|
2025
|
+
const i1 = +(rx >= 3), j1 = +(ry >= 3), k1 = +(rz >= 3), l1 = +(rw >= 3);
|
|
2026
|
+
const i2 = +(rx >= 2), j2 = +(ry >= 2), k2 = +(rz >= 2), l2 = +(rw >= 2);
|
|
2027
|
+
const i3 = +(rx >= 1), j3 = +(ry >= 1), k3 = +(rz >= 1), l3 = +(rw >= 1);
|
|
2028
|
+
const x1 = x0 - i1 + G4, y1 = y0 - j1 + G4, z1 = z0 - k1 + G4, w1 = w0 - l1 + G4;
|
|
2029
|
+
const x2 = x0 - i2 + 2 * G4, y2 = y0 - j2 + 2 * G4, z2 = z0 - k2 + 2 * G4, w2 = w0 - l2 + 2 * G4;
|
|
2030
|
+
const x3 = x0 - i3 + 3 * G4, y3 = y0 - j3 + 3 * G4, z3 = z0 - k3 + 3 * G4, w3 = w0 - l3 + 3 * G4;
|
|
2031
|
+
const x4 = x0 - 1 + 4 * G4, y4 = y0 - 1 + 4 * G4, z4 = z0 - 1 + 4 * G4, w4 = w0 - 1 + 4 * G4;
|
|
2032
|
+
const ii = i & 255, jj = j & 255, kk = k & 255, ll = l & 255;
|
|
2033
|
+
const g4 = (gi, x5, y5, z5, w5) => {
|
|
2034
|
+
const g = gi >> 3;
|
|
2035
|
+
const b = gi & 7;
|
|
2036
|
+
let a, c, d;
|
|
2037
|
+
if (g === 0) {
|
|
2038
|
+
a = y5;
|
|
2039
|
+
c = z5;
|
|
2040
|
+
d = w5;
|
|
2041
|
+
} else if (g === 1) {
|
|
2042
|
+
a = x5;
|
|
2043
|
+
c = z5;
|
|
2044
|
+
d = w5;
|
|
2045
|
+
} else if (g === 2) {
|
|
2046
|
+
a = x5;
|
|
2047
|
+
c = y5;
|
|
2048
|
+
d = w5;
|
|
2047
2049
|
} else {
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
+
a = x5;
|
|
2051
|
+
c = y5;
|
|
2052
|
+
d = z5;
|
|
2050
2053
|
}
|
|
2051
|
-
return
|
|
2052
|
-
}
|
|
2053
|
-
|
|
2054
|
+
return (b & 4 ? -a : a) + (b & 2 ? -c : c) + (b & 1 ? -d : d);
|
|
2055
|
+
};
|
|
2056
|
+
const gi0 = p[ii + p[jj + p[kk + p[ll]]]] & 31;
|
|
2057
|
+
const gi1 = p[ii + i1 + p[jj + j1 + p[kk + k1 + p[ll + l1]]]] & 31;
|
|
2058
|
+
const gi2 = p[ii + i2 + p[jj + j2 + p[kk + k2 + p[ll + l2]]]] & 31;
|
|
2059
|
+
const gi3 = p[ii + i3 + p[jj + j3 + p[kk + k3 + p[ll + l3]]]] & 31;
|
|
2060
|
+
const gi4 = p[ii + 1 + p[jj + 1 + p[kk + 1 + p[ll + 1]]]] & 31;
|
|
2061
|
+
let n = 0;
|
|
2062
|
+
let tc = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
|
|
2063
|
+
if (tc >= 0) {
|
|
2064
|
+
tc *= tc;
|
|
2065
|
+
n += tc * tc * g4(gi0, x0, y0, z0, w0);
|
|
2054
2066
|
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
+
tc = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
|
|
2068
|
+
if (tc >= 0) {
|
|
2069
|
+
tc *= tc;
|
|
2070
|
+
n += tc * tc * g4(gi1, x1, y1, z1, w1);
|
|
2071
|
+
}
|
|
2072
|
+
tc = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
|
|
2073
|
+
if (tc >= 0) {
|
|
2074
|
+
tc *= tc;
|
|
2075
|
+
n += tc * tc * g4(gi2, x2, y2, z2, w2);
|
|
2076
|
+
}
|
|
2077
|
+
tc = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
|
|
2078
|
+
if (tc >= 0) {
|
|
2079
|
+
tc *= tc;
|
|
2080
|
+
n += tc * tc * g4(gi3, x3, y3, z3, w3);
|
|
2081
|
+
}
|
|
2082
|
+
tc = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
|
|
2083
|
+
if (tc >= 0) {
|
|
2084
|
+
tc *= tc;
|
|
2085
|
+
n += tc * tc * g4(gi4, x4, y4, z4, w4);
|
|
2086
|
+
}
|
|
2087
|
+
return 27 * n;
|
|
2067
2088
|
}
|
|
2068
2089
|
hash(x, y, z, w) {
|
|
2069
|
-
let n
|
|
2090
|
+
let n;
|
|
2070
2091
|
if (y === void 0) {
|
|
2071
|
-
n = Math.sin(x * 12.9898 + this.
|
|
2092
|
+
n = Math.sin(x * 12.9898 + this._seed) * 43758.5453;
|
|
2072
2093
|
} else if (z === void 0) {
|
|
2073
|
-
n = Math.sin(x * 12.9898 + y * 78.233 + this.
|
|
2094
|
+
n = Math.sin(x * 12.9898 + y * 78.233 + this._seed) * 43758.5453;
|
|
2074
2095
|
} else if (w === void 0) {
|
|
2075
|
-
n = Math.sin(x * 12.9898 + y * 78.233 + z * 37.719 + this.
|
|
2096
|
+
n = Math.sin(x * 12.9898 + y * 78.233 + z * 37.719 + this._seed) * 43758.5453;
|
|
2076
2097
|
} else {
|
|
2077
|
-
n = Math.sin(
|
|
2098
|
+
n = Math.sin(
|
|
2099
|
+
x * 12.9898 + y * 78.233 + z * 37.719 + w * 53.137 + this._seed
|
|
2100
|
+
) * 43758.5453;
|
|
2078
2101
|
}
|
|
2079
2102
|
return n - Math.floor(n);
|
|
2080
2103
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
let zVal = void 0;
|
|
2088
|
-
let opts = typeof y === "object" ? y : typeof z === "object" ? z : {};
|
|
2089
|
-
if (typeof y === "number") yVal = y;
|
|
2090
|
-
if (typeof z === "number") zVal = z;
|
|
2091
|
-
if (options) opts = { ...opts, ...options };
|
|
2092
|
-
const octaves = opts.octaves ?? 4;
|
|
2093
|
-
if (octaves <= 0) return 0;
|
|
2094
|
-
let amplitude = opts.amplitude ?? 1;
|
|
2095
|
-
let frequency = opts.frequency ?? 1;
|
|
2096
|
-
const lacunarity = opts.lacunarity ?? 2;
|
|
2097
|
-
const gain = opts.gain ?? 0.5;
|
|
2098
|
-
let value = 0;
|
|
2099
|
-
let maxValue = 0;
|
|
2100
|
-
for (let i = 0; i < octaves; i++) {
|
|
2101
|
-
if (yVal === void 0) {
|
|
2102
|
-
value += amplitude * this.perlin(x * frequency);
|
|
2103
|
-
} else if (zVal === void 0) {
|
|
2104
|
-
value += amplitude * this.perlin(x * frequency, yVal * frequency);
|
|
2105
|
-
} else {
|
|
2106
|
-
value += amplitude * this.perlin(x * frequency, yVal * frequency, zVal * frequency);
|
|
2107
|
-
}
|
|
2108
|
-
maxValue += amplitude;
|
|
2109
|
-
amplitude *= gain;
|
|
2110
|
-
frequency *= lacunarity;
|
|
2111
|
-
}
|
|
2112
|
-
return maxValue === 0 ? 0 : value / maxValue;
|
|
2113
|
-
}
|
|
2114
|
-
/**
|
|
2115
|
-
* Turbulence noise (absolute value of noise)
|
|
2116
|
-
* Supports options object for octaves.
|
|
2117
|
-
*/
|
|
2118
|
-
turbulence(x, y, z, options) {
|
|
2119
|
-
let yVal = void 0;
|
|
2120
|
-
let zVal = void 0;
|
|
2121
|
-
let opts = typeof y === "object" ? y : typeof z === "object" ? z : {};
|
|
2122
|
-
if (typeof y === "number") yVal = y;
|
|
2123
|
-
if (typeof z === "number") zVal = z;
|
|
2124
|
-
if (options) opts = { ...opts, ...options };
|
|
2125
|
-
const octaves = opts.octaves ?? 4;
|
|
2126
|
-
if (octaves <= 0) return 0;
|
|
2127
|
-
let value = 0;
|
|
2128
|
-
let amplitude = 1;
|
|
2129
|
-
let frequency = 1;
|
|
2130
|
-
let maxValue = 0;
|
|
2131
|
-
for (let i = 0; i < octaves; i++) {
|
|
2132
|
-
let noise = 0;
|
|
2133
|
-
if (yVal === void 0) {
|
|
2134
|
-
noise = this.perlin(x * frequency);
|
|
2135
|
-
} else if (zVal === void 0) {
|
|
2136
|
-
noise = this.perlin(x * frequency, yVal * frequency);
|
|
2137
|
-
} else {
|
|
2138
|
-
noise = this.perlin(x * frequency, yVal * frequency, zVal * frequency);
|
|
2139
|
-
}
|
|
2140
|
-
value += amplitude * Math.abs(noise);
|
|
2141
|
-
maxValue += amplitude;
|
|
2142
|
-
amplitude *= 0.5;
|
|
2143
|
-
frequency *= 2;
|
|
2144
|
-
}
|
|
2145
|
-
return maxValue === 0 ? 0 : value / maxValue;
|
|
2146
|
-
}
|
|
2147
|
-
/**
|
|
2148
|
-
* Ridged multifractal noise (simple implementation)
|
|
2149
|
-
*/
|
|
2150
|
-
ridge(x, y, options) {
|
|
2151
|
-
let yVal = void 0;
|
|
2152
|
-
let opts = typeof y === "object" ? y : {};
|
|
2153
|
-
if (typeof y === "number") yVal = y;
|
|
2154
|
-
if (options) opts = { ...opts, ...options };
|
|
2155
|
-
const octaves = opts.octaves ?? 4;
|
|
2156
|
-
if (octaves <= 0) return 0;
|
|
2157
|
-
let amplitude = opts.amplitude ?? 1;
|
|
2158
|
-
let frequency = opts.frequency ?? 1;
|
|
2159
|
-
const lacunarity = opts.lacunarity ?? 2;
|
|
2160
|
-
const gain = opts.gain ?? 0.5;
|
|
2161
|
-
let value = 0;
|
|
2162
|
-
let weight = 1;
|
|
2163
|
-
let maxValue = 0;
|
|
2164
|
-
for (let i = 0; i < octaves; i++) {
|
|
2165
|
-
const n = yVal === void 0 ? this.perlin(x * frequency) : this.perlin(x * frequency, yVal * frequency);
|
|
2166
|
-
let signal = 1 - Math.abs(n);
|
|
2167
|
-
signal *= signal;
|
|
2168
|
-
signal *= weight;
|
|
2169
|
-
weight = signal * 2;
|
|
2170
|
-
weight = Math.min(Math.max(weight, 0), 1);
|
|
2171
|
-
value += signal * amplitude;
|
|
2172
|
-
maxValue += amplitude;
|
|
2173
|
-
amplitude *= gain;
|
|
2174
|
-
frequency *= lacunarity;
|
|
2175
|
-
}
|
|
2176
|
-
return maxValue === 0 ? 0 : value / maxValue;
|
|
2177
|
-
}
|
|
2178
|
-
/**
|
|
2179
|
-
* Cellular / Worley noise (2D simple implementation)
|
|
2180
|
-
*/
|
|
2181
|
-
cellular(x, y, options) {
|
|
2182
|
-
let yVal = void 0;
|
|
2183
|
-
let opts = typeof y === "object" ? y : {};
|
|
2184
|
-
if (typeof y === "number") yVal = y;
|
|
2185
|
-
if (options) opts = { ...opts, ...options };
|
|
2186
|
-
if (yVal === void 0) yVal = 0;
|
|
2187
|
-
const xi = Math.floor(x);
|
|
2188
|
-
const yi = Math.floor(yVal);
|
|
2189
|
-
const distance = opts.distance ?? "euclidean";
|
|
2190
|
-
let minDist = Infinity;
|
|
2191
|
-
for (let j = -1; j <= 1; j++) {
|
|
2192
|
-
for (let i = -1; i <= 1; i++) {
|
|
2193
|
-
const fx = i + this.hash(xi + i, yi + j);
|
|
2194
|
-
const fy = j + this.hash(yi + j, xi + i);
|
|
2195
|
-
const dx = fx + xi - x;
|
|
2196
|
-
const dy = fy + yi - yVal;
|
|
2197
|
-
const dist = distance === "manhattan" ? Math.abs(dx) + Math.abs(dy) : Math.sqrt(dx * dx + dy * dy);
|
|
2198
|
-
if (dist < minDist) minDist = dist;
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
const maxDist = Math.SQRT2;
|
|
2202
|
-
const normalized = 1 - Math.min(minDist / maxDist, 1);
|
|
2203
|
-
return normalized;
|
|
2104
|
+
// ---- GAUSSIAN RANDOM ----
|
|
2105
|
+
/** Box-Muller transform — returns normally distributed random number (seeded) */
|
|
2106
|
+
gaussianRandom(mean = 0, stddev = 1) {
|
|
2107
|
+
const u1 = 1 - this.rng();
|
|
2108
|
+
const u2 = this.rng();
|
|
2109
|
+
return mean + stddev * Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
2204
2110
|
}
|
|
2205
2111
|
};
|
|
2112
|
+
_Noise.F2 = (Math.sqrt(3) - 1) / 2;
|
|
2113
|
+
_Noise.G2 = (3 - Math.sqrt(3)) / 6;
|
|
2114
|
+
_Noise.F3 = 1 / 3;
|
|
2115
|
+
_Noise.G3 = 1 / 6;
|
|
2116
|
+
_Noise.F4 = (Math.sqrt(5) - 1) / 4;
|
|
2117
|
+
_Noise.G4 = (5 - Math.sqrt(5)) / 20;
|
|
2118
|
+
var Noise = _Noise;
|
|
2206
2119
|
var Noise_default = Noise;
|
|
2207
2120
|
|
|
2208
2121
|
// src/elements/Hotspot.tsx
|
|
@@ -2299,349 +2212,385 @@ var Hotspot = class {
|
|
|
2299
2212
|
};
|
|
2300
2213
|
var Hotspot_default = Hotspot;
|
|
2301
2214
|
|
|
2302
|
-
// src/elements/
|
|
2303
|
-
var
|
|
2304
|
-
constructor(
|
|
2305
|
-
this.
|
|
2306
|
-
this.
|
|
2307
|
-
this.
|
|
2308
|
-
this.
|
|
2215
|
+
// src/elements/Quadtree.tsx
|
|
2216
|
+
var Rectangle = class {
|
|
2217
|
+
constructor(x, y, w, h) {
|
|
2218
|
+
this.x = x;
|
|
2219
|
+
this.y = y;
|
|
2220
|
+
this.w = w;
|
|
2221
|
+
this.h = h;
|
|
2309
2222
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
*/
|
|
2313
|
-
batchDraw(drawFn) {
|
|
2314
|
-
this.context.save();
|
|
2315
|
-
this.context.beginPath();
|
|
2316
|
-
try {
|
|
2317
|
-
drawFn();
|
|
2318
|
-
} finally {
|
|
2319
|
-
this.context.restore();
|
|
2320
|
-
}
|
|
2223
|
+
contains(point) {
|
|
2224
|
+
return point.x >= this.x - this.w && point.x < this.x + this.w && point.y >= this.y - this.h && point.y < this.y + this.h;
|
|
2321
2225
|
}
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
*/
|
|
2325
|
-
useOffscreenCache(id, width, height, renderFn) {
|
|
2326
|
-
let offscreen = this.context.__offscreens.get(id);
|
|
2327
|
-
if (!offscreen || offscreen instanceof HTMLImageElement) {
|
|
2328
|
-
offscreen = this.context.createOffscreen(id, width, height);
|
|
2329
|
-
if (offscreen && !(offscreen instanceof HTMLImageElement)) {
|
|
2330
|
-
renderFn(offscreen);
|
|
2331
|
-
}
|
|
2332
|
-
}
|
|
2333
|
-
if (offscreen) {
|
|
2334
|
-
if (offscreen instanceof HTMLImageElement) {
|
|
2335
|
-
this.context.image(offscreen, 0, 0);
|
|
2336
|
-
} else {
|
|
2337
|
-
this.context.image(offscreen.canvas, 0, 0);
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2226
|
+
intersects(range) {
|
|
2227
|
+
return !(range.x - range.w > this.x + this.w || range.x + range.w < this.x - this.w || range.y - range.h > this.y + this.h || range.y + range.h < this.y - this.h);
|
|
2340
2228
|
}
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
if (!cached || this.context.frame % interval === 0) {
|
|
2348
|
-
const result = fn();
|
|
2349
|
-
this.context[cacheKey] = { value: result, frame: this.context.frame };
|
|
2350
|
-
return result;
|
|
2351
|
-
}
|
|
2352
|
-
return cached.value;
|
|
2229
|
+
intersectsCircle(cx, cy, r) {
|
|
2230
|
+
const dx = Math.abs(cx - this.x);
|
|
2231
|
+
const dy = Math.abs(cy - this.y);
|
|
2232
|
+
if (dx > this.w + r || dy > this.h + r) return false;
|
|
2233
|
+
if (dx <= this.w || dy <= this.h) return true;
|
|
2234
|
+
return (dx - this.w) ** 2 + (dy - this.h) ** 2 <= r * r;
|
|
2353
2235
|
}
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
}
|
|
2381
|
-
};
|
|
2236
|
+
};
|
|
2237
|
+
var Quadtree = class _Quadtree {
|
|
2238
|
+
constructor(boundary, capacity = 4, maxDepth = 8, depth = 0) {
|
|
2239
|
+
this.ne = null;
|
|
2240
|
+
this.nw = null;
|
|
2241
|
+
this.se = null;
|
|
2242
|
+
this.sw = null;
|
|
2243
|
+
this.boundary = boundary;
|
|
2244
|
+
this.capacity = capacity;
|
|
2245
|
+
this.maxDepth = maxDepth;
|
|
2246
|
+
this.depth = depth;
|
|
2247
|
+
this.points = [];
|
|
2248
|
+
this.divided = false;
|
|
2249
|
+
}
|
|
2250
|
+
/**
|
|
2251
|
+
* Create a Quadtree from corner-based bounds (top-left + size).
|
|
2252
|
+
* Internally converts to center-based representation.
|
|
2253
|
+
*/
|
|
2254
|
+
static create(x, y, width, height, options) {
|
|
2255
|
+
const hw = width / 2;
|
|
2256
|
+
const hh = height / 2;
|
|
2257
|
+
return new _Quadtree(
|
|
2258
|
+
new Rectangle(x + hw, y + hh, hw, hh),
|
|
2259
|
+
options?.capacity ?? 4,
|
|
2260
|
+
options?.maxDepth ?? 8
|
|
2261
|
+
);
|
|
2382
2262
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
this.context.save();
|
|
2390
|
-
this.context.font = font;
|
|
2391
|
-
const metrics = this.context.measureText(text);
|
|
2392
|
-
this.context.restore();
|
|
2393
|
-
this.textMetricsCache.set(cacheKey, metrics);
|
|
2394
|
-
if (this.textMetricsCache.size > 1e3) {
|
|
2395
|
-
const firstKey = this.textMetricsCache.keys().next().value;
|
|
2396
|
-
if (firstKey) this.textMetricsCache.delete(firstKey);
|
|
2263
|
+
insert(point) {
|
|
2264
|
+
if (!this.boundary.contains(point)) return false;
|
|
2265
|
+
if (!this.divided) {
|
|
2266
|
+
if (this.points.length < this.capacity || this.depth >= this.maxDepth) {
|
|
2267
|
+
this.points.push(point);
|
|
2268
|
+
return true;
|
|
2397
2269
|
}
|
|
2270
|
+
this.subdivide();
|
|
2271
|
+
}
|
|
2272
|
+
return this.ne.insert(point) || this.nw.insert(point) || this.se.insert(point) || this.sw.insert(point);
|
|
2273
|
+
}
|
|
2274
|
+
subdivide() {
|
|
2275
|
+
const { x, y, w, h } = this.boundary;
|
|
2276
|
+
const hw = w / 2;
|
|
2277
|
+
const hh = h / 2;
|
|
2278
|
+
const d = this.depth + 1;
|
|
2279
|
+
this.ne = new _Quadtree(
|
|
2280
|
+
new Rectangle(x + hw, y - hh, hw, hh),
|
|
2281
|
+
this.capacity,
|
|
2282
|
+
this.maxDepth,
|
|
2283
|
+
d
|
|
2284
|
+
);
|
|
2285
|
+
this.nw = new _Quadtree(
|
|
2286
|
+
new Rectangle(x - hw, y - hh, hw, hh),
|
|
2287
|
+
this.capacity,
|
|
2288
|
+
this.maxDepth,
|
|
2289
|
+
d
|
|
2290
|
+
);
|
|
2291
|
+
this.se = new _Quadtree(
|
|
2292
|
+
new Rectangle(x + hw, y + hh, hw, hh),
|
|
2293
|
+
this.capacity,
|
|
2294
|
+
this.maxDepth,
|
|
2295
|
+
d
|
|
2296
|
+
);
|
|
2297
|
+
this.sw = new _Quadtree(
|
|
2298
|
+
new Rectangle(x - hw, y + hh, hw, hh),
|
|
2299
|
+
this.capacity,
|
|
2300
|
+
this.maxDepth,
|
|
2301
|
+
d
|
|
2302
|
+
);
|
|
2303
|
+
this.divided = true;
|
|
2304
|
+
for (const p of this.points) {
|
|
2305
|
+
this.ne.insert(p) || this.nw.insert(p) || this.se.insert(p) || this.sw.insert(p);
|
|
2398
2306
|
}
|
|
2399
|
-
|
|
2400
|
-
}
|
|
2401
|
-
/**
|
|
2402
|
-
* Clear all performance caches
|
|
2403
|
-
*/
|
|
2404
|
-
clearCaches() {
|
|
2405
|
-
this.textMetricsCache.clear();
|
|
2406
|
-
}
|
|
2407
|
-
/**
|
|
2408
|
-
* Get current performance metrics
|
|
2409
|
-
*/
|
|
2410
|
-
getMetrics() {
|
|
2411
|
-
return this.context.__performance || null;
|
|
2307
|
+
this.points = [];
|
|
2412
2308
|
}
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
const metrics = this.getMetrics();
|
|
2418
|
-
if (!metrics) return;
|
|
2419
|
-
const {
|
|
2420
|
-
x = 10,
|
|
2421
|
-
y = 10,
|
|
2422
|
-
width = 200,
|
|
2423
|
-
height = 120,
|
|
2424
|
-
backgroundColor = "rgba(0, 0, 0, 0.8)",
|
|
2425
|
-
textColor = "#ffffff",
|
|
2426
|
-
accentColor = "#4ecdc4",
|
|
2427
|
-
showGraph = true,
|
|
2428
|
-
graphHeight = 40,
|
|
2429
|
-
fontSize = 12,
|
|
2430
|
-
showMemory = true
|
|
2431
|
-
} = options;
|
|
2432
|
-
if (showGraph) {
|
|
2433
|
-
this.frameTimeHistory.push(metrics.frameTime);
|
|
2434
|
-
if (this.frameTimeHistory.length > this.MAX_HISTORY) {
|
|
2435
|
-
this.frameTimeHistory.shift();
|
|
2436
|
-
}
|
|
2309
|
+
query(range, found = []) {
|
|
2310
|
+
if (!this.boundary.intersects(range)) return found;
|
|
2311
|
+
for (const p of this.points) {
|
|
2312
|
+
if (range.contains(p)) found.push(p);
|
|
2437
2313
|
}
|
|
2438
|
-
this.
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
this.context.strokeRect(x, y, width, height);
|
|
2444
|
-
this.context.fillStyle = textColor;
|
|
2445
|
-
this.context.font = `${fontSize}px monospace`;
|
|
2446
|
-
this.context.textAlign = "left";
|
|
2447
|
-
this.context.textBaseline = "top";
|
|
2448
|
-
let currentY = y + 8;
|
|
2449
|
-
const fpsColor = metrics.fps >= 55 ? "#4ecdc4" : metrics.fps >= 30 ? "#ffd93d" : "#ff6b6b";
|
|
2450
|
-
this.context.fillStyle = fpsColor;
|
|
2451
|
-
this.context.fillText(`FPS: ${metrics.fps}`, x + 8, currentY);
|
|
2452
|
-
currentY += fontSize + 4;
|
|
2453
|
-
this.context.fillStyle = textColor;
|
|
2454
|
-
this.context.fillText(`Frame: ${metrics.frameTime.toFixed(2)}ms`, x + 8, currentY);
|
|
2455
|
-
currentY += fontSize + 4;
|
|
2456
|
-
this.context.fillText(`Avg: ${metrics.averageFrameTime.toFixed(2)}ms`, x + 8, currentY);
|
|
2457
|
-
currentY += fontSize + 4;
|
|
2458
|
-
this.context.fillText(
|
|
2459
|
-
`Min: ${metrics.minFrameTime.toFixed(2)}ms / Max: ${metrics.maxFrameTime.toFixed(2)}ms`,
|
|
2460
|
-
x + 8,
|
|
2461
|
-
currentY
|
|
2462
|
-
);
|
|
2463
|
-
currentY += fontSize + 4;
|
|
2464
|
-
if (metrics.droppedFrames > 0) {
|
|
2465
|
-
this.context.fillStyle = "#ff6b6b";
|
|
2466
|
-
this.context.fillText(`Dropped: ${metrics.droppedFrames}`, x + 8, currentY);
|
|
2467
|
-
currentY += fontSize + 4;
|
|
2314
|
+
if (this.divided) {
|
|
2315
|
+
this.ne.query(range, found);
|
|
2316
|
+
this.nw.query(range, found);
|
|
2317
|
+
this.se.query(range, found);
|
|
2318
|
+
this.sw.query(range, found);
|
|
2468
2319
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2320
|
+
return found;
|
|
2321
|
+
}
|
|
2322
|
+
queryRadius(cx, cy, radius, found = []) {
|
|
2323
|
+
if (!this.boundary.intersectsCircle(cx, cy, radius)) return found;
|
|
2324
|
+
const rSq = radius * radius;
|
|
2325
|
+
for (const p of this.points) {
|
|
2326
|
+
if ((p.x - cx) ** 2 + (p.y - cy) ** 2 <= rSq) found.push(p);
|
|
2473
2327
|
}
|
|
2474
|
-
if (
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
this.context.fillStyle = "rgba(255, 255, 255, 0.1)";
|
|
2480
|
-
this.context.fillRect(graphX, graphY, graphWidth, graphHeight);
|
|
2481
|
-
const targetY = graphY + graphHeight - targetFrameTime / (targetFrameTime * 2) * graphHeight;
|
|
2482
|
-
this.context.strokeStyle = "rgba(255, 255, 255, 0.3)";
|
|
2483
|
-
this.context.lineWidth = 1;
|
|
2484
|
-
this.context.beginPath();
|
|
2485
|
-
this.context.moveTo(graphX, targetY);
|
|
2486
|
-
this.context.lineTo(graphX + graphWidth, targetY);
|
|
2487
|
-
this.context.stroke();
|
|
2488
|
-
this.context.strokeStyle = accentColor;
|
|
2489
|
-
this.context.lineWidth = 2;
|
|
2490
|
-
this.context.beginPath();
|
|
2491
|
-
const maxFrameTime = Math.max(...this.frameTimeHistory, targetFrameTime * 2);
|
|
2492
|
-
const stepX = graphWidth / (this.frameTimeHistory.length - 1);
|
|
2493
|
-
this.frameTimeHistory.forEach((frameTime, index) => {
|
|
2494
|
-
const normalizedTime = Math.min(frameTime / maxFrameTime, 1);
|
|
2495
|
-
const pointY = graphY + graphHeight - normalizedTime * graphHeight;
|
|
2496
|
-
const pointX = graphX + index * stepX;
|
|
2497
|
-
if (index === 0) {
|
|
2498
|
-
this.context.moveTo(pointX, pointY);
|
|
2499
|
-
} else {
|
|
2500
|
-
this.context.lineTo(pointX, pointY);
|
|
2501
|
-
}
|
|
2502
|
-
});
|
|
2503
|
-
this.context.stroke();
|
|
2328
|
+
if (this.divided) {
|
|
2329
|
+
this.ne.queryRadius(cx, cy, radius, found);
|
|
2330
|
+
this.nw.queryRadius(cx, cy, radius, found);
|
|
2331
|
+
this.se.queryRadius(cx, cy, radius, found);
|
|
2332
|
+
this.sw.queryRadius(cx, cy, radius, found);
|
|
2504
2333
|
}
|
|
2505
|
-
|
|
2334
|
+
return found;
|
|
2506
2335
|
}
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2336
|
+
clear() {
|
|
2337
|
+
this.points = [];
|
|
2338
|
+
this.divided = false;
|
|
2339
|
+
this.ne = this.nw = this.se = this.sw = null;
|
|
2340
|
+
}
|
|
2341
|
+
get size() {
|
|
2342
|
+
let n = this.points.length;
|
|
2343
|
+
if (this.divided) {
|
|
2344
|
+
n += this.ne.size + this.nw.size + this.se.size + this.sw.size;
|
|
2345
|
+
}
|
|
2346
|
+
return n;
|
|
2512
2347
|
}
|
|
2513
2348
|
};
|
|
2514
|
-
var
|
|
2349
|
+
var Quadtree_default = Quadtree;
|
|
2515
2350
|
|
|
2516
|
-
// src/elements/
|
|
2517
|
-
var
|
|
2351
|
+
// src/elements/Pixels.tsx
|
|
2352
|
+
var Pixels = class {
|
|
2518
2353
|
constructor(ctx) {
|
|
2519
|
-
this.
|
|
2354
|
+
this.ctx = ctx;
|
|
2520
2355
|
}
|
|
2521
2356
|
/**
|
|
2522
|
-
*
|
|
2357
|
+
* Read all pixels from the canvas as ImageData.
|
|
2523
2358
|
*/
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
return this.renderInBrowser(draw, options);
|
|
2527
|
-
}
|
|
2528
|
-
throw new Error(
|
|
2529
|
-
"Server-side rendering requires 'canvas' package. Install it with: npm install canvas\nAlternatively, use SSR.generateImageUrl() to generate images via an API endpoint."
|
|
2530
|
-
);
|
|
2359
|
+
load() {
|
|
2360
|
+
return this.ctx.getImageData(0, 0, this.ctx.width, this.ctx.height);
|
|
2531
2361
|
}
|
|
2532
2362
|
/**
|
|
2533
|
-
*
|
|
2363
|
+
* Write pixel data back to the canvas.
|
|
2364
|
+
* Accepts a Uint8ClampedArray or a plain number array of RGBA values.
|
|
2534
2365
|
*/
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2366
|
+
update(pixels) {
|
|
2367
|
+
const pixelArray = pixels instanceof Uint8ClampedArray ? pixels : new Uint8ClampedArray(pixels);
|
|
2368
|
+
const imageData = new ImageData(
|
|
2369
|
+
new Uint8ClampedArray(pixelArray.buffer),
|
|
2370
|
+
this.ctx.width,
|
|
2371
|
+
this.ctx.height
|
|
2372
|
+
);
|
|
2373
|
+
this.ctx.putImageData(imageData, 0, 0);
|
|
2542
2374
|
}
|
|
2543
2375
|
/**
|
|
2544
|
-
*
|
|
2376
|
+
* Read pixel values at a position.
|
|
2377
|
+
* Returns an array of [r, g, b, a] values (0-255).
|
|
2378
|
+
*
|
|
2379
|
+
* @param x - X coordinate
|
|
2380
|
+
* @param y - Y coordinate
|
|
2381
|
+
* @param w - Width of region (default: 1)
|
|
2382
|
+
* @param h - Height of region (default: 1)
|
|
2545
2383
|
*/
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
}
|
|
2550
|
-
try {
|
|
2551
|
-
require("canvas");
|
|
2552
|
-
return true;
|
|
2553
|
-
} catch {
|
|
2554
|
-
return false;
|
|
2555
|
-
}
|
|
2384
|
+
read(x, y, w = 1, h = 1) {
|
|
2385
|
+
const imageData = this.ctx.getImageData(x, y, w, h);
|
|
2386
|
+
return Array.from(imageData.data);
|
|
2556
2387
|
}
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2388
|
+
};
|
|
2389
|
+
|
|
2390
|
+
// src/elements/Timeline.tsx
|
|
2391
|
+
var Timeline = class {
|
|
2392
|
+
constructor() {
|
|
2393
|
+
this.callbacks = { start: [], end: [], loop: [] };
|
|
2394
|
+
}
|
|
2395
|
+
onStart(fn) {
|
|
2396
|
+
this.callbacks.start.push(fn);
|
|
2397
|
+
}
|
|
2398
|
+
onEnd(fn) {
|
|
2399
|
+
this.callbacks.end.push(fn);
|
|
2400
|
+
}
|
|
2401
|
+
onLoop(fn) {
|
|
2402
|
+
this.callbacks.loop.push(fn);
|
|
2403
|
+
}
|
|
2404
|
+
create(setup, options = {}) {
|
|
2405
|
+
const tracks = /* @__PURE__ */ new Map();
|
|
2406
|
+
let currentProgress = 0;
|
|
2407
|
+
let hasStarted = false;
|
|
2408
|
+
let hasEnded = false;
|
|
2409
|
+
const callbacks = this.callbacks;
|
|
2410
|
+
const defaultEasing = options.defaultEasing || ((t) => t);
|
|
2411
|
+
const defaultLoop = options.defaultLoop || 0;
|
|
2412
|
+
const executeCallback = (callback, errorMsg = "Callback error") => {
|
|
2562
2413
|
try {
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2414
|
+
callback();
|
|
2415
|
+
} catch (e) {
|
|
2416
|
+
console.warn(`${errorMsg}:`, e);
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
function createKeyframes() {
|
|
2420
|
+
const segments = [];
|
|
2421
|
+
let currentPos = 0;
|
|
2422
|
+
let loopCount = defaultLoop;
|
|
2423
|
+
const parentTrack = void 0;
|
|
2424
|
+
const parseEasingCallback = (easing, callback) => {
|
|
2425
|
+
if (typeof easing === "function" && typeof callback === "undefined") {
|
|
2426
|
+
if (easing.length === 0) {
|
|
2427
|
+
return { easing: defaultEasing, callback: easing };
|
|
2428
|
+
}
|
|
2429
|
+
return {
|
|
2430
|
+
easing,
|
|
2431
|
+
callback: void 0
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
return {
|
|
2435
|
+
easing: easing || defaultEasing,
|
|
2436
|
+
callback
|
|
2437
|
+
};
|
|
2438
|
+
};
|
|
2439
|
+
const builder = {
|
|
2440
|
+
start(value, delay = 0, callback) {
|
|
2441
|
+
segments.push({ pos: delay, value, callback, type: "start" });
|
|
2442
|
+
currentPos = delay;
|
|
2443
|
+
return builder;
|
|
2444
|
+
},
|
|
2445
|
+
at(progress, value, easing, callback) {
|
|
2446
|
+
const { easing: finalEasing, callback: finalCallback } = parseEasingCallback(easing, callback);
|
|
2447
|
+
segments.push({
|
|
2448
|
+
pos: progress,
|
|
2449
|
+
value,
|
|
2450
|
+
easing: finalEasing,
|
|
2451
|
+
callback: finalCallback,
|
|
2452
|
+
type: "tween"
|
|
2453
|
+
});
|
|
2454
|
+
currentPos = progress;
|
|
2455
|
+
return builder;
|
|
2456
|
+
},
|
|
2457
|
+
then(value, duration, easing, callback) {
|
|
2458
|
+
const { easing: finalEasing, callback: finalCallback } = parseEasingCallback(easing, callback);
|
|
2459
|
+
const nextPos = currentPos + duration;
|
|
2460
|
+
segments.push({
|
|
2461
|
+
pos: nextPos,
|
|
2462
|
+
value,
|
|
2463
|
+
easing: finalEasing,
|
|
2464
|
+
callback: finalCallback,
|
|
2465
|
+
type: "tween"
|
|
2466
|
+
});
|
|
2467
|
+
currentPos = nextPos;
|
|
2468
|
+
return builder;
|
|
2469
|
+
},
|
|
2470
|
+
loop(count = Infinity) {
|
|
2471
|
+
loopCount = count;
|
|
2472
|
+
return builder;
|
|
2473
|
+
},
|
|
2474
|
+
_compile: () => {
|
|
2475
|
+
segments.sort((a, b) => a.pos - b.pos);
|
|
2476
|
+
return { segments, loopCount, parentTrack };
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
return builder;
|
|
2480
|
+
}
|
|
2481
|
+
function interpolateTrack(compiled, progress) {
|
|
2482
|
+
const { segments } = compiled;
|
|
2483
|
+
if (!segments.length) return 0;
|
|
2484
|
+
progress = Math.max(0, Math.min(1, progress));
|
|
2485
|
+
const valueSegments = segments.filter(
|
|
2486
|
+
(seg) => seg.value !== void 0
|
|
2487
|
+
);
|
|
2488
|
+
if (!valueSegments.length) return 0;
|
|
2489
|
+
let prevSeg = valueSegments[0];
|
|
2490
|
+
for (let i = 1; i < valueSegments.length; i++) {
|
|
2491
|
+
const seg = valueSegments[i];
|
|
2492
|
+
if (progress <= seg.pos) {
|
|
2493
|
+
if (seg.type === "tween" && prevSeg.value !== void 0 && seg.value !== void 0) {
|
|
2494
|
+
const t = (progress - prevSeg.pos) / (seg.pos - prevSeg.pos);
|
|
2495
|
+
const easedT = seg.easing ? seg.easing(t) : t;
|
|
2496
|
+
return prevSeg.value + (seg.value - prevSeg.value) * easedT;
|
|
2497
|
+
}
|
|
2498
|
+
return seg.value || 0;
|
|
2499
|
+
}
|
|
2500
|
+
if (seg.value !== void 0) {
|
|
2501
|
+
prevSeg = seg;
|
|
2571
2502
|
}
|
|
2572
|
-
const klintContext = this.createMinimalContext(
|
|
2573
|
-
ctx,
|
|
2574
|
-
canvas,
|
|
2575
|
-
options.width,
|
|
2576
|
-
options.height,
|
|
2577
|
-
dpr
|
|
2578
|
-
);
|
|
2579
|
-
draw(klintContext);
|
|
2580
|
-
const mimeType = options.format === "jpeg" ? "image/jpeg" : options.format === "webp" ? "image/webp" : "image/png";
|
|
2581
|
-
const quality = options.quality !== void 0 ? options.quality : 0.85;
|
|
2582
|
-
const dataUrl = canvas.toDataURL(mimeType, quality);
|
|
2583
|
-
resolve(dataUrl);
|
|
2584
|
-
} catch (error) {
|
|
2585
|
-
reject(error);
|
|
2586
2503
|
}
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
arc: ctx.arc.bind(ctx),
|
|
2606
|
-
fill: ctx.fill.bind(ctx),
|
|
2607
|
-
stroke: ctx.stroke.bind(ctx),
|
|
2608
|
-
save: ctx.save.bind(ctx),
|
|
2609
|
-
restore: ctx.restore.bind(ctx),
|
|
2610
|
-
translate: ctx.translate.bind(ctx),
|
|
2611
|
-
rotate: ctx.rotate.bind(ctx),
|
|
2612
|
-
scale: ctx.scale.bind(ctx),
|
|
2613
|
-
// Basic properties
|
|
2614
|
-
fillStyle: ctx.fillStyle,
|
|
2615
|
-
strokeStyle: ctx.strokeStyle,
|
|
2616
|
-
lineWidth: ctx.lineWidth,
|
|
2617
|
-
// Minimal Klint-like API
|
|
2618
|
-
background: (color) => {
|
|
2619
|
-
ctx.fillStyle = color || "#000";
|
|
2620
|
-
ctx.fillRect(0, 0, width * dpr, height * dpr);
|
|
2621
|
-
},
|
|
2622
|
-
fillColor: (color) => {
|
|
2623
|
-
ctx.fillStyle = color;
|
|
2504
|
+
return prevSeg.value || 0;
|
|
2505
|
+
}
|
|
2506
|
+
const timeline = {
|
|
2507
|
+
track: (keyframesOrFn) => {
|
|
2508
|
+
const compiled = typeof keyframesOrFn === "function" ? timeline.keyframes(keyframesOrFn) : keyframesOrFn;
|
|
2509
|
+
const track = {
|
|
2510
|
+
...compiled,
|
|
2511
|
+
currentValue: 0,
|
|
2512
|
+
getValue: (progress) => interpolateTrack(compiled, progress),
|
|
2513
|
+
get current() {
|
|
2514
|
+
return this.currentValue;
|
|
2515
|
+
},
|
|
2516
|
+
value() {
|
|
2517
|
+
return this.currentValue;
|
|
2518
|
+
}
|
|
2519
|
+
};
|
|
2520
|
+
tracks.set(track, compiled);
|
|
2521
|
+
return track;
|
|
2624
2522
|
},
|
|
2625
|
-
|
|
2626
|
-
|
|
2523
|
+
keyframes: (fn) => {
|
|
2524
|
+
const kf = createKeyframes();
|
|
2525
|
+
fn(kf);
|
|
2526
|
+
return kf._compile();
|
|
2627
2527
|
},
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2528
|
+
stagger: (count, offset, keyframesFn) => {
|
|
2529
|
+
const compiled = timeline.keyframes(keyframesFn);
|
|
2530
|
+
return Array.from({ length: count }, (_, i) => {
|
|
2531
|
+
const track = {
|
|
2532
|
+
...compiled,
|
|
2533
|
+
currentValue: 0,
|
|
2534
|
+
staggerDelay: i * offset,
|
|
2535
|
+
getValue: (progress) => {
|
|
2536
|
+
const staggeredProgress = Math.max(0, progress - i * offset);
|
|
2537
|
+
const normalizedProgress = Math.min(
|
|
2538
|
+
1,
|
|
2539
|
+
staggeredProgress / (1 - i * offset)
|
|
2540
|
+
);
|
|
2541
|
+
return normalizedProgress > 0 ? interpolateTrack(compiled, normalizedProgress) : 0;
|
|
2542
|
+
},
|
|
2543
|
+
get current() {
|
|
2544
|
+
return this.currentValue;
|
|
2545
|
+
},
|
|
2546
|
+
value() {
|
|
2547
|
+
return this.currentValue;
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2550
|
+
tracks.set(track, compiled);
|
|
2551
|
+
return track;
|
|
2552
|
+
});
|
|
2632
2553
|
},
|
|
2633
|
-
|
|
2634
|
-
|
|
2554
|
+
update: (progress) => {
|
|
2555
|
+
const prevProgress = currentProgress;
|
|
2556
|
+
currentProgress = progress;
|
|
2557
|
+
if (!hasStarted && progress > 0) {
|
|
2558
|
+
hasStarted = true;
|
|
2559
|
+
callbacks.start.forEach(
|
|
2560
|
+
(cb) => executeCallback(cb, "Start callback error")
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2563
|
+
if (!hasEnded && progress >= 1) {
|
|
2564
|
+
hasEnded = true;
|
|
2565
|
+
callbacks.end.forEach(
|
|
2566
|
+
(cb) => executeCallback(cb, "End callback error")
|
|
2567
|
+
);
|
|
2568
|
+
}
|
|
2569
|
+
if (progress < prevProgress) {
|
|
2570
|
+
if (progress === 0) {
|
|
2571
|
+
hasStarted = false;
|
|
2572
|
+
hasEnded = false;
|
|
2573
|
+
} else if (progress < 1) {
|
|
2574
|
+
hasEnded = false;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
for (const [track, compiled] of tracks) {
|
|
2578
|
+
track.currentValue = track.getValue(progress);
|
|
2579
|
+
if (compiled.segments) {
|
|
2580
|
+
compiled.segments.forEach((seg) => {
|
|
2581
|
+
if (seg.callback && seg.pos <= progress && seg.pos > prevProgress) {
|
|
2582
|
+
executeCallback(seg.callback);
|
|
2583
|
+
}
|
|
2584
|
+
});
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2635
2587
|
},
|
|
2636
|
-
|
|
2637
|
-
frame: 0,
|
|
2638
|
-
time: 0,
|
|
2639
|
-
deltaTime: 0,
|
|
2640
|
-
fps: 60
|
|
2588
|
+
progress: () => currentProgress
|
|
2641
2589
|
};
|
|
2590
|
+
const result = setup(timeline);
|
|
2591
|
+
return { ...result, update: timeline.update };
|
|
2642
2592
|
}
|
|
2643
2593
|
};
|
|
2644
|
-
var SSR_default = SSR;
|
|
2645
2594
|
|
|
2646
2595
|
// src/KlintFunctions.tsx
|
|
2647
2596
|
var KlintCoreFunctions = {
|
|
@@ -2663,37 +2612,6 @@ var KlintCoreFunctions = {
|
|
|
2663
2612
|
// to do
|
|
2664
2613
|
redraw: () => () => {
|
|
2665
2614
|
},
|
|
2666
|
-
extend: (ctx) => (name, data, enforceReplace = false) => {
|
|
2667
|
-
if (name in ctx && !enforceReplace) return;
|
|
2668
|
-
ctx[name] = data;
|
|
2669
|
-
},
|
|
2670
|
-
passImage: () => (element) => {
|
|
2671
|
-
if (!element.complete) {
|
|
2672
|
-
console.warn("Image passed to passImage() is not fully loaded");
|
|
2673
|
-
return null;
|
|
2674
|
-
}
|
|
2675
|
-
return element;
|
|
2676
|
-
},
|
|
2677
|
-
passImages: () => (elements) => {
|
|
2678
|
-
return elements.map((element) => {
|
|
2679
|
-
if (!element.complete) {
|
|
2680
|
-
console.warn("Image passed to passImages() is not fully loaded");
|
|
2681
|
-
return null;
|
|
2682
|
-
}
|
|
2683
|
-
return element;
|
|
2684
|
-
});
|
|
2685
|
-
},
|
|
2686
|
-
saveConfig: (ctx) => (from) => {
|
|
2687
|
-
return Object.fromEntries(
|
|
2688
|
-
CONFIG_PROPS.map((key) => [
|
|
2689
|
-
key,
|
|
2690
|
-
from?.[key] ?? ctx[key]
|
|
2691
|
-
])
|
|
2692
|
-
);
|
|
2693
|
-
},
|
|
2694
|
-
restoreConfig: (ctx) => (config) => {
|
|
2695
|
-
Object.assign(ctx, config);
|
|
2696
|
-
},
|
|
2697
2615
|
describe: (ctx) => (description) => {
|
|
2698
2616
|
ctx.__description = description;
|
|
2699
2617
|
},
|
|
@@ -2798,6 +2716,7 @@ var KlintFunctions = {
|
|
|
2798
2716
|
strokeWidth: (ctx) => (width) => {
|
|
2799
2717
|
if (width <= 0) {
|
|
2800
2718
|
ctx.lineWidth = EPSILON;
|
|
2719
|
+
return;
|
|
2801
2720
|
}
|
|
2802
2721
|
ctx.lineWidth = width;
|
|
2803
2722
|
},
|
|
@@ -2974,7 +2893,7 @@ var KlintFunctions = {
|
|
|
2974
2893
|
ctx.__currentContours = null;
|
|
2975
2894
|
ctx.__startedShape = false;
|
|
2976
2895
|
},
|
|
2977
|
-
gradient: (ctx) => (x1 = 0, y1 = 0, x2 = ctx.width, y2 = ctx.
|
|
2896
|
+
gradient: (ctx) => (x1 = 0, y1 = 0, x2 = ctx.width, y2 = ctx.height) => {
|
|
2978
2897
|
return ctx.createLinearGradient(x1, y1, x2, y2);
|
|
2979
2898
|
},
|
|
2980
2899
|
radialGradient: (ctx) => (x1 = ctx.width / 2, y1 = ctx.height / 2, r1 = 0, x2 = ctx.width / 2, y2 = ctx.height / 2, r2 = Math.min(ctx.width, ctx.height)) => {
|
|
@@ -3237,19 +3156,6 @@ var KlintFunctions = {
|
|
|
3237
3156
|
const adjustedY = ctx.__imageOrigin === "center" ? dy - height / 2 : dy;
|
|
3238
3157
|
ctx.drawImage(sourceImage, adjustedX, adjustedY);
|
|
3239
3158
|
},
|
|
3240
|
-
// unsure about keeping those next two, maybe a shader plugin would be better
|
|
3241
|
-
loadPixels: (ctx) => () => {
|
|
3242
|
-
return ctx.getImageData(0, 0, ctx.width, ctx.height);
|
|
3243
|
-
},
|
|
3244
|
-
updatePixels: (ctx) => (pixels) => {
|
|
3245
|
-
const pixelArray = pixels instanceof Uint8ClampedArray ? new Uint8ClampedArray(pixels) : new Uint8ClampedArray(pixels);
|
|
3246
|
-
const imageData = new ImageData(pixelArray, ctx.width, ctx.height);
|
|
3247
|
-
ctx.putImageData(imageData, 0, 0);
|
|
3248
|
-
},
|
|
3249
|
-
readPixels: (ctx) => (x, y, w = 1, h = 1) => {
|
|
3250
|
-
const imageData = ctx.getImageData(x, y, w, h);
|
|
3251
|
-
return Array.from(imageData.data);
|
|
3252
|
-
},
|
|
3253
3159
|
scaleTo: () => (originWidth, originHeight, destinationWidth, destinationHeight, cover = false) => {
|
|
3254
3160
|
const widthRatio = destinationWidth / originWidth;
|
|
3255
3161
|
const heightRatio = destinationHeight / originHeight;
|
|
@@ -3261,6 +3167,12 @@ var KlintFunctions = {
|
|
|
3261
3167
|
blend: (ctx) => (blend) => {
|
|
3262
3168
|
ctx.globalCompositeOperation = blend === "default" ? "source-over" : blend;
|
|
3263
3169
|
},
|
|
3170
|
+
smooth: (ctx) => () => {
|
|
3171
|
+
ctx.imageSmoothingEnabled = true;
|
|
3172
|
+
},
|
|
3173
|
+
noSmooth: (ctx) => () => {
|
|
3174
|
+
ctx.imageSmoothingEnabled = false;
|
|
3175
|
+
},
|
|
3264
3176
|
setCanvasOrigin: (ctx) => (type) => {
|
|
3265
3177
|
ctx.__canvasOrigin = type;
|
|
3266
3178
|
},
|
|
@@ -3324,6 +3236,41 @@ var KlintFunctions = {
|
|
|
3324
3236
|
ctx.fill = originalFill;
|
|
3325
3237
|
ctx.stroke = originalStroke;
|
|
3326
3238
|
},
|
|
3239
|
+
screenToWorld: (ctx) => (screenX, screenY) => {
|
|
3240
|
+
const isCenter = ctx.__canvasOrigin === "center";
|
|
3241
|
+
const deviceX = isCenter ? screenX + ctx.width * 0.5 : screenX;
|
|
3242
|
+
const deviceY = isCenter ? screenY + ctx.height * 0.5 : screenY;
|
|
3243
|
+
const inverse = ctx.getTransform().inverse();
|
|
3244
|
+
const pt = inverse.transformPoint(new DOMPoint(deviceX, deviceY));
|
|
3245
|
+
return { x: pt.x, y: pt.y };
|
|
3246
|
+
},
|
|
3247
|
+
worldToScreen: (ctx) => (worldX, worldY) => {
|
|
3248
|
+
const isCenter = ctx.__canvasOrigin === "center";
|
|
3249
|
+
const matrix = ctx.getTransform();
|
|
3250
|
+
const pt = matrix.transformPoint(new DOMPoint(worldX, worldY));
|
|
3251
|
+
const screenX = isCenter ? pt.x - ctx.width * 0.5 : pt.x;
|
|
3252
|
+
const screenY = isCenter ? pt.y - ctx.height * 0.5 : pt.y;
|
|
3253
|
+
return { x: screenX, y: screenY };
|
|
3254
|
+
},
|
|
3255
|
+
getVisibleBounds: (ctx) => () => {
|
|
3256
|
+
const inverse = ctx.getTransform().inverse();
|
|
3257
|
+
const c0 = inverse.transformPoint(new DOMPoint(0, 0));
|
|
3258
|
+
const c1 = inverse.transformPoint(new DOMPoint(ctx.width, 0));
|
|
3259
|
+
const c2 = inverse.transformPoint(new DOMPoint(ctx.width, ctx.height));
|
|
3260
|
+
const c3 = inverse.transformPoint(new DOMPoint(0, ctx.height));
|
|
3261
|
+
const left = Math.min(c0.x, c1.x, c2.x, c3.x);
|
|
3262
|
+
const right = Math.max(c0.x, c1.x, c2.x, c3.x);
|
|
3263
|
+
const top = Math.min(c0.y, c1.y, c2.y, c3.y);
|
|
3264
|
+
const bottom = Math.max(c0.y, c1.y, c2.y, c3.y);
|
|
3265
|
+
return {
|
|
3266
|
+
left,
|
|
3267
|
+
top,
|
|
3268
|
+
right,
|
|
3269
|
+
bottom,
|
|
3270
|
+
width: right - left,
|
|
3271
|
+
height: bottom - top
|
|
3272
|
+
};
|
|
3273
|
+
},
|
|
3327
3274
|
canIuseFilter: (ctx) => () => {
|
|
3328
3275
|
return ctx.filter !== void 0 && ctx.filter !== null;
|
|
3329
3276
|
},
|
|
@@ -3363,7 +3310,6 @@ var KlintFunctions = {
|
|
|
3363
3310
|
};
|
|
3364
3311
|
|
|
3365
3312
|
// src/useKlint.tsx
|
|
3366
|
-
var import_meta2 = {};
|
|
3367
3313
|
var DEFAULT_MOUSE_STATE = {
|
|
3368
3314
|
x: 0,
|
|
3369
3315
|
y: 0,
|
|
@@ -3415,29 +3361,8 @@ function useKlint() {
|
|
|
3415
3361
|
const gestureRef = (0, import_react2.useRef)(null);
|
|
3416
3362
|
const keyboardRef = (0, import_react2.useRef)(null);
|
|
3417
3363
|
const useDev = () => {
|
|
3418
|
-
(0, import_react2.useEffect)(() => {
|
|
3419
|
-
if (process.env.NODE_ENV === "development") {
|
|
3420
|
-
if (typeof import_meta2 !== "undefined" && import_meta2.hot) {
|
|
3421
|
-
console.log("[Klint] hot updated - clearing non-context state");
|
|
3422
|
-
if (contextRef.current) {
|
|
3423
|
-
const ctx = contextRef.current;
|
|
3424
|
-
ctx.frame = 0;
|
|
3425
|
-
ctx.time = 0;
|
|
3426
|
-
ctx.__offscreens?.clear();
|
|
3427
|
-
ctx.__startedShape = false;
|
|
3428
|
-
ctx.__currentShape = null;
|
|
3429
|
-
ctx.__startedContour = false;
|
|
3430
|
-
ctx.__currentContours = null;
|
|
3431
|
-
ctx.__currentContour = null;
|
|
3432
|
-
ctx.__isReadyToDraw = true;
|
|
3433
|
-
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
3434
|
-
}
|
|
3435
|
-
}
|
|
3436
|
-
}
|
|
3437
|
-
}, []);
|
|
3438
3364
|
(0, import_react2.useEffect)(() => {
|
|
3439
3365
|
if (process.env.NODE_ENV === "development" && contextRef.current) {
|
|
3440
|
-
console.log("[Klint] hot updated - clearing context state");
|
|
3441
3366
|
contextRef.current.__isReadyToDraw = true;
|
|
3442
3367
|
}
|
|
3443
3368
|
});
|
|
@@ -3561,7 +3486,7 @@ function useKlint() {
|
|
|
3561
3486
|
canvas.addEventListener("mouseleave", handleMouseLeave, { signal });
|
|
3562
3487
|
canvas.addEventListener("click", handleClick, { signal });
|
|
3563
3488
|
return () => controller.abort();
|
|
3564
|
-
});
|
|
3489
|
+
}, []);
|
|
3565
3490
|
return {
|
|
3566
3491
|
mouse: mouseRef.current,
|
|
3567
3492
|
onClick: (callback) => clickCallbackRef.current = callback,
|
|
@@ -3596,7 +3521,7 @@ function useKlint() {
|
|
|
3596
3521
|
};
|
|
3597
3522
|
canvas.addEventListener("wheel", handleScroll, { signal });
|
|
3598
3523
|
return () => controller.abort();
|
|
3599
|
-
});
|
|
3524
|
+
}, []);
|
|
3600
3525
|
return {
|
|
3601
3526
|
scroll: scrollRef.current,
|
|
3602
3527
|
onScroll: (callback) => scrollCallbackRef.current = callback
|
|
@@ -3773,6 +3698,17 @@ function useKlint() {
|
|
|
3773
3698
|
const keyPressedCallbackRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
3774
3699
|
const keyReleasedCallbackRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
3775
3700
|
const keyComboCallbackRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
3701
|
+
const normalizeKey = (key) => {
|
|
3702
|
+
const keyMap = {
|
|
3703
|
+
" ": "Space",
|
|
3704
|
+
Control: "Ctrl",
|
|
3705
|
+
Escape: "Esc"
|
|
3706
|
+
};
|
|
3707
|
+
return keyMap[key] || key;
|
|
3708
|
+
};
|
|
3709
|
+
const createComboKey = (keys) => {
|
|
3710
|
+
return keys.map(normalizeKey).sort().join("+");
|
|
3711
|
+
};
|
|
3776
3712
|
(0, import_react2.useEffect)(() => {
|
|
3777
3713
|
if (!contextRef.current) return;
|
|
3778
3714
|
const ctx = contextRef.current;
|
|
@@ -3785,17 +3721,9 @@ function useKlint() {
|
|
|
3785
3721
|
keyboardRef.current.modifiers.ctrl = e.ctrlKey;
|
|
3786
3722
|
keyboardRef.current.modifiers.meta = e.metaKey;
|
|
3787
3723
|
};
|
|
3788
|
-
const normalizeKey2 = (key) => {
|
|
3789
|
-
const keyMap = {
|
|
3790
|
-
" ": "Space",
|
|
3791
|
-
Control: "Ctrl",
|
|
3792
|
-
Escape: "Esc"
|
|
3793
|
-
};
|
|
3794
|
-
return keyMap[key] || key;
|
|
3795
|
-
};
|
|
3796
3724
|
const handleKeyDown = (e) => {
|
|
3797
3725
|
if (!keyboardRef.current) return;
|
|
3798
|
-
const normalizedKey =
|
|
3726
|
+
const normalizedKey = normalizeKey(e.key);
|
|
3799
3727
|
keyboardRef.current.pressedKeys.add(normalizedKey);
|
|
3800
3728
|
keyboardRef.current.lastKey = normalizedKey;
|
|
3801
3729
|
keyboardRef.current.lastKeyTime = performance.now();
|
|
@@ -3815,7 +3743,7 @@ function useKlint() {
|
|
|
3815
3743
|
};
|
|
3816
3744
|
const handleKeyUp = (e) => {
|
|
3817
3745
|
if (!keyboardRef.current) return;
|
|
3818
|
-
const normalizedKey =
|
|
3746
|
+
const normalizedKey = normalizeKey(e.key);
|
|
3819
3747
|
keyboardRef.current.pressedKeys.delete(normalizedKey);
|
|
3820
3748
|
updateModifiers(e);
|
|
3821
3749
|
const keyCallback = keyReleasedCallbackRef.current.get(normalizedKey);
|
|
@@ -3827,17 +3755,6 @@ function useKlint() {
|
|
|
3827
3755
|
window.addEventListener("keyup", handleKeyUp, { signal });
|
|
3828
3756
|
return () => controller.abort();
|
|
3829
3757
|
}, []);
|
|
3830
|
-
const createComboKey = (keys) => {
|
|
3831
|
-
return keys.map(normalizeKey).sort().join("+");
|
|
3832
|
-
};
|
|
3833
|
-
const normalizeKey = (key) => {
|
|
3834
|
-
const keyMap = {
|
|
3835
|
-
" ": "Space",
|
|
3836
|
-
Control: "Ctrl",
|
|
3837
|
-
Escape: "Esc"
|
|
3838
|
-
};
|
|
3839
|
-
return keyMap[key] || key;
|
|
3840
|
-
};
|
|
3841
3758
|
return {
|
|
3842
3759
|
keyboard: keyboardRef.current,
|
|
3843
3760
|
// Register callback for single key press
|
|
@@ -3871,210 +3788,6 @@ function useKlint() {
|
|
|
3871
3788
|
}
|
|
3872
3789
|
};
|
|
3873
3790
|
};
|
|
3874
|
-
const KlintTimeline = () => {
|
|
3875
|
-
const timelinesRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
3876
|
-
const callbacksRef = (0, import_react2.useRef)({ start: [], end: [], loop: [] });
|
|
3877
|
-
const Timeline = {
|
|
3878
|
-
create: (setup, options = {}) => {
|
|
3879
|
-
const tracks = /* @__PURE__ */ new Map();
|
|
3880
|
-
const parents = /* @__PURE__ */ new Set();
|
|
3881
|
-
let currentProgress = 0;
|
|
3882
|
-
let hasStarted = false;
|
|
3883
|
-
let hasEnded = false;
|
|
3884
|
-
const defaultEasing = options.defaultEasing || ((t) => t);
|
|
3885
|
-
const defaultLoop = options.defaultLoop || 0;
|
|
3886
|
-
const executeCallback = (callback, errorMsg = "Callback error") => {
|
|
3887
|
-
try {
|
|
3888
|
-
callback();
|
|
3889
|
-
} catch (e) {
|
|
3890
|
-
console.warn(`${errorMsg}:`, e);
|
|
3891
|
-
}
|
|
3892
|
-
};
|
|
3893
|
-
function createKeyframes() {
|
|
3894
|
-
const segments = [];
|
|
3895
|
-
let currentPos = 0;
|
|
3896
|
-
let loopCount = defaultLoop;
|
|
3897
|
-
let parentTrack = void 0;
|
|
3898
|
-
const parseEasingCallback = (easing, callback) => {
|
|
3899
|
-
if (typeof easing === "function" && typeof callback === "undefined") {
|
|
3900
|
-
if (easing.length === 0) {
|
|
3901
|
-
return {
|
|
3902
|
-
easing: defaultEasing,
|
|
3903
|
-
callback: easing
|
|
3904
|
-
};
|
|
3905
|
-
}
|
|
3906
|
-
return {
|
|
3907
|
-
easing,
|
|
3908
|
-
callback: void 0
|
|
3909
|
-
};
|
|
3910
|
-
}
|
|
3911
|
-
return {
|
|
3912
|
-
easing: easing || defaultEasing,
|
|
3913
|
-
callback
|
|
3914
|
-
};
|
|
3915
|
-
};
|
|
3916
|
-
const builder = {
|
|
3917
|
-
start(value, delay = 0, callback) {
|
|
3918
|
-
segments.push({ pos: delay, value, callback, type: "start" });
|
|
3919
|
-
currentPos = delay;
|
|
3920
|
-
return builder;
|
|
3921
|
-
},
|
|
3922
|
-
at(progress, value, easing, callback) {
|
|
3923
|
-
const { easing: finalEasing, callback: finalCallback } = parseEasingCallback(easing, callback);
|
|
3924
|
-
segments.push({
|
|
3925
|
-
pos: progress,
|
|
3926
|
-
value,
|
|
3927
|
-
easing: finalEasing,
|
|
3928
|
-
callback: finalCallback,
|
|
3929
|
-
type: "tween"
|
|
3930
|
-
});
|
|
3931
|
-
currentPos = progress;
|
|
3932
|
-
return builder;
|
|
3933
|
-
},
|
|
3934
|
-
then(value, duration, easing, callback) {
|
|
3935
|
-
const { easing: finalEasing, callback: finalCallback } = parseEasingCallback(easing, callback);
|
|
3936
|
-
const nextPos = currentPos + duration;
|
|
3937
|
-
segments.push({
|
|
3938
|
-
pos: nextPos,
|
|
3939
|
-
value,
|
|
3940
|
-
easing: finalEasing,
|
|
3941
|
-
callback: finalCallback,
|
|
3942
|
-
type: "tween"
|
|
3943
|
-
});
|
|
3944
|
-
currentPos = nextPos;
|
|
3945
|
-
return builder;
|
|
3946
|
-
},
|
|
3947
|
-
loop(count = Infinity) {
|
|
3948
|
-
loopCount = count;
|
|
3949
|
-
return builder;
|
|
3950
|
-
},
|
|
3951
|
-
_compile: () => {
|
|
3952
|
-
segments.sort((a, b) => a.pos - b.pos);
|
|
3953
|
-
return { segments, loopCount, parentTrack };
|
|
3954
|
-
}
|
|
3955
|
-
};
|
|
3956
|
-
return builder;
|
|
3957
|
-
}
|
|
3958
|
-
function interpolateTrack(compiled, progress) {
|
|
3959
|
-
const { segments } = compiled;
|
|
3960
|
-
if (!segments.length) return 0;
|
|
3961
|
-
progress = Math.max(0, Math.min(1, progress));
|
|
3962
|
-
const valueSegments = segments.filter(
|
|
3963
|
-
(seg) => seg.type !== "callback"
|
|
3964
|
-
);
|
|
3965
|
-
if (!valueSegments.length) return 0;
|
|
3966
|
-
let prevSeg = valueSegments[0];
|
|
3967
|
-
for (let i = 1; i < valueSegments.length; i++) {
|
|
3968
|
-
const seg = valueSegments[i];
|
|
3969
|
-
if (progress <= seg.pos) {
|
|
3970
|
-
if (seg.type === "tween" && prevSeg.value !== void 0 && seg.value !== void 0) {
|
|
3971
|
-
const t = (progress - prevSeg.pos) / (seg.pos - prevSeg.pos);
|
|
3972
|
-
const easedT = seg.easing ? seg.easing(t) : t;
|
|
3973
|
-
return prevSeg.value + (seg.value - prevSeg.value) * easedT;
|
|
3974
|
-
}
|
|
3975
|
-
return seg.value || 0;
|
|
3976
|
-
}
|
|
3977
|
-
if (seg.value !== void 0) {
|
|
3978
|
-
prevSeg = seg;
|
|
3979
|
-
}
|
|
3980
|
-
}
|
|
3981
|
-
return prevSeg.value || 0;
|
|
3982
|
-
}
|
|
3983
|
-
const timeline = {
|
|
3984
|
-
track: (keyframesOrFn) => {
|
|
3985
|
-
const compiled = typeof keyframesOrFn === "function" ? timeline.keyframes(keyframesOrFn) : keyframesOrFn;
|
|
3986
|
-
const track = {
|
|
3987
|
-
...compiled,
|
|
3988
|
-
currentValue: 0,
|
|
3989
|
-
getValue: (progress) => interpolateTrack(compiled, progress),
|
|
3990
|
-
get current() {
|
|
3991
|
-
return this.currentValue;
|
|
3992
|
-
},
|
|
3993
|
-
value: function() {
|
|
3994
|
-
return this.currentValue;
|
|
3995
|
-
}
|
|
3996
|
-
};
|
|
3997
|
-
tracks.set(track, compiled);
|
|
3998
|
-
return track;
|
|
3999
|
-
},
|
|
4000
|
-
keyframes: (fn) => {
|
|
4001
|
-
const kf = createKeyframes();
|
|
4002
|
-
fn(kf);
|
|
4003
|
-
return kf._compile();
|
|
4004
|
-
},
|
|
4005
|
-
stagger: (count, offset, keyframesFn) => {
|
|
4006
|
-
const compiled = timeline.keyframes(keyframesFn);
|
|
4007
|
-
return Array.from({ length: count }, (_, i) => {
|
|
4008
|
-
const track = {
|
|
4009
|
-
...compiled,
|
|
4010
|
-
currentValue: 0,
|
|
4011
|
-
staggerDelay: i * offset,
|
|
4012
|
-
getValue: (progress) => {
|
|
4013
|
-
const staggeredProgress = Math.max(0, progress - i * offset);
|
|
4014
|
-
const normalizedProgress = Math.min(
|
|
4015
|
-
1,
|
|
4016
|
-
staggeredProgress / (1 - i * offset)
|
|
4017
|
-
);
|
|
4018
|
-
return normalizedProgress > 0 ? interpolateTrack(compiled, normalizedProgress) : 0;
|
|
4019
|
-
},
|
|
4020
|
-
get current() {
|
|
4021
|
-
return this.currentValue;
|
|
4022
|
-
},
|
|
4023
|
-
value: function() {
|
|
4024
|
-
return this.currentValue;
|
|
4025
|
-
}
|
|
4026
|
-
};
|
|
4027
|
-
tracks.set(track, compiled);
|
|
4028
|
-
return track;
|
|
4029
|
-
});
|
|
4030
|
-
},
|
|
4031
|
-
update: (progress) => {
|
|
4032
|
-
const prevProgress = currentProgress;
|
|
4033
|
-
currentProgress = progress;
|
|
4034
|
-
if (!hasStarted && progress > 0) {
|
|
4035
|
-
hasStarted = true;
|
|
4036
|
-
callbacksRef.current.start.forEach(
|
|
4037
|
-
(cb) => executeCallback(cb, "Start callback error")
|
|
4038
|
-
);
|
|
4039
|
-
}
|
|
4040
|
-
if (!hasEnded && progress >= 1) {
|
|
4041
|
-
hasEnded = true;
|
|
4042
|
-
callbacksRef.current.end.forEach(
|
|
4043
|
-
(cb) => executeCallback(cb, "End callback error")
|
|
4044
|
-
);
|
|
4045
|
-
}
|
|
4046
|
-
if (progress < prevProgress) {
|
|
4047
|
-
if (progress === 0) {
|
|
4048
|
-
hasStarted = false;
|
|
4049
|
-
hasEnded = false;
|
|
4050
|
-
} else if (progress < 1) {
|
|
4051
|
-
hasEnded = false;
|
|
4052
|
-
}
|
|
4053
|
-
}
|
|
4054
|
-
for (const [track, compiled] of tracks) {
|
|
4055
|
-
track.currentValue = track.getValue(progress);
|
|
4056
|
-
if (compiled.segments) {
|
|
4057
|
-
compiled.segments.forEach((seg) => {
|
|
4058
|
-
if (seg.callback && seg.pos <= progress && seg.pos > prevProgress) {
|
|
4059
|
-
executeCallback(seg.callback);
|
|
4060
|
-
}
|
|
4061
|
-
});
|
|
4062
|
-
}
|
|
4063
|
-
}
|
|
4064
|
-
},
|
|
4065
|
-
progress: () => currentProgress
|
|
4066
|
-
};
|
|
4067
|
-
const result = setup(timeline);
|
|
4068
|
-
return { ...result, update: timeline.update };
|
|
4069
|
-
}
|
|
4070
|
-
};
|
|
4071
|
-
return {
|
|
4072
|
-
Timeline,
|
|
4073
|
-
onStart: (fn) => callbacksRef.current.start.push(fn),
|
|
4074
|
-
onEnd: (fn) => callbacksRef.current.end.push(fn),
|
|
4075
|
-
onLoop: (fn) => callbacksRef.current.loop.push(fn)
|
|
4076
|
-
};
|
|
4077
|
-
};
|
|
4078
3791
|
const KlintWindow = () => {
|
|
4079
3792
|
const resizeCallbackRef = (0, import_react2.useRef)(
|
|
4080
3793
|
null
|
|
@@ -4145,13 +3858,13 @@ function useKlint() {
|
|
|
4145
3858
|
context.Vector = new Vector_default();
|
|
4146
3859
|
context.Easing = new Easing_default();
|
|
4147
3860
|
context.Text = new Text_default(context);
|
|
4148
|
-
context.Thing = new Thing_default(context);
|
|
4149
3861
|
context.Grid = new Grid_default(context);
|
|
4150
3862
|
context.Strip = new Strip_default(context);
|
|
4151
3863
|
context.Noise = new Noise_default(context);
|
|
4152
3864
|
context.Hotspot = new Hotspot_default(context);
|
|
4153
|
-
context.
|
|
4154
|
-
context.
|
|
3865
|
+
context.Quadtree = Quadtree_default;
|
|
3866
|
+
context.Pixels = new Pixels(context);
|
|
3867
|
+
context.Timeline = new Timeline();
|
|
4155
3868
|
Object.entries(KlintCoreFunctions).forEach(([name, fn]) => {
|
|
4156
3869
|
context[name] = fn(context);
|
|
4157
3870
|
});
|
|
@@ -4182,30 +3895,6 @@ function useKlint() {
|
|
|
4182
3895
|
contextRef.current.__isPlaying = !contextRef.current.__isPlaying;
|
|
4183
3896
|
}
|
|
4184
3897
|
}, []);
|
|
4185
|
-
const KlintPerformance = () => {
|
|
4186
|
-
const metricsRef = (0, import_react2.useRef)(null);
|
|
4187
|
-
(0, import_react2.useEffect)(() => {
|
|
4188
|
-
if (!contextRef.current?.__performance) return;
|
|
4189
|
-
const updateMetrics = () => {
|
|
4190
|
-
if (contextRef.current?.__performance) {
|
|
4191
|
-
metricsRef.current = { ...contextRef.current.__performance };
|
|
4192
|
-
}
|
|
4193
|
-
};
|
|
4194
|
-
const interval = setInterval(updateMetrics, 100);
|
|
4195
|
-
return () => clearInterval(interval);
|
|
4196
|
-
}, []);
|
|
4197
|
-
return {
|
|
4198
|
-
metrics: metricsRef.current,
|
|
4199
|
-
getMetrics: () => contextRef.current?.__performance || null,
|
|
4200
|
-
reset: () => {
|
|
4201
|
-
if (contextRef.current?.__performance) {
|
|
4202
|
-
contextRef.current.__performance.droppedFrames = 0;
|
|
4203
|
-
contextRef.current.__performance.minFrameTime = Infinity;
|
|
4204
|
-
contextRef.current.__performance.maxFrameTime = 0;
|
|
4205
|
-
}
|
|
4206
|
-
}
|
|
4207
|
-
};
|
|
4208
|
-
};
|
|
4209
3898
|
return {
|
|
4210
3899
|
context: {
|
|
4211
3900
|
context: contextRef.current,
|
|
@@ -4217,8 +3906,6 @@ function useKlint() {
|
|
|
4217
3906
|
KlintKeyboard,
|
|
4218
3907
|
KlintWindow,
|
|
4219
3908
|
KlintImage,
|
|
4220
|
-
KlintTimeline,
|
|
4221
|
-
KlintPerformance,
|
|
4222
3909
|
togglePlay,
|
|
4223
3910
|
useDev
|
|
4224
3911
|
};
|
|
@@ -4274,11 +3961,12 @@ var useStorage = (initialProps = {}) => {
|
|
|
4274
3961
|
KlintCoreFunctions,
|
|
4275
3962
|
KlintFunctions,
|
|
4276
3963
|
Noise,
|
|
4277
|
-
|
|
4278
|
-
|
|
3964
|
+
Pixels,
|
|
3965
|
+
Quadtree,
|
|
3966
|
+
Rectangle,
|
|
4279
3967
|
Strip,
|
|
4280
3968
|
Text,
|
|
4281
|
-
|
|
3969
|
+
Timeline,
|
|
4282
3970
|
Vector,
|
|
4283
3971
|
useKlint,
|
|
4284
3972
|
useProps,
|