# quarks.r3f React Three Fiber integration for [three.quarks](https://github.com/Alchemist0823/three.quarks) particle systems. ## Installation ```bash npm install quarks.r3f three.quarks ``` ## Quick Start ```tsx import { Canvas } from '@react-three/fiber' import { QuarksProvider, ParticleSystem } from 'quarks.r3f' import { ConeEmitter, SizeOverLife, PiecewiseBezier, Bezier, RenderMode } from 'three.quarks' function FireEffect() { const shape = useMemo(() => new ConeEmitter({ angle: 0.3, radius: 0.2 }), []) const behaviors = useMemo(() => [ new SizeOverLife(new PiecewiseBezier([[new Bezier(1, 0.8, 0.4, 0), 0]])) ], []) return ( ) } function App() { return ( ) } ``` ## Components ### `` Required wrapper component that manages the `BatchedRenderer` for all child particle systems. ```tsx {/* All particle systems must be children of QuarksProvider */} ``` ### `` Declarative particle system component with flexible prop types. **Props:** | Prop | Type | Description | |------|------|-------------| | `duration` | `number` | System duration in seconds | | `looping` | `boolean` | Whether to loop the system | | `startLife` | `number \| [min, max] \| ValueGenerator` | Particle lifetime | | `startSpeed` | `number \| [min, max] \| ValueGenerator` | Initial particle speed | | `startSize` | `number \| [min, max] \| ValueGenerator` | Initial particle size | | `startColor` | `{r,g,b,a} \| ColorGenerator` | Initial particle color | | `startRotation` | `number \| [min, max] \| ValueGenerator` | Initial rotation | | `emissionOverTime` | `number \| [min, max] \| ValueGenerator` | Particles per second | | `shape` | `EmitterShape` | Emitter shape (ConeEmitter, SphereEmitter, etc.) | | `material` | `Material` | Three.js material for particles | | `renderMode` | `RenderMode` | BillBoard, StretchedBillBoard, Mesh, Trail | | `behaviors` | `Behavior[]` | Array of particle behaviors | | `uTileCount` | `number` | Texture atlas horizontal tiles | | `vTileCount` | `number` | Texture atlas vertical tiles | | `worldSpace` | `boolean` | Emit in world space | | `position` | `[x, y, z]` | Emitter position | | `rotation` | `[x, y, z]` | Emitter rotation (Euler angles) | | `scale` | `[x, y, z]` | Emitter scale | | `autoPlay` | `boolean` | Start playing automatically (default: true) | **Ref API:** ```tsx const systemRef = useRef(null) // Control methods systemRef.current.play() systemRef.current.pause() systemRef.current.restart() systemRef.current.stop() // Access underlying objects systemRef.current.system // ParticleSystem instance systemRef.current.emitter // ParticleEmitter (Object3D) ``` ### `` Load particle effects from JSON files with React Suspense support. ```tsx import { Suspense } from 'react' import { QuarksEffect } from 'quarks.r3f' function MyEffect() { return ( ) } // Preload effects QuarksEffect.preload('/effects/explosion.json') ``` ## Hooks ### `useQuarks()` Access the BatchedRenderer from context. ```tsx import { useQuarks } from 'quarks.r3f' function MyComponent() { const { batchedRenderer } = useQuarks() // Use for advanced operations } ``` ### `useParticleSystem(props)` Imperative hook for creating particle systems. ```tsx import { useParticleSystem } from 'quarks.r3f' function MyParticles() { const { system, emitter, play, pause, restart } = useParticleSystem({ duration: 5, looping: true, startLife: [1, 2], // ... other props }) return } ``` ### `useQuarksEffect(url)` Hook for loading JSON effects with Suspense. ```tsx import { useQuarksEffect } from 'quarks.r3f' function MyEffect() { const { group, systems, play, pause, restart } = useQuarksEffect('/effect.json') return } // Preload useQuarksEffect.preload('/effect.json') ``` ## Flexible Prop Types Props like `startLife`, `startSpeed`, `startSize`, and `emissionOverTime` accept flexible types: ```tsx // Constant value startLife={2} // Random range [min, max] startLife={[1, 3]} // ValueGenerator from three.quarks startLife={new IntervalValue(1, 3)} startLife={new PiecewiseBezier([[new Bezier(1, 2, 3, 4), 0]])} ``` ## Behaviors Use behaviors from `three.quarks` to animate particles over their lifetime: ```tsx import { SizeOverLife, ColorOverLife, SpeedOverLife, RotationOverLife, Gradient, PiecewiseBezier, Bezier, Vector4, } from 'three.quarks' const behaviors = useMemo(() => [ // Size fades out new SizeOverLife(new PiecewiseBezier([[new Bezier(1, 0.8, 0.4, 0), 0]])), // Color gradient new ColorOverLife(new Gradient([ [new Vector4(1, 0.8, 0.2, 1), 0], [new Vector4(1, 0.3, 0.1, 1), 0.5], [new Vector4(0.5, 0.1, 0.1, 0), 1], ])), // Speed decay new SpeedOverLife(new PiecewiseBezier([[new Bezier(1, 0.5, 0.2, 0), 0]])), ], []) ``` ## Emitter Shapes ```tsx import { ConeEmitter, SphereEmitter, PointEmitter } from 'three.quarks' // Cone emitter (good for fire, fountains) const cone = new ConeEmitter({ angle: 0.3, radius: 0.2, arc: Math.PI * 2 }) // Sphere emitter (good for explosions, magic effects) const sphere = new SphereEmitter({ radius: 0.5, thickness: 0.2 }) // Point emitter const point = new PointEmitter() ``` ## License MIT