A React Native wrapper for iOS's CAEmitterLayer
Create powerful and performant particle effects for your React Native apps!
Installation | Basic Usage | Documentation/API | Roadmap | Acknowledgements
Add this package to your app with the following command:
npx expo install react-native-caemitterlayer
โ ๏ธ This module is built on Expo Modules API and thus requires Expo 47 or above. If your project is a "vanilla" React Native application, consider adding Expo to it to utilize the Expo ecosystem.
โน๏ธ If not already, you will have to adopt Expo prebuild or Expo dev builds to make use of custom native modules.
EmitterView requires an emitterConfig prop, which contains the configuration for the underlying CAEmitterLayer and its associated CAEmitterCells.
import { View } from 'react-native'
import { EmitterConfigPropType, EmitterView } from 'react-native-caemitterlayer'
const circle = require('../assets/contents/circle.png')
export function BasicExample() {
const emitterConfig: EmitterConfigPropType = {
layer: {
// center the emission point in the middle of top edge of the view
emitterPosition: {
x: 50,
y: 0,
},
emitterCells: [
{
imageContents: circle, // image require'd by Metro bundler
color: '#006699',
lifetime: 5, // particles live for 5 seconds
velocity: 20,
birthRate: 1, // One particle per second
emissionLongitude: -Math.PI / 2, // emit particles up
emissionRange: Math.PI / 4, // emit particles in a 45 degree cone
},
],
},
}
return (
<View
style={{
width: '100%',
height: '100%',
justifyContent: 'center',
alignItems: 'center',
}}>
<EmitterView
emitterConfig={emitterConfig}
style={{ width: 100, height: 100, backgroundColor: 'teal' }}
/>
</View>
)
}The code above produces this:
Check out the example app for more in depth and powerful examples.
import { EmitterView } from 'react-native-caemitterlayer';
<EmitterView
emitterConfig={...}
/>Props
The CAEmitterLayer configuration for this EmitterView. See below for how to configure this prop, or check out the example app's examples for working examples.
Configures the single CAEmitterLayer which will render particles.
Whether or not the emitter is enabled. Defaults to true.
Values which are applied to the CAEmitterLayer on mount and whenever the layer transitions from enabled: false -> enabled: true.
This is useful for setting certain CAMediaTiming properties which should only be set once (e.g. beginTime).
An array of EmitterCellType objects which act as templates for the particles emitted by the layer.
Each property on the EmitterCellType is optional and has the same defaults as the corresponding property on CAEmitterCell. See the CAEmitterCell docs for details on each property.
The rest of the properties on emitterConfig.layer are passed directly to the CAEmitterLayer instance (if set) and have the same defaults they would on CAEmitterLayer. See the CAEmitterLayer docs for details on each property.
EmitterView also accepts all the same ViewProps props (i.e. style) as a React Native View.
Future plans for features/enhancements/fixes (in no particular order/priority):
-
Better image support โ - Shipped in
v0.3.0This library currently requires inlining of the images used for emitter cells (viaEmitterCellType.imageData). The images must be represented as base64 encoded strings on the JS side. This isn't ideal for performance or developer ergonomics. A better way of handling images is high priority. -
Better animation support
It's currently not possible to animate
EmitterViewdirectly via RN Animated or Reanmiated. Will be looking at ways to support this to avoid having to wrap the<EmitterView>in an<Animated.View>or similar. -
Support placeholders for
emitterPositionandemitterSize.emitterPositionandemitterSizerequire specifying exact coordinates/sizes. For some uses,useWindowDimensionsmay be sufficient. However, due to the nature of how React Native renders things, you may have to wait untilonLayoutis called before knowing what to set these values to. Adding placeholder values/strings could reduce the need foronLayout/useWindowDimensionsas we could then setemitterSize/emitterPositionon the native side. -
Support emoji as emitter cell contents.
-
Support drawing basic images to be used in emitter cells (circle, oval, rect, triangle, etc)
-
Possible animation support of layer or cell properties - either via Animated/Reanimated or basic
CAAnimations
Android support is not planned at this time. Android does not contain a built in particle emitter engine. I've explored various options but there's drawbacks to each. I've also investigated building one myself. However, it would take much effort reach parity with CAEmitterLayer.
A number of blog posts helped immensely with learning CAEmitterLayer. These authors also provided great examples which were used to test this library's functionality:
- https://nshipster.com/caemitterlayer/ by @Mattt
- https://bryce.co/caemitterbehavior/ by @brycepauken
- https://bryce.co/recreating-imessage-confetti/ by @brycepauken
- https://medium.com/@peteliev/what-do-you-know-about-caemitterlayer-368378d45c2e by @peteliev
MIT

