r3f-vfx 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -265,15 +265,12 @@ declare const useVFXStore: typeof useVFXStoreImpl & {
265
265
  };
266
266
 
267
267
  /**
268
- * Hook for async curve texture loading
268
+ * Hook for curve texture loading/baking
269
269
  * Returns a STABLE texture reference that updates in place
270
270
  *
271
- * If curveTexturePath is provided, loads pre-baked texture (fast)
272
- * If curves are defined, bakes them in web worker
273
- * If no curves AND no path, returns default texture (no baking, instant)
274
- *
275
- * The 4KB default texture is always created for shader compatibility,
276
- * but baking is skipped when not needed (main performance win).
271
+ * If curveTexturePath is provided, loads pre-baked texture from file
272
+ * If curves are defined, bakes them synchronously on the main thread
273
+ * If no curves AND no path, returns default texture (no baking needed)
277
274
  */
278
275
  declare const useCurveTextureAsync: (sizeCurve: CurveData | null, opacityCurve: CurveData | null, velocityCurve: CurveData | null, rotationSpeedCurve: CurveData | null, curveTexturePath?: string | null) => THREE.DataTexture;
279
276
 
package/dist/index.js CHANGED
@@ -58,103 +58,79 @@ var init_react_store = __esm({
58
58
  });
59
59
 
60
60
  // src/useCurveTextureAsync.ts
61
- import { useRef, useEffect } from "react";
61
+ import { useRef, useEffect, useMemo } from "react";
62
62
  import {
63
63
  createDefaultCurveTexture,
64
+ createCombinedCurveTexture,
64
65
  loadCurveTextureFromPath
65
66
  } from "core-vfx";
66
- var import_meta, curveWorker, curveWorkerCallbacks, curveWorkerIdCounter, getCurveWorker, bakeCurvesAsync, useCurveTextureAsync;
67
+ var useCurveTextureAsync;
67
68
  var init_useCurveTextureAsync = __esm({
68
69
  "src/useCurveTextureAsync.ts"() {
69
70
  "use strict";
70
- import_meta = {};
71
- curveWorker = null;
72
- curveWorkerCallbacks = /* @__PURE__ */ new Map();
73
- curveWorkerIdCounter = 0;
74
- getCurveWorker = () => {
75
- if (!curveWorker) {
76
- curveWorker = new Worker(new URL("./curveWorker.js", import_meta.url), {
77
- type: "module"
78
- });
79
- curveWorker.onmessage = (e) => {
80
- const { id, rgba } = e.data;
81
- const callback = curveWorkerCallbacks.get(id);
82
- if (callback) {
83
- callback(rgba);
84
- curveWorkerCallbacks.delete(id);
85
- }
86
- };
87
- }
88
- return curveWorker;
89
- };
90
- bakeCurvesAsync = (sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve) => {
91
- return new Promise((resolve) => {
92
- const worker = getCurveWorker();
93
- const id = curveWorkerIdCounter++;
94
- curveWorkerCallbacks.set(id, resolve);
95
- worker.postMessage({
96
- id,
97
- sizeCurve,
98
- opacityCurve,
99
- velocityCurve,
100
- rotationSpeedCurve
101
- });
102
- });
103
- };
104
71
  useCurveTextureAsync = (sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve, curveTexturePath = null) => {
105
72
  const textureRef = useRef(null);
106
- const pendingRef = useRef(null);
107
73
  if (!textureRef.current) {
108
74
  textureRef.current = createDefaultCurveTexture();
109
75
  }
76
+ const hasAnyCurve = sizeCurve || opacityCurve || velocityCurve || rotationSpeedCurve;
77
+ useMemo(() => {
78
+ if (!curveTexturePath && hasAnyCurve && textureRef.current) {
79
+ const bakedTexture = createCombinedCurveTexture(
80
+ sizeCurve,
81
+ opacityCurve,
82
+ velocityCurve,
83
+ rotationSpeedCurve
84
+ );
85
+ const srcData = bakedTexture.image.data;
86
+ const dstData = textureRef.current.image.data;
87
+ if (srcData && dstData) {
88
+ dstData.set(srcData);
89
+ textureRef.current.needsUpdate = true;
90
+ }
91
+ bakedTexture.dispose();
92
+ }
93
+ }, [
94
+ sizeCurve,
95
+ opacityCurve,
96
+ velocityCurve,
97
+ rotationSpeedCurve,
98
+ curveTexturePath,
99
+ hasAnyCurve
100
+ ]);
110
101
  useEffect(() => {
111
- const requestId = {};
112
- pendingRef.current = requestId;
113
- const hasAnyCurve = sizeCurve || opacityCurve || velocityCurve || rotationSpeedCurve;
114
- if (curveTexturePath) {
102
+ if (curveTexturePath && textureRef.current) {
115
103
  loadCurveTextureFromPath(curveTexturePath, textureRef.current).catch(
116
104
  (err) => {
117
105
  console.warn(
118
106
  `Failed to load curve texture: ${curveTexturePath}, falling back to baking`,
119
107
  err
120
108
  );
121
- return bakeCurvesAsync(
122
- sizeCurve,
123
- opacityCurve,
124
- velocityCurve,
125
- rotationSpeedCurve
126
- ).then((rgba) => {
127
- var _a;
128
- if (pendingRef.current === requestId && ((_a = textureRef.current) == null ? void 0 : _a.image.data)) {
129
- textureRef.current.image.data.set(rgba);
109
+ if (hasAnyCurve && textureRef.current) {
110
+ const bakedTexture = createCombinedCurveTexture(
111
+ sizeCurve,
112
+ opacityCurve,
113
+ velocityCurve,
114
+ rotationSpeedCurve
115
+ );
116
+ const srcData = bakedTexture.image.data;
117
+ const dstData = textureRef.current.image.data;
118
+ if (srcData && dstData) {
119
+ dstData.set(srcData);
130
120
  textureRef.current.needsUpdate = true;
131
121
  }
132
- });
122
+ bakedTexture.dispose();
123
+ }
133
124
  }
134
125
  );
135
- } else if (hasAnyCurve) {
136
- bakeCurvesAsync(
137
- sizeCurve,
138
- opacityCurve,
139
- velocityCurve,
140
- rotationSpeedCurve
141
- ).then((rgba) => {
142
- var _a;
143
- if (pendingRef.current === requestId && ((_a = textureRef.current) == null ? void 0 : _a.image.data)) {
144
- textureRef.current.image.data.set(rgba);
145
- textureRef.current.needsUpdate = true;
146
- }
147
- });
148
126
  }
149
- return () => {
150
- pendingRef.current = null;
151
- };
152
127
  }, [
128
+ curveTexturePath,
153
129
  sizeCurve,
154
130
  opacityCurve,
155
131
  velocityCurve,
156
132
  rotationSpeedCurve,
157
- curveTexturePath
133
+ hasAnyCurve
158
134
  ]);
159
135
  useEffect(() => {
160
136
  return () => {
@@ -3630,7 +3606,7 @@ ${" ".repeat(indent - 2)}}`;
3630
3606
  flushChanges();
3631
3607
  }
3632
3608
  const values2 = valuesRef.current;
3633
- const CURVE_RESOLUTION2 = 256;
3609
+ const CURVE_RESOLUTION = 256;
3634
3610
  const evaluateBezierSegment = (t, p0, p1, h0Out, h1In) => {
3635
3611
  const cp0 = p0;
3636
3612
  const cp1 = [p0[0] + ((h0Out == null ? void 0 : h0Out[0]) || 0), p0[1] + ((h0Out == null ? void 0 : h0Out[1]) || 0)];
@@ -3687,23 +3663,23 @@ ${" ".repeat(indent - 2)}}`;
3687
3663
  return Math.max(-0.5, Math.min(1.5, py));
3688
3664
  };
3689
3665
  const bakeCurveToArray2 = (curveData) => {
3690
- const data = new Float32Array(CURVE_RESOLUTION2);
3666
+ const data = new Float32Array(CURVE_RESOLUTION);
3691
3667
  if (!(curveData == null ? void 0 : curveData.points) || !Array.isArray(curveData.points) || curveData.points.length < 2) {
3692
- for (let i = 0; i < CURVE_RESOLUTION2; i++) {
3693
- data[i] = 1 - i / (CURVE_RESOLUTION2 - 1);
3668
+ for (let i = 0; i < CURVE_RESOLUTION; i++) {
3669
+ data[i] = 1 - i / (CURVE_RESOLUTION - 1);
3694
3670
  }
3695
3671
  return data;
3696
3672
  }
3697
3673
  const firstPoint = curveData.points[0];
3698
3674
  const lastPoint = curveData.points[curveData.points.length - 1];
3699
3675
  if (!(firstPoint == null ? void 0 : firstPoint.pos) || !(lastPoint == null ? void 0 : lastPoint.pos) || !Array.isArray(firstPoint.pos) || !Array.isArray(lastPoint.pos)) {
3700
- for (let i = 0; i < CURVE_RESOLUTION2; i++) {
3701
- data[i] = 1 - i / (CURVE_RESOLUTION2 - 1);
3676
+ for (let i = 0; i < CURVE_RESOLUTION; i++) {
3677
+ data[i] = 1 - i / (CURVE_RESOLUTION - 1);
3702
3678
  }
3703
3679
  return data;
3704
3680
  }
3705
- for (let i = 0; i < CURVE_RESOLUTION2; i++) {
3706
- const x = i / (CURVE_RESOLUTION2 - 1);
3681
+ for (let i = 0; i < CURVE_RESOLUTION; i++) {
3682
+ const x = i / (CURVE_RESOLUTION - 1);
3707
3683
  data[i] = sampleCurveAtX(x, curveData.points);
3708
3684
  }
3709
3685
  return data;
@@ -3712,8 +3688,8 @@ ${" ".repeat(indent - 2)}}`;
3712
3688
  const opacityData = bakeCurveToArray2(values2.fadeOpacityCurve);
3713
3689
  const velocityData = bakeCurveToArray2(values2.velocityCurve);
3714
3690
  const rotationSpeedData = bakeCurveToArray2(values2.rotationSpeedCurve);
3715
- const rgba = new Float32Array(CURVE_RESOLUTION2 * 4);
3716
- for (let i = 0; i < CURVE_RESOLUTION2; i++) {
3691
+ const rgba = new Float32Array(CURVE_RESOLUTION * 4);
3692
+ for (let i = 0; i < CURVE_RESOLUTION; i++) {
3717
3693
  rgba[i * 4] = sizeData[i];
3718
3694
  rgba[i * 4 + 1] = opacityData[i];
3719
3695
  rgba[i * 4 + 2] = velocityData[i];
@@ -5426,7 +5402,7 @@ import {
5426
5402
  useImperativeHandle,
5427
5403
  useEffect as useEffect3,
5428
5404
  useRef as useRef3,
5429
- useMemo,
5405
+ useMemo as useMemo2,
5430
5406
  useCallback as useCallback2,
5431
5407
  useState as useState2
5432
5408
  } from "react";
@@ -5458,7 +5434,7 @@ import {
5458
5434
  Easing as Easing2,
5459
5435
  Lighting,
5460
5436
  bakeCurveToArray,
5461
- createCombinedCurveTexture as createCombinedCurveTexture2
5437
+ createCombinedCurveTexture as createCombinedCurveTexture3
5462
5438
  } from "core-vfx";
5463
5439
  import { jsx as jsx2 } from "react/jsx-runtime";
5464
5440
  var VFXParticles;
@@ -5673,10 +5649,10 @@ var init_VFXParticles = __esm({
5673
5649
  attractors,
5674
5650
  collision
5675
5651
  ]);
5676
- const sizeRange = useMemo(() => toRange(size, [0.1, 0.3]), [size]);
5677
- const speedRange = useMemo(() => toRange(speed, [0.1, 0.1]), [speed]);
5678
- const fadeSizeRange = useMemo(() => toRange(fadeSize, [1, 0]), [fadeSize]);
5679
- const fadeOpacityRange = useMemo(
5652
+ const sizeRange = useMemo2(() => toRange(size, [0.1, 0.3]), [size]);
5653
+ const speedRange = useMemo2(() => toRange(speed, [0.1, 0.1]), [speed]);
5654
+ const fadeSizeRange = useMemo2(() => toRange(fadeSize, [1, 0]), [fadeSize]);
5655
+ const fadeOpacityRange = useMemo2(
5680
5656
  () => toRange(fadeOpacity, [1, 0]),
5681
5657
  [fadeOpacity]
5682
5658
  );
@@ -5696,26 +5672,26 @@ var init_VFXParticles = __esm({
5696
5672
  }
5697
5673
  };
5698
5674
  }, [curveTexture]);
5699
- const lifetimeRange = useMemo(() => toRange(lifetime, [1, 2]), [lifetime]);
5700
- const rotation3D = useMemo(() => toRotation3D(rotation), [rotation]);
5701
- const rotationSpeed3D = useMemo(
5675
+ const lifetimeRange = useMemo2(() => toRange(lifetime, [1, 2]), [lifetime]);
5676
+ const rotation3D = useMemo2(() => toRotation3D(rotation), [rotation]);
5677
+ const rotationSpeed3D = useMemo2(
5702
5678
  () => toRotation3D(rotationSpeed),
5703
5679
  [rotationSpeed]
5704
5680
  );
5705
- const direction3D = useMemo(() => toRotation3D(direction), [direction]);
5706
- const startPosition3D = useMemo(
5681
+ const direction3D = useMemo2(() => toRotation3D(direction), [direction]);
5682
+ const startPosition3D = useMemo2(
5707
5683
  () => toRotation3D(startPosition),
5708
5684
  [startPosition]
5709
5685
  );
5710
- const emitterRadiusRange = useMemo(
5686
+ const emitterRadiusRange = useMemo2(
5711
5687
  () => toRange(emitterRadius, [0, 1]),
5712
5688
  [emitterRadius]
5713
5689
  );
5714
- const emitterHeightRange = useMemo(
5690
+ const emitterHeightRange = useMemo2(
5715
5691
  () => toRange(emitterHeight, [0, 1]),
5716
5692
  [emitterHeight]
5717
5693
  );
5718
- const activeFeatures = useMemo(
5694
+ const activeFeatures = useMemo2(
5719
5695
  () => ({
5720
5696
  // Storage array features
5721
5697
  needsPerParticleColor: activeNeedsPerParticleColor,
@@ -5735,33 +5711,33 @@ var init_VFXParticles = __esm({
5735
5711
  activeCollision
5736
5712
  ]
5737
5713
  );
5738
- const frictionIntensityRange = useMemo(() => {
5714
+ const frictionIntensityRange = useMemo2(() => {
5739
5715
  if (typeof friction === "object" && friction !== null && "intensity" in friction) {
5740
5716
  return toRange(friction.intensity, [0, 0]);
5741
5717
  }
5742
5718
  return [0, 0];
5743
5719
  }, [friction]);
5744
- const frictionEasingType = useMemo(() => {
5720
+ const frictionEasingType = useMemo2(() => {
5745
5721
  var _a2;
5746
5722
  if (typeof friction === "object" && friction !== null && "easing" in friction) {
5747
5723
  return easingToType((_a2 = friction.easing) != null ? _a2 : "linear");
5748
5724
  }
5749
5725
  return 0;
5750
5726
  }, [friction]);
5751
- const startColors = useMemo(() => {
5727
+ const startColors = useMemo2(() => {
5752
5728
  const colors = colorStart.slice(0, 8).map(hexToRgb);
5753
5729
  while (colors.length < 8)
5754
5730
  colors.push(colors[colors.length - 1] || [1, 1, 1]);
5755
5731
  return colors;
5756
5732
  }, [colorStart]);
5757
5733
  const effectiveColorEnd = colorEnd != null ? colorEnd : colorStart;
5758
- const endColors = useMemo(() => {
5734
+ const endColors = useMemo2(() => {
5759
5735
  const colors = effectiveColorEnd.slice(0, 8).map(hexToRgb);
5760
5736
  while (colors.length < 8)
5761
5737
  colors.push(colors[colors.length - 1] || [1, 1, 1]);
5762
5738
  return colors;
5763
5739
  }, [effectiveColorEnd]);
5764
- const uniforms = useMemo(
5740
+ const uniforms = useMemo2(
5765
5741
  () => {
5766
5742
  var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5767
5743
  return {
@@ -6060,7 +6036,7 @@ var init_VFXParticles = __esm({
6060
6036
  orientAxis,
6061
6037
  stretchBySpeed
6062
6038
  ]);
6063
- const storage = useMemo(() => {
6039
+ const storage = useMemo2(() => {
6064
6040
  const arrays = {
6065
6041
  positions: instancedArray(activeMaxParticles, "vec3"),
6066
6042
  velocities: instancedArray(activeMaxParticles, "vec3"),
@@ -6085,15 +6061,15 @@ var init_VFXParticles = __esm({
6085
6061
  activeFeatures.needsRotation,
6086
6062
  activeFeatures.needsPerParticleColor
6087
6063
  ]);
6088
- const computeInit = useMemo(
6064
+ const computeInit = useMemo2(
6089
6065
  () => createInitCompute(storage, activeMaxParticles),
6090
6066
  [storage, activeMaxParticles]
6091
6067
  );
6092
- const computeSpawn = useMemo(
6068
+ const computeSpawn = useMemo2(
6093
6069
  () => createSpawnCompute(storage, uniforms, activeMaxParticles),
6094
6070
  [storage, uniforms, activeMaxParticles]
6095
6071
  );
6096
- const computeUpdate = useMemo(
6072
+ const computeUpdate = useMemo2(
6097
6073
  () => createUpdateCompute(
6098
6074
  storage,
6099
6075
  uniforms,
@@ -6109,7 +6085,7 @@ var init_VFXParticles = __esm({
6109
6085
  ),
6110
6086
  [storage, uniforms, curveTexture, activeMaxParticles, activeFeatures]
6111
6087
  );
6112
- const material = useMemo(
6088
+ const material = useMemo2(
6113
6089
  () => createParticleMaterial(storage, uniforms, curveTexture, {
6114
6090
  alphaMap,
6115
6091
  flipbook,
@@ -6146,7 +6122,7 @@ var init_VFXParticles = __esm({
6146
6122
  activeShadow
6147
6123
  ]
6148
6124
  );
6149
- const renderObject = useMemo(() => {
6125
+ const renderObject = useMemo2(() => {
6150
6126
  if (activeGeometry) {
6151
6127
  const mesh = new THREE2.InstancedMesh(
6152
6128
  activeGeometry,
@@ -6358,7 +6334,7 @@ var init_VFXParticles = __esm({
6358
6334
  nextIndex.current = 0;
6359
6335
  };
6360
6336
  }, []);
6361
- const particleAPI = useMemo(
6337
+ const particleAPI = useMemo2(
6362
6338
  () => ({
6363
6339
  spawn,
6364
6340
  start,
@@ -7148,7 +7124,7 @@ export {
7148
7124
  VFXEmitter,
7149
7125
  VFXParticles,
7150
7126
  bakeCurveToArray,
7151
- createCombinedCurveTexture2 as createCombinedCurveTexture,
7127
+ createCombinedCurveTexture3 as createCombinedCurveTexture,
7152
7128
  useCurveTextureAsync,
7153
7129
  useVFXEmitter,
7154
7130
  useVFXStore
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "r3f-vfx",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -24,7 +24,7 @@
24
24
  "prepublishOnly": "bun run copy-readme"
25
25
  },
26
26
  "dependencies": {
27
- "core-vfx": "0.0.3",
27
+ "core-vfx": "0.0.5",
28
28
  "zustand": "5.0.10"
29
29
  },
30
30
  "devDependencies": {
@@ -1,2 +0,0 @@
1
-
2
- export { }
@@ -1,105 +0,0 @@
1
- // src/curveWorker.js
2
- var CURVE_RESOLUTION = 256;
3
- var evaluateBezierSegment = (t, p0, p1, h0Out, h1In) => {
4
- const cp0 = p0;
5
- const cp1 = [p0[0] + ((h0Out == null ? void 0 : h0Out[0]) || 0), p0[1] + ((h0Out == null ? void 0 : h0Out[1]) || 0)];
6
- const cp2 = [p1[0] + ((h1In == null ? void 0 : h1In[0]) || 0), p1[1] + ((h1In == null ? void 0 : h1In[1]) || 0)];
7
- const cp3 = p1;
8
- const mt = 1 - t;
9
- const mt2 = mt * mt;
10
- const mt3 = mt2 * mt;
11
- const t2 = t * t;
12
- const t3 = t2 * t;
13
- return [
14
- mt3 * cp0[0] + 3 * mt2 * t * cp1[0] + 3 * mt * t2 * cp2[0] + t3 * cp3[0],
15
- mt3 * cp0[1] + 3 * mt2 * t * cp1[1] + 3 * mt * t2 * cp2[1] + t3 * cp3[1]
16
- ];
17
- };
18
- var sampleCurveAtX = (x, points) => {
19
- var _a, _b, _c, _d;
20
- if (!points || points.length < 2) return x;
21
- if (!((_a = points[0]) == null ? void 0 : _a.pos) || !((_b = points[points.length - 1]) == null ? void 0 : _b.pos)) return x;
22
- let segmentIdx = 0;
23
- for (let i = 0; i < points.length - 1; i++) {
24
- if (((_c = points[i]) == null ? void 0 : _c.pos) && ((_d = points[i + 1]) == null ? void 0 : _d.pos) && x >= points[i].pos[0] && x <= points[i + 1].pos[0]) {
25
- segmentIdx = i;
26
- break;
27
- }
28
- }
29
- const p0 = points[segmentIdx];
30
- const p1 = points[segmentIdx + 1];
31
- if (!(p0 == null ? void 0 : p0.pos) || !(p1 == null ? void 0 : p1.pos)) return x;
32
- let tLow = 0;
33
- let tHigh = 1;
34
- let t = 0.5;
35
- for (let iter = 0; iter < 20; iter++) {
36
- const [px] = evaluateBezierSegment(
37
- t,
38
- p0.pos,
39
- p1.pos,
40
- p0.handleOut,
41
- p1.handleIn
42
- );
43
- if (Math.abs(px - x) < 1e-4) break;
44
- if (px < x) {
45
- tLow = t;
46
- } else {
47
- tHigh = t;
48
- }
49
- t = (tLow + tHigh) / 2;
50
- }
51
- const [, py] = evaluateBezierSegment(
52
- t,
53
- p0.pos,
54
- p1.pos,
55
- p0.handleOut,
56
- p1.handleIn
57
- );
58
- return Math.max(-0.5, Math.min(1.5, py));
59
- };
60
- var bakeCurveToArray = (curveData) => {
61
- const data = new Float32Array(CURVE_RESOLUTION);
62
- if (!(curveData == null ? void 0 : curveData.points) || !Array.isArray(curveData.points) || curveData.points.length < 2) {
63
- for (let i = 0; i < CURVE_RESOLUTION; i++) {
64
- data[i] = 1 - i / (CURVE_RESOLUTION - 1);
65
- }
66
- return data;
67
- }
68
- const firstPoint = curveData.points[0];
69
- const lastPoint = curveData.points[curveData.points.length - 1];
70
- if (!(firstPoint == null ? void 0 : firstPoint.pos) || !(lastPoint == null ? void 0 : lastPoint.pos) || !Array.isArray(firstPoint.pos) || !Array.isArray(lastPoint.pos)) {
71
- for (let i = 0; i < CURVE_RESOLUTION; i++) {
72
- data[i] = 1 - i / (CURVE_RESOLUTION - 1);
73
- }
74
- return data;
75
- }
76
- for (let i = 0; i < CURVE_RESOLUTION; i++) {
77
- const x = i / (CURVE_RESOLUTION - 1);
78
- data[i] = sampleCurveAtX(x, curveData.points);
79
- }
80
- return data;
81
- };
82
- var bakeCombinedCurves = (sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve) => {
83
- const sizeData = bakeCurveToArray(sizeCurve);
84
- const opacityData = bakeCurveToArray(opacityCurve);
85
- const velocityData = bakeCurveToArray(velocityCurve);
86
- const rotationSpeedData = bakeCurveToArray(rotationSpeedCurve);
87
- const rgba = new Float32Array(CURVE_RESOLUTION * 4);
88
- for (let i = 0; i < CURVE_RESOLUTION; i++) {
89
- rgba[i * 4] = sizeData[i];
90
- rgba[i * 4 + 1] = opacityData[i];
91
- rgba[i * 4 + 2] = velocityData[i];
92
- rgba[i * 4 + 3] = rotationSpeedData[i];
93
- }
94
- return rgba;
95
- };
96
- self.onmessage = (e) => {
97
- const { id, sizeCurve, opacityCurve, velocityCurve, rotationSpeedCurve } = e.data;
98
- const rgba = bakeCombinedCurves(
99
- sizeCurve,
100
- opacityCurve,
101
- velocityCurve,
102
- rotationSpeedCurve
103
- );
104
- self.postMessage({ id, rgba }, [rgba.buffer]);
105
- };