Skip to content

DigitalZebra/react-native-caemitterlayer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

26 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

react-native-caemitterlayer

A React Native wrapper for iOS's CAEmitterLayer

Create powerful and performant particle effects for your React Native apps!

a GIF of a view emitting flames from the top

Installation | Basic Usage | Documentation/API | Roadmap | Acknowledgements

๐Ÿ’ฟ Installation

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.

๐Ÿ”ฅ Basic Usage

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:

a GIF of a view emitting circles from the top.

Check out the example app for more in depth and powerful examples.

๐Ÿ“– Documentation

EmitterView

import { EmitterView } from 'react-native-caemitterlayer';

<EmitterView
   emitterConfig={...}
/>

Props

emitterConfig: EmitterConfigPropType (required)

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.

emitterConfig.layer: EmitterLayer (required)

Configures the single CAEmitterLayer which will render particles.

emitterConfig.layer.enabled?: boolean

Whether or not the emitter is enabled. Defaults to true.

emitterConfig.layer.initialValues?: object

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).

emitterConfig.layer.emitterCells?: EmitterCellType[]

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.

emitterConfig.layer - CAEmitterLayer properties

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.

...ViewProps

EmitterView also accepts all the same ViewProps props (i.e. style) as a React Native View.

๐Ÿ—บ๏ธ Roadmap

Future plans for features/enhancements/fixes (in no particular order/priority):

  • Better image support โœ… - Shipped in v0.3.0

    This library currently requires inlining of the images used for emitter cells (via EmitterCellType.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 EmitterView directly 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 emitterPosition and emitterSize.

    emitterPosition and emitterSize require specifying exact coordinates/sizes. For some uses, useWindowDimensions may be sufficient. However, due to the nature of how React Native renders things, you may have to wait until onLayout is called before knowing what to set these values to. Adding placeholder values/strings could reduce the need for onLayout/useWindowDimensions as we could then set emitterSize/emitterPosition on 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

Not planned/Out of scope

Android support

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.

๐Ÿ™Œ Acknowledgements

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:

โš–๏ธ License

MIT