r3f-vfx 0.0.2 → 0.0.4

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.
Files changed (2) hide show
  1. package/README.md +172 -155
  2. package/package.json +5 -2
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # r3f-vf
1
+ # r3f-vfx
2
2
 
3
3
  High-performance GPU-accelerated particle system for Three.js WebGPU with React Three Fiber.
4
4
 
@@ -21,29 +21,26 @@ npm install r3f-vfx
21
21
  ### Peer Dependencies
22
22
 
23
23
  ```bash
24
- npm install three @react-three/fiber zustand react
24
+ npm install three @react-three/fiber react
25
25
  ```
26
26
 
27
27
  ## Quick Start
28
28
 
29
29
  ```tsx
30
- import { Canvas } from "@react-three/fiber";
31
- import { VFXParticles, Appearance, EmitterShape } from "r3f-vfx";
32
- import * as THREE from "three/webgpu";
30
+ import { Canvas } from '@react-three/fiber';
31
+ import { VFXParticles, Appearance, EmitterShape } from 'r3f-vfx';
32
+ import * as THREE from 'three/webgpu';
33
33
 
34
34
  function App() {
35
35
  return (
36
- <Canvas
37
- renderer
38
- >
39
- <VFXParticles debug/>
36
+ <Canvas>
37
+ <VFXParticles debug />
40
38
  </Canvas>
41
39
  );
42
40
  }
43
41
  ```
44
42
 
45
- That's it, start designing in the debug panel, then copy JSX
46
-
43
+ That's it, start designing in the debug panel, then copy JSX
47
44
 
48
45
  ## API Reference
49
46
 
@@ -53,128 +50,128 @@ The main particle system component.
53
50
 
54
51
  #### Basic Props
55
52
 
56
- | Prop | Type | Default | Description |
57
- |------|------|---------|-------------|
58
- | `name` | `string` | - | Register system for use with VFXEmitter |
59
- | `maxParticles` | `number` | `10000` | Maximum number of particles |
60
- | `autoStart` | `boolean` | `true` | Start emitting automatically |
61
- | `delay` | `number` | `0` | Seconds between emissions (0 = every frame) |
62
- | `emitCount` | `number` | `1` | Particles to emit per burst |
63
- | `position` | `[x, y, z]` | `[0, 0, 0]` | Emitter position |
53
+ | Prop | Type | Default | Description |
54
+ | -------------- | ----------- | ----------- | ------------------------------------------- |
55
+ | `name` | `string` | - | Register system for use with VFXEmitter |
56
+ | `maxParticles` | `number` | `10000` | Maximum number of particles |
57
+ | `autoStart` | `boolean` | `true` | Start emitting automatically |
58
+ | `delay` | `number` | `0` | Seconds between emissions (0 = every frame) |
59
+ | `emitCount` | `number` | `1` | Particles to emit per burst |
60
+ | `position` | `[x, y, z]` | `[0, 0, 0]` | Emitter position |
64
61
 
65
62
  #### Appearance Props
66
63
 
67
- | Prop | Type | Default | Description |
68
- |------|------|---------|-------------|
69
- | `size` | `number \| [min, max]` | `[0.1, 0.3]` | Particle size range |
70
- | `colorStart` | `string[]` | `["#ffffff"]` | Starting colors (random pick) |
71
- | `colorEnd` | `string[] \| null` | `null` | Ending colors (null = no transition) |
72
- | `fadeSize` | `number \| [start, end]` | `[1, 0]` | Size multiplier over lifetime |
73
- | `fadeOpacity` | `number \| [start, end]` | `[1, 0]` | Opacity over lifetime |
74
- | `appearance` | `Appearance` | `GRADIENT` | Shape: `DEFAULT`, `GRADIENT`, `CIRCULAR` |
75
- | `intensity` | `number` | `1` | Color intensity multiplier |
76
- | `blending` | `Blending` | `NORMAL` | Blend mode: `NORMAL`, `ADDITIVE`, `MULTIPLY`, `SUBTRACTIVE` |
64
+ | Prop | Type | Default | Description |
65
+ | ------------- | ------------------------ | ------------- | ----------------------------------------------------------- |
66
+ | `size` | `number \| [min, max]` | `[0.1, 0.3]` | Particle size range |
67
+ | `colorStart` | `string[]` | `["#ffffff"]` | Starting colors (random pick) |
68
+ | `colorEnd` | `string[] \| null` | `null` | Ending colors (null = no transition) |
69
+ | `fadeSize` | `number \| [start, end]` | `[1, 0]` | Size multiplier over lifetime |
70
+ | `fadeOpacity` | `number \| [start, end]` | `[1, 0]` | Opacity over lifetime |
71
+ | `appearance` | `Appearance` | `GRADIENT` | Shape: `DEFAULT`, `GRADIENT`, `CIRCULAR` |
72
+ | `intensity` | `number` | `1` | Color intensity multiplier |
73
+ | `blending` | `Blending` | `NORMAL` | Blend mode: `NORMAL`, `ADDITIVE`, `MULTIPLY`, `SUBTRACTIVE` |
77
74
 
78
75
  #### Physics Props
79
76
 
80
- | Prop | Type | Default | Description |
81
- |------|------|---------|-------------|
82
- | `lifetime` | `number \| [min, max]` | `[1, 2]` | Particle lifetime in seconds |
83
- | `speed` | `number \| [min, max]` | `[0.1, 0.1]` | Initial speed |
84
- | `direction` | `Range3D \| [min, max]` | `[[-1,1], [0,1], [-1,1]]` | Emission direction per axis |
85
- | `gravity` | `[x, y, z]` | `[0, 0, 0]` | Gravity vector |
86
- | `friction` | `FrictionConfig` | `{ intensity: 0 }` | Velocity damping |
77
+ | Prop | Type | Default | Description |
78
+ | ----------- | ----------------------- | ------------------------- | ---------------------------- |
79
+ | `lifetime` | `number \| [min, max]` | `[1, 2]` | Particle lifetime in seconds |
80
+ | `speed` | `number \| [min, max]` | `[0.1, 0.1]` | Initial speed |
81
+ | `direction` | `Range3D \| [min, max]` | `[[-1,1], [0,1], [-1,1]]` | Emission direction per axis |
82
+ | `gravity` | `[x, y, z]` | `[0, 0, 0]` | Gravity vector |
83
+ | `friction` | `FrictionConfig` | `{ intensity: 0 }` | Velocity damping |
87
84
 
88
85
  #### Emitter Shape Props
89
86
 
90
- | Prop | Type | Default | Description |
91
- |------|------|---------|-------------|
92
- | `emitterShape` | `EmitterShape` | `BOX` | Shape: `POINT`, `BOX`, `SPHERE`, `CONE`, `DISK`, `EDGE` |
93
- | `emitterRadius` | `[inner, outer]` | `[0, 1]` | Radius range for sphere/cone/disk |
94
- | `emitterAngle` | `number` | `π/4` | Cone angle in radians |
95
- | `emitterHeight` | `[min, max]` | `[0, 1]` | Height range for cone |
96
- | `emitterDirection` | `[x, y, z]` | `[0, 1, 0]` | Cone/disk normal direction |
97
- | `emitterSurfaceOnly` | `boolean` | `false` | Emit from surface only |
98
- | `startPosition` | `Range3D` | `[[0,0], [0,0], [0,0]]` | Position offset per axis |
87
+ | Prop | Type | Default | Description |
88
+ | -------------------- | ---------------- | ----------------------- | ------------------------------------------------------- |
89
+ | `emitterShape` | `EmitterShape` | `BOX` | Shape: `POINT`, `BOX`, `SPHERE`, `CONE`, `DISK`, `EDGE` |
90
+ | `emitterRadius` | `[inner, outer]` | `[0, 1]` | Radius range for sphere/cone/disk |
91
+ | `emitterAngle` | `number` | `π/4` | Cone angle in radians |
92
+ | `emitterHeight` | `[min, max]` | `[0, 1]` | Height range for cone |
93
+ | `emitterDirection` | `[x, y, z]` | `[0, 1, 0]` | Cone/disk normal direction |
94
+ | `emitterSurfaceOnly` | `boolean` | `false` | Emit from surface only |
95
+ | `startPosition` | `Range3D` | `[[0,0], [0,0], [0,0]]` | Position offset per axis |
99
96
 
100
97
  #### Geometry Mode Props
101
98
 
102
- | Prop | Type | Default | Description |
103
- |------|------|---------|-------------|
104
- | `geometry` | `BufferGeometry` | `null` | Custom particle geometry |
105
- | `lighting` | `Lighting` | `STANDARD` | Material: `BASIC`, `STANDARD`, `PHYSICAL` |
106
- | `shadow` | `boolean` | `false` | Enable shadow casting/receiving |
107
- | `orientToDirection` | `boolean` | `false` | Orient geometry to velocity |
108
- | `orientAxis` | `string` | `"z"` | Axis to align: `"x"`, `"y"`, `"z"`, `"-x"`, `"-y"`, `"-z"` |
109
- | `rotation` | `Range3D \| [min, max]` | `[0, 0]` | Initial rotation per axis |
110
- | `rotationSpeed` | `Range3D \| [min, max]` | `[0, 0]` | Rotation speed rad/s |
99
+ | Prop | Type | Default | Description |
100
+ | ------------------- | ----------------------- | ---------- | ---------------------------------------------------------- |
101
+ | `geometry` | `BufferGeometry` | `null` | Custom particle geometry |
102
+ | `lighting` | `Lighting` | `STANDARD` | Material: `BASIC`, `STANDARD`, `PHYSICAL` |
103
+ | `shadow` | `boolean` | `false` | Enable shadow casting/receiving |
104
+ | `orientToDirection` | `boolean` | `false` | Orient geometry to velocity |
105
+ | `orientAxis` | `string` | `"z"` | Axis to align: `"x"`, `"y"`, `"z"`, `"-x"`, `"-y"`, `"-z"` |
106
+ | `rotation` | `Range3D \| [min, max]` | `[0, 0]` | Initial rotation per axis |
107
+ | `rotationSpeed` | `Range3D \| [min, max]` | `[0, 0]` | Rotation speed rad/s |
111
108
 
112
109
  #### Stretch Props
113
110
 
114
- | Prop | Type | Default | Description |
115
- |------|------|---------|-------------|
116
- | `stretchBySpeed` | `StretchConfig` | `null` | Stretch particles by velocity |
111
+ | Prop | Type | Default | Description |
112
+ | ---------------- | --------------- | ------- | ----------------------------- |
113
+ | `stretchBySpeed` | `StretchConfig` | `null` | Stretch particles by velocity |
117
114
 
118
115
  ```ts
119
116
  interface StretchConfig {
120
- factor: number; // Stretch multiplier
117
+ factor: number; // Stretch multiplier
121
118
  maxStretch: number; // Maximum stretch amount
122
119
  }
123
120
  ```
124
121
 
125
122
  #### Turbulence Props
126
123
 
127
- | Prop | Type | Default | Description |
128
- |------|------|---------|-------------|
129
- | `turbulence` | `TurbulenceConfig` | `null` | Curl noise turbulence |
124
+ | Prop | Type | Default | Description |
125
+ | ------------ | ------------------ | ------- | --------------------- |
126
+ | `turbulence` | `TurbulenceConfig` | `null` | Curl noise turbulence |
130
127
 
131
128
  ```ts
132
129
  interface TurbulenceConfig {
133
- intensity: number; // Turbulence strength
134
- frequency: number; // Noise scale
135
- speed: number; // Animation speed
130
+ intensity: number; // Turbulence strength
131
+ frequency: number; // Noise scale
132
+ speed: number; // Animation speed
136
133
  }
137
134
  ```
138
135
 
139
136
  #### Attractor Props
140
137
 
141
- | Prop | Type | Default | Description |
142
- |------|------|---------|-------------|
143
- | `attractors` | `AttractorConfig[]` | `null` | Up to 4 attractors |
144
- | `attractToCenter` | `boolean` | `false` | Pull particles to emitter center |
138
+ | Prop | Type | Default | Description |
139
+ | ----------------- | ------------------- | ------- | -------------------------------- |
140
+ | `attractors` | `AttractorConfig[]` | `null` | Up to 4 attractors |
141
+ | `attractToCenter` | `boolean` | `false` | Pull particles to emitter center |
145
142
 
146
143
  ```ts
147
144
  interface AttractorConfig {
148
145
  position: [x, y, z];
149
- strength: number; // Positive = attract, negative = repel
150
- radius?: number; // 0 = infinite range
151
- type?: "point" | "vortex";
152
- axis?: [x, y, z]; // Vortex rotation axis
146
+ strength: number; // Positive = attract, negative = repel
147
+ radius?: number; // 0 = infinite range
148
+ type?: 'point' | 'vortex';
149
+ axis?: [x, y, z]; // Vortex rotation axis
153
150
  }
154
151
  ```
155
152
 
156
153
  #### Collision Props
157
154
 
158
- | Prop | Type | Default | Description |
159
- |------|------|---------|-------------|
160
- | `collision` | `CollisionConfig` | `null` | Plane collision |
155
+ | Prop | Type | Default | Description |
156
+ | ----------- | ----------------- | ------- | --------------- |
157
+ | `collision` | `CollisionConfig` | `null` | Plane collision |
161
158
 
162
159
  ```ts
163
160
  interface CollisionConfig {
164
- plane: { y: number }; // Plane Y position
165
- bounce?: number; // Bounce factor (0-1)
166
- friction?: number; // Horizontal friction
167
- die?: boolean; // Kill on collision
161
+ plane: { y: number }; // Plane Y position
162
+ bounce?: number; // Bounce factor (0-1)
163
+ friction?: number; // Horizontal friction
164
+ die?: boolean; // Kill on collision
168
165
  sizeBasedGravity?: number; // Gravity multiplier by size
169
166
  }
170
167
  ```
171
168
 
172
169
  #### Soft Particles Props
173
170
 
174
- | Prop | Type | Default | Description |
175
- |------|------|---------|-------------|
176
- | `softParticles` | `boolean` | `false` | Fade near geometry |
177
- | `softDistance` | `number` | `0.5` | Fade distance in world units |
171
+ | Prop | Type | Default | Description |
172
+ | --------------- | --------- | ------- | ---------------------------- |
173
+ | `softParticles` | `boolean` | `false` | Fade near geometry |
174
+ | `softDistance` | `number` | `0.5` | Fade distance in world units |
178
175
 
179
176
  #### Curve Props
180
177
 
@@ -183,55 +180,55 @@ All curves use Bezier spline format:
183
180
  ```ts
184
181
  interface CurveData {
185
182
  points: Array<{
186
- pos: [x, y]; // Position (x: 0-1 progress, y: value)
187
- handleIn?: [x, y]; // Bezier handle in (offset)
188
- handleOut?: [x, y]; // Bezier handle out (offset)
183
+ pos: [x, y]; // Position (x: 0-1 progress, y: value)
184
+ handleIn?: [x, y]; // Bezier handle in (offset)
185
+ handleOut?: [x, y]; // Bezier handle out (offset)
189
186
  }>;
190
187
  }
191
188
  ```
192
189
 
193
- | Prop | Type | Description |
194
- |------|------|-------------|
195
- | `fadeSizeCurve` | `CurveData` | Size multiplier over lifetime |
196
- | `fadeOpacityCurve` | `CurveData` | Opacity over lifetime |
197
- | `velocityCurve` | `CurveData` | Velocity multiplier (overrides friction) |
198
- | `rotationSpeedCurve` | `CurveData` | Rotation speed multiplier |
190
+ | Prop | Type | Description |
191
+ | -------------------- | ----------- | ---------------------------------------- |
192
+ | `fadeSizeCurve` | `CurveData` | Size multiplier over lifetime |
193
+ | `fadeOpacityCurve` | `CurveData` | Opacity over lifetime |
194
+ | `velocityCurve` | `CurveData` | Velocity multiplier (overrides friction) |
195
+ | `rotationSpeedCurve` | `CurveData` | Rotation speed multiplier |
199
196
 
200
197
  #### Custom Shader Props
201
198
 
202
- | Prop | Type | Description |
203
- |------|------|-------------|
204
- | `colorNode` | `NodeFunction` | Custom color shader |
205
- | `opacityNode` | `NodeFunction` | Custom opacity shader |
206
- | `backdropNode` | `NodeFunction` | Backdrop sampling (refraction) |
207
- | `castShadowNode` | `NodeFunction` | Shadow map output |
208
- | `alphaTestNode` | `NodeFunction` | Alpha test/discard |
199
+ | Prop | Type | Description |
200
+ | ---------------- | -------------- | ------------------------------ |
201
+ | `colorNode` | `NodeFunction` | Custom color shader |
202
+ | `opacityNode` | `NodeFunction` | Custom opacity shader |
203
+ | `backdropNode` | `NodeFunction` | Backdrop sampling (refraction) |
204
+ | `castShadowNode` | `NodeFunction` | Shadow map output |
205
+ | `alphaTestNode` | `NodeFunction` | Alpha test/discard |
209
206
 
210
207
  ```ts
211
208
  type NodeFunction = (data: ParticleData, defaultColor?: Node) => Node;
212
209
 
213
210
  interface ParticleData {
214
- progress: Node; // 0 → 1 over lifetime
215
- lifetime: Node; // 1 → 0 over lifetime
216
- position: Node; // vec3 world position
217
- velocity: Node; // vec3 velocity
218
- size: Node; // float size
219
- rotation: Node; // vec3 rotation
220
- colorStart: Node; // vec3 start color
221
- colorEnd: Node; // vec3 end color
222
- color: Node; // vec3 interpolated color
211
+ progress: Node; // 0 → 1 over lifetime
212
+ lifetime: Node; // 1 → 0 over lifetime
213
+ position: Node; // vec3 world position
214
+ velocity: Node; // vec3 velocity
215
+ size: Node; // float size
216
+ rotation: Node; // vec3 rotation
217
+ colorStart: Node; // vec3 start color
218
+ colorEnd: Node; // vec3 end color
219
+ color: Node; // vec3 interpolated color
223
220
  intensifiedColor: Node; // color × intensity
224
- shapeMask: Node; // float alpha mask
225
- index: Node; // particle index
221
+ shapeMask: Node; // float alpha mask
222
+ index: Node; // particle index
226
223
  }
227
224
  ```
228
225
 
229
226
  #### Texture Props
230
227
 
231
- | Prop | Type | Description |
232
- |------|------|-------------|
233
- | `alphaMap` | `Texture` | Alpha/shape texture |
234
- | `flipbook` | `FlipbookConfig` | Animated flipbook |
228
+ | Prop | Type | Description |
229
+ | ---------- | ---------------- | ------------------- |
230
+ | `alphaMap` | `Texture` | Alpha/shape texture |
231
+ | `flipbook` | `FlipbookConfig` | Animated flipbook |
235
232
 
236
233
  ```ts
237
234
  interface FlipbookConfig {
@@ -261,31 +258,31 @@ Decoupled emitter component that links to a VFXParticles system.
261
258
 
262
259
  #### Props
263
260
 
264
- | Prop | Type | Default | Description |
265
- |------|------|---------|-------------|
266
- | `name` | `string` | - | Name of VFXParticles system |
267
- | `particlesRef` | `Ref<ParticleAPI>` | - | Direct ref (alternative to name) |
268
- | `position` | `[x, y, z]` | `[0, 0, 0]` | Local position offset |
269
- | `emitCount` | `number` | `10` | Particles per burst |
270
- | `delay` | `number` | `0` | Seconds between emissions |
271
- | `autoStart` | `boolean` | `true` | Start emitting automatically |
272
- | `loop` | `boolean` | `true` | Keep emitting (false = once) |
273
- | `localDirection` | `boolean` | `false` | Transform direction by parent rotation |
274
- | `direction` | `Range3D` | - | Direction override |
275
- | `overrides` | `SpawnOverrides` | - | Per-spawn property overrides |
276
- | `onEmit` | `function` | - | Callback after each emission |
261
+ | Prop | Type | Default | Description |
262
+ | ---------------- | ------------------ | ----------- | -------------------------------------- |
263
+ | `name` | `string` | - | Name of VFXParticles system |
264
+ | `particlesRef` | `Ref<ParticleAPI>` | - | Direct ref (alternative to name) |
265
+ | `position` | `[x, y, z]` | `[0, 0, 0]` | Local position offset |
266
+ | `emitCount` | `number` | `10` | Particles per burst |
267
+ | `delay` | `number` | `0` | Seconds between emissions |
268
+ | `autoStart` | `boolean` | `true` | Start emitting automatically |
269
+ | `loop` | `boolean` | `true` | Keep emitting (false = once) |
270
+ | `localDirection` | `boolean` | `false` | Transform direction by parent rotation |
271
+ | `direction` | `Range3D` | - | Direction override |
272
+ | `overrides` | `SpawnOverrides` | - | Per-spawn property overrides |
273
+ | `onEmit` | `function` | - | Callback after each emission |
277
274
 
278
275
  #### Ref Methods
279
276
 
280
277
  ```ts
281
278
  interface VFXEmitterAPI {
282
- emit(): boolean; // Emit at current position
279
+ emit(): boolean; // Emit at current position
283
280
  burst(count?: number): boolean; // Burst emit
284
- start(): void; // Start auto-emission
285
- stop(): void; // Stop auto-emission
286
- isEmitting: boolean; // Current state
281
+ start(): void; // Start auto-emission
282
+ stop(): void; // Stop auto-emission
283
+ isEmitting: boolean; // Current state
287
284
  getParticleSystem(): ParticleAPI;
288
- group: THREE.Group; // The group element
285
+ group: THREE.Group; // The group element
289
286
  }
290
287
  ```
291
288
 
@@ -295,10 +292,10 @@ Programmatic emitter control.
295
292
 
296
293
  ```tsx
297
294
  function MyComponent() {
298
- const { emit, burst, start, stop } = useVFXEmitter("sparks");
295
+ const { emit, burst, start, stop } = useVFXEmitter('sparks');
299
296
 
300
297
  const handleClick = () => {
301
- burst([0, 1, 0], 100, { colorStart: ["#ff0000"] });
298
+ burst([0, 1, 0], 100, { colorStart: ['#ff0000'] });
302
299
  };
303
300
 
304
301
  return <mesh onClick={handleClick}>...</mesh>;
@@ -309,8 +306,16 @@ function MyComponent() {
309
306
 
310
307
  ```ts
311
308
  interface UseVFXEmitterResult {
312
- emit(position?: [x,y,z], count?: number, overrides?: SpawnOverrides): boolean;
313
- burst(position?: [x,y,z], count?: number, overrides?: SpawnOverrides): boolean;
309
+ emit(
310
+ position?: [x, y, z],
311
+ count?: number,
312
+ overrides?: SpawnOverrides
313
+ ): boolean;
314
+ burst(
315
+ position?: [x, y, z],
316
+ count?: number,
317
+ overrides?: SpawnOverrides
318
+ ): boolean;
314
319
  start(): boolean;
315
320
  stop(): boolean;
316
321
  clear(): boolean;
@@ -328,14 +333,14 @@ Zustand store for managing particle systems.
328
333
  const store = useVFXStore();
329
334
 
330
335
  // Access registered particle systems
331
- const sparks = store.getParticles("sparks");
336
+ const sparks = store.getParticles('sparks');
332
337
  sparks?.spawn(0, 0, 0, 50);
333
338
 
334
339
  // Store methods
335
- store.emit("sparks", { x: 0, y: 0, z: 0, count: 20 });
336
- store.start("sparks");
337
- store.stop("sparks");
338
- store.clear("sparks");
340
+ store.emit('sparks', { x: 0, y: 0, z: 0, count: 20 });
341
+ store.start('sparks');
342
+ store.stop('sparks');
343
+ store.clear('sparks');
339
344
  ```
340
345
 
341
346
  ## Examples
@@ -346,15 +351,19 @@ store.clear("sparks");
346
351
  <VFXParticles
347
352
  maxParticles={3000}
348
353
  size={[0.3, 0.8]}
349
- colorStart={["#ff6600", "#ffcc00", "#ff0000"]}
350
- colorEnd={["#ff0000", "#330000"]}
354
+ colorStart={['#ff6600', '#ffcc00', '#ff0000']}
355
+ colorEnd={['#ff0000', '#330000']}
351
356
  fadeSize={[1, 0.2]}
352
357
  fadeOpacity={[1, 0]}
353
358
  gravity={[0, 0.5, 0]}
354
359
  lifetime={[0.4, 0.8]}
355
- direction={[[-0.3, 0.3], [0.5, 1], [-0.3, 0.3]]}
360
+ direction={[
361
+ [-0.3, 0.3],
362
+ [0.5, 1],
363
+ [-0.3, 0.3],
364
+ ]}
356
365
  speed={[0.01, 0.05]}
357
- friction={{ intensity: 0.03, easing: "easeOut" }}
366
+ friction={{ intensity: 0.03, easing: 'easeOut' }}
358
367
  appearance={Appearance.GRADIENT}
359
368
  intensity={10}
360
369
  />
@@ -366,7 +375,7 @@ store.clear("sparks");
366
375
  <VFXParticles
367
376
  maxParticles={500}
368
377
  size={[0.05, 0.1]}
369
- colorStart={["#00ffff", "#0088ff"]}
378
+ colorStart={['#00ffff', '#0088ff']}
370
379
  fadeOpacity={[1, 0]}
371
380
  lifetime={[1, 2]}
372
381
  emitterShape={EmitterShape.SPHERE}
@@ -379,19 +388,23 @@ store.clear("sparks");
379
388
  ### 3D Geometry Particles
380
389
 
381
390
  ```tsx
382
- import { BoxGeometry } from "three/webgpu";
391
+ import { BoxGeometry } from 'three/webgpu';
383
392
 
384
393
  <VFXParticles
385
394
  geometry={new BoxGeometry(1, 1, 1)}
386
395
  maxParticles={500}
387
396
  size={[0.1, 0.2]}
388
- colorStart={["#ff00ff", "#aa00ff"]}
397
+ colorStart={['#ff00ff', '#aa00ff']}
389
398
  gravity={[0, -2, 0]}
390
399
  lifetime={[1, 2]}
391
- rotation={[[0, Math.PI * 2], [0, Math.PI * 2], [0, Math.PI * 2]]}
400
+ rotation={[
401
+ [0, Math.PI * 2],
402
+ [0, Math.PI * 2],
403
+ [0, Math.PI * 2],
404
+ ]}
392
405
  shadow={true}
393
406
  lighting={Lighting.STANDARD}
394
- />
407
+ />;
395
408
  ```
396
409
 
397
410
  ### Turbulent Smoke
@@ -400,13 +413,17 @@ import { BoxGeometry } from "three/webgpu";
400
413
  <VFXParticles
401
414
  maxParticles={300}
402
415
  size={[0.3, 0.6]}
403
- colorStart={["#666666", "#888888"]}
404
- colorEnd={["#333333"]}
416
+ colorStart={['#666666', '#888888']}
417
+ colorEnd={['#333333']}
405
418
  fadeSize={[0.5, 1.5]}
406
419
  fadeOpacity={[0.6, 0]}
407
420
  gravity={[0, 0.5, 0]}
408
421
  lifetime={[3, 5]}
409
- direction={[[-0.1, 0.1], [0.3, 0.5], [-0.1, 0.1]]}
422
+ direction={[
423
+ [-0.1, 0.1],
424
+ [0.3, 0.5],
425
+ [-0.1, 0.1],
426
+ ]}
410
427
  speed={[0.02, 0.05]}
411
428
  turbulence={{
412
429
  intensity: 1.2,
@@ -447,9 +464,9 @@ import type {
447
464
  TurbulenceConfig,
448
465
  CollisionConfig,
449
466
  AttractorConfig,
450
- } from "r3f-vfx";
467
+ } from 'r3f-vfx';
451
468
  ```
452
469
 
453
470
  ## License
454
471
 
455
- MIT
472
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "r3f-vfx",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -19,9 +19,12 @@
19
19
  "scripts": {
20
20
  "dev": "tsup --watch",
21
21
  "build": "tsup",
22
- "typecheck": "tsc"
22
+ "typecheck": "tsc",
23
+ "copy-readme": "cp ../../README.md README.md",
24
+ "prepublishOnly": "bun run typecheck && bun run build && bun run copy-readme"
23
25
  },
24
26
  "dependencies": {
27
+ "core-vfx": "0.0.1",
25
28
  "zustand": "5.0.10"
26
29
  },
27
30
  "devDependencies": {