0) {
183 | println "android.packagingOptions.$prop += $options ($options.length)"
184 | // Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
185 | options.each {
186 | android.packagingOptions[prop] += it
187 | }
188 | }
189 | }
190 |
191 | dependencies {
192 | // The version of react-native is set by the React Native Gradle Plugin
193 | implementation("com.facebook.react:react-android")
194 |
195 | def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
196 | def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
197 | def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
198 | def frescoVersion = rootProject.ext.frescoVersion
199 |
200 | // If your app supports Android versions before Ice Cream Sandwich (API level 14)
201 | if (isGifEnabled || isWebpEnabled) {
202 | implementation("com.facebook.fresco:fresco:${frescoVersion}")
203 | implementation("com.facebook.fresco:imagepipeline-okhttp3:${frescoVersion}")
204 | }
205 |
206 | if (isGifEnabled) {
207 | // For animated gif support
208 | implementation("com.facebook.fresco:animated-gif:${frescoVersion}")
209 | }
210 |
211 | if (isWebpEnabled) {
212 | // For webp support
213 | implementation("com.facebook.fresco:webpsupport:${frescoVersion}")
214 | if (isWebpAnimatedEnabled) {
215 | // Animated webp support
216 | implementation("com.facebook.fresco:animated-webp:${frescoVersion}")
217 | }
218 | }
219 |
220 | implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
221 |
222 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
223 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
224 | exclude group:'com.squareup.okhttp3', module:'okhttp'
225 | }
226 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
227 |
228 | if (hermesEnabled.toBoolean()) {
229 | implementation("com.facebook.react:hermes-android")
230 | } else {
231 | implementation jscFlavor
232 | }
233 | }
234 |
235 | apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
236 | applyNativeModulesAppBuildGradle(project)
237 |
--------------------------------------------------------------------------------
/example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/debug.keystore
--------------------------------------------------------------------------------
/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # react-native-reanimated
11 | -keep class com.swmansion.reanimated.** { *; }
12 | -keep class com.facebook.react.turbomodule.** { *; }
13 |
14 | # Add any project specific keep options here:
15 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/java/expo/modules/caemitterlayer/example/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package expo.modules.caemitterlayer.example;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
21 | import com.facebook.react.ReactInstanceEventListener;
22 | import com.facebook.react.ReactInstanceManager;
23 | import com.facebook.react.bridge.ReactContext;
24 | import com.facebook.react.modules.network.NetworkingModule;
25 | import okhttp3.OkHttpClient;
26 |
27 | /**
28 | * Class responsible of loading Flipper inside your React Native application. This is the debug
29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup.
30 | */
31 | public class ReactNativeFlipper {
32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
33 | if (FlipperUtils.shouldEnableFlipper(context)) {
34 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
35 |
36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
37 | client.addPlugin(new DatabasesFlipperPlugin(context));
38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
39 | client.addPlugin(CrashReporterPlugin.getInstance());
40 |
41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
42 | NetworkingModule.setCustomClientBuilder(
43 | new NetworkingModule.CustomClientBuilder() {
44 | @Override
45 | public void apply(OkHttpClient.Builder builder) {
46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
47 | }
48 | });
49 | client.addPlugin(networkFlipperPlugin);
50 | client.start();
51 |
52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
53 | // Hence we run if after all native modules have been initialized
54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
55 | if (reactContext == null) {
56 | reactInstanceManager.addReactInstanceEventListener(
57 | new ReactInstanceEventListener() {
58 | @Override
59 | public void onReactContextInitialized(ReactContext reactContext) {
60 | reactInstanceManager.removeReactInstanceEventListener(this);
61 | reactContext.runOnNativeModulesQueueThread(
62 | new Runnable() {
63 | @Override
64 | public void run() {
65 | client.addPlugin(new FrescoFlipperPlugin());
66 | }
67 | });
68 | }
69 | });
70 | } else {
71 | client.addPlugin(new FrescoFlipperPlugin());
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/expo/modules/caemitterlayer/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package expo.modules.caemitterlayer.example;
2 |
3 | import android.os.Build;
4 | import android.os.Bundle;
5 |
6 | import com.facebook.react.ReactActivity;
7 | import com.facebook.react.ReactActivityDelegate;
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
9 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
10 |
11 | import expo.modules.ReactActivityDelegateWrapper;
12 |
13 | public class MainActivity extends ReactActivity {
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | // Set the theme to AppTheme BEFORE onCreate to support
17 | // coloring the background, status bar, and navigation bar.
18 | // This is required for expo-splash-screen.
19 | setTheme(R.style.AppTheme);
20 | super.onCreate(null);
21 | }
22 |
23 | /**
24 | * Returns the name of the main component registered from JavaScript.
25 | * This is used to schedule rendering of the component.
26 | */
27 | @Override
28 | protected String getMainComponentName() {
29 | return "main";
30 | }
31 |
32 | /**
33 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
34 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
35 | * (aka React 18) with two boolean flags.
36 | */
37 | @Override
38 | protected ReactActivityDelegate createReactActivityDelegate() {
39 | return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
40 | this,
41 | getMainComponentName(),
42 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
43 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
44 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
45 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
46 | ));
47 | }
48 |
49 | /**
50 | * Align the back button behavior with Android S
51 | * where moving root activities to background instead of finishing activities.
52 | * @see onBackPressed
53 | */
54 | @Override
55 | public void invokeDefaultOnBackPressed() {
56 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
57 | if (!moveTaskToBack(false)) {
58 | // For non-root activities, use the default implementation to finish them.
59 | super.invokeDefaultOnBackPressed();
60 | }
61 | return;
62 | }
63 |
64 | // Use the default back button implementation on Android S
65 | // because it's doing more than {@link Activity#moveTaskToBack} in fact.
66 | super.invokeDefaultOnBackPressed();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/expo/modules/caemitterlayer/example/MainApplication.java:
--------------------------------------------------------------------------------
1 | package expo.modules.caemitterlayer.example;
2 |
3 | import android.app.Application;
4 | import android.content.res.Configuration;
5 | import androidx.annotation.NonNull;
6 |
7 | import com.facebook.react.PackageList;
8 | import com.facebook.react.ReactApplication;
9 | import com.facebook.react.ReactNativeHost;
10 | import com.facebook.react.ReactPackage;
11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
12 | import com.facebook.react.defaults.DefaultReactNativeHost;
13 | import com.facebook.soloader.SoLoader;
14 |
15 | import expo.modules.ApplicationLifecycleDispatcher;
16 | import expo.modules.ReactNativeHostWrapper;
17 |
18 | import java.util.List;
19 |
20 | public class MainApplication extends Application implements ReactApplication {
21 |
22 | private final ReactNativeHost mReactNativeHost =
23 | new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
24 | @Override
25 | public boolean getUseDeveloperSupport() {
26 | return BuildConfig.DEBUG;
27 | }
28 |
29 | @Override
30 | protected List getPackages() {
31 | @SuppressWarnings("UnnecessaryLocalVariable")
32 | List packages = new PackageList(this).getPackages();
33 | // Packages that cannot be autolinked yet can be added manually here, for example:
34 | // packages.add(new MyReactNativePackage());
35 | return packages;
36 | }
37 |
38 | @Override
39 | protected String getJSMainModuleName() {
40 | return "index";
41 | }
42 |
43 | @Override
44 | protected boolean isNewArchEnabled() {
45 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
46 | }
47 |
48 | @Override
49 | protected Boolean isHermesEnabled() {
50 | return BuildConfig.IS_HERMES_ENABLED;
51 | }
52 | });
53 |
54 | @Override
55 | public ReactNativeHost getReactNativeHost() {
56 | return mReactNativeHost;
57 | }
58 |
59 | @Override
60 | public void onCreate() {
61 | super.onCreate();
62 | SoLoader.init(this, /* native exopackage */ false);
63 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
64 | // If you opted-in for the New Architecture, we load the native entry point for this app.
65 | DefaultNewArchitectureEntryPoint.load();
66 | }
67 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
68 | ApplicationLifecycleDispatcher.onApplicationCreate(this);
69 | }
70 |
71 | @Override
72 | public void onConfigurationChanged(@NonNull Configuration newConfig) {
73 | super.onConfigurationChanged(newConfig);
74 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-hdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/drawable-hdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-mdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/drawable-mdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/splashscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
3 | #ffffff
4 | #023c69
5 | #ffffff
6 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | react-native-caemitterlayer-example
3 | contain
4 | false
5 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
14 |
17 |
--------------------------------------------------------------------------------
/example/android/app/src/release/java/expo/modules/caemitterlayer/example/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package expo.modules.caemitterlayer.example;
8 |
9 | import android.content.Context;
10 | import com.facebook.react.ReactInstanceManager;
11 |
12 | /**
13 | * Class responsible of loading Flipper inside your React Native application. This is the release
14 | * flavor of it so it's empty as we don't want to load Flipper.
15 | */
16 | public class ReactNativeFlipper {
17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
18 | // Do nothing as we don't want to initialize Flipper on Release.
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '33.0.0'
6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '21')
7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '33')
8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '33')
9 | if (findProperty('android.kotlinVersion')) {
10 | kotlinVersion = findProperty('android.kotlinVersion')
11 | }
12 | frescoVersion = findProperty('expo.frescoVersion') ?: '2.5.0'
13 |
14 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
15 | ndkVersion = "23.1.7779620"
16 | }
17 | repositories {
18 | google()
19 | mavenCentral()
20 | }
21 | dependencies {
22 | classpath('com.android.tools.build:gradle:7.4.1')
23 | classpath('com.facebook.react:react-native-gradle-plugin')
24 | }
25 | }
26 |
27 | allprojects {
28 | repositories {
29 | maven {
30 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
31 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
32 | }
33 | maven {
34 | // Android JSC is installed from npm
35 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), '../dist'))
36 | }
37 |
38 | google()
39 | mavenCentral()
40 | maven { url 'https://www.jitpack.io' }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Automatically convert third-party libraries to use AndroidX
26 | android.enableJetifier=true
27 |
28 | # Version of flipper SDK to use with React Native
29 | FLIPPER_VERSION=0.125.0
30 |
31 | # Use this property to specify which architecture you want to build.
32 | # You can also override it from the CLI using
33 | # ./gradlew -PreactNativeArchitectures=x86_64
34 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
35 |
36 | # Use this property to enable support to the new architecture.
37 | # This will allow you to use TurboModules and the Fabric render in
38 | # your application. You should enable this flag either if you want
39 | # to write custom TurboModules/Fabric components OR use libraries that
40 | # are providing them.
41 | newArchEnabled=false
42 |
43 | # The hosted JavaScript engine
44 | # Supported values: expo.jsEngine = "hermes" | "jsc"
45 | expo.jsEngine=hermes
46 |
47 | # Enable GIF support in React Native images (~200 B increase)
48 | expo.gif.enabled=true
49 | # Enable webp support in React Native images (~85 KB increase)
50 | expo.webp.enabled=true
51 | # Enable animated webp support (~3.4 MB increase)
52 | # Disabled by default because iOS doesn't support animated webp
53 | expo.webp.animated=false
54 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Stop when "xargs" is not available.
209 | if ! command -v xargs >/dev/null 2>&1
210 | then
211 | die "xargs is not available"
212 | fi
213 |
214 | # Use "xargs" to parse quoted args.
215 | #
216 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
217 | #
218 | # In Bash we could simply go:
219 | #
220 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
221 | # set -- "${ARGS[@]}" "$@"
222 | #
223 | # but POSIX shell has neither arrays nor command substitution, so instead we
224 | # post-process each arg (as a line of input to sed) to backslash-escape any
225 | # character that might be a shell metacharacter, then use eval to reverse
226 | # that process (while maintaining the separation between arguments), and wrap
227 | # the whole thing up as a single "set" statement.
228 | #
229 | # This will of course break if any of these variables contains a newline or
230 | # an unmatched quote.
231 | #
232 |
233 | eval "set -- $(
234 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
235 | xargs -n1 |
236 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
237 | tr '\n' ' '
238 | )" '"$@"'
239 |
240 | exec "$JAVACMD" "$@"
241 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'react-native-caemitterlayer-example'
2 |
3 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
4 | useExpoModules()
5 |
6 | apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
7 | applyNativeModulesSettingsGradle(settings)
8 |
9 | include ':app'
10 | includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())
11 |
--------------------------------------------------------------------------------
/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "react-native-caemitterlayer-example",
4 | "slug": "react-native-caemitterlayer-example",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "userInterfaceStyle": "light",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#ffffff"
13 | },
14 | "assetBundlePatterns": [
15 | "**/*"
16 | ],
17 | "ios": {
18 | "supportsTablet": true,
19 | "bundleIdentifier": "expo.modules.caemitterlayer.example"
20 | },
21 | "android": {
22 | "adaptiveIcon": {
23 | "foregroundImage": "./assets/adaptive-icon.png",
24 | "backgroundColor": "#ffffff"
25 | },
26 | "package": "expo.modules.caemitterlayer.example"
27 | },
28 | "web": {
29 | "favicon": "./assets/favicon.png"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/example/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/example/assets/contents/circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/contents/circle.png
--------------------------------------------------------------------------------
/example/assets/contents/flame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/contents/flame.png
--------------------------------------------------------------------------------
/example/assets/contents/rectangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/contents/rectangle.png
--------------------------------------------------------------------------------
/example/assets/contents/snowflake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/contents/snowflake.png
--------------------------------------------------------------------------------
/example/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/favicon.png
--------------------------------------------------------------------------------
/example/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/icon.png
--------------------------------------------------------------------------------
/example/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/assets/splash.png
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | module.exports = function (api) {
3 | api.cache(true);
4 | return {
5 | presets: ['babel-preset-expo'],
6 | plugins: [
7 | [
8 | 'module-resolver',
9 | {
10 | extensions: ['.tsx', '.ts', '.js', '.json'],
11 | alias: {
12 | // For development, we want to alias the library to the source
13 | 'react-native-caemitterlayer': path.join(__dirname, '..', 'src', 'index.ts'),
14 | },
15 | },
16 | ],
17 | ],
18 | };
19 | };
20 |
--------------------------------------------------------------------------------
/example/examples/Basic.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native'
2 | import { EmitterConfigPropType, EmitterView } from 'react-native-caemitterlayer'
3 |
4 | const circle = require('../assets/contents/circle.png')
5 |
6 | export function Basic() {
7 | const emitterConfig: EmitterConfigPropType = {
8 | layer: {
9 | // center the emission point in the middle of top edge of the view
10 | emitterPosition: {
11 | x: 50,
12 | y: 0,
13 | },
14 | emitterCells: [
15 | {
16 | color: '#006699',
17 | imageContents: circle,
18 | lifetime: 5, // particles live for 5 seconds
19 | velocity: 20, // velocity of 20dp/s in the direction of emission
20 | birthRate: 1, // One particle per second
21 | emissionLongitude: -Math.PI / 2, // emit particles up
22 | emissionRange: Math.PI / 3, // emit particles in a 45 degree cone
23 | },
24 | ],
25 | },
26 | }
27 |
28 | return (
29 |
36 |
40 |
41 | )
42 | }
43 |
--------------------------------------------------------------------------------
/example/examples/BurstEffect.tsx:
--------------------------------------------------------------------------------
1 | import { useWindowDimensions } from 'react-native'
2 | import {
3 | EmitterCellType,
4 | EmitterConfigPropType,
5 | EmitterLayer,
6 | EmitterView,
7 | } from 'react-native-caemitterlayer'
8 |
9 | const circle =
10 | 'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABygAwAEAAAAAQAAABwAAAAAl4eZoQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDYuMC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KGV7hBwAAArtJREFUSA2tlr1uFDEQx7ncJQEJJL4qoIQyNQ3wAigFTZrwAql4BGjzDqmoaNJQnAQ1SFTwBugqIkFDmkCS++D383pyZtm7C7cZ6W97xuOZnbE93s6lBTSZTFZQ6YJRp9MZN6mj00HeA2N0Rk06IVNxJmFoDQMnpQKya/BXgWuPmP9Zm1+DP0U+KeUxbnSYv1hnxyrCb9A9BY/AfXALGPkhGIBPoI/+B3r1V+kWRquuyh1gehw/AK/BL3AeeofSY9dKjN2K2YSCzvxylbfBIQg6ZqDj3+Ako5QhOqOX4QVJs1MmyshenC2dOihEjcNTpGUm9uY6RXk9R/a8MGcE/0tGP8qLdrPNLvz0vMB4smLPIo3LOMt+UspjvJltJx86SXuWhR4QyX1qS5HezxiK7PV06BG23wChZFrakmmN1G5lHz2ji8rgPbsMvOjpI+jbkLajaDzTEPd0uEIT5cpLLQVfce3a2K6HRHtdU0kAY7mygkjT01TxbdpweA8jdzQUAmuj5UoKWcW1a8OWW3RDUyEwqhgrv0iKIp7KZTg5woOFWAqFimvXastgPJjpVUkOOTgyAyBd5KGJG/ADuwcaX+HAxCHxiZGCr7h2bXz8F4L6rikjTLml7yuArArDNGrXmM54Kd5qiuC6VZMNI3gPpKg4FbdcG+VxwPLb2WEVHIIo3k8K223K2xA7UdZ2srNp9WKyfAtfZacuWMapzuKl2c/J+yuTSYZS5NvJPRBkeuNrQ9bUjxGaRh1KH8GVf6KLL8gTpdPdtKxqdKhjv9yXXV5ENM6V2diHn+8sHKNYOt2E9z2rk9GIOnlA0p7NjSycRc8ifwmSY/p1sAXegK8g9odhivIbfR/sgHQa5zmbeclZ7NwqFzbeNPfWJ+YuuAm8w1aog7jUjNXxNJ7vn9QFdcJAT9TldR4ds7JQ7w+9Y9X6UdlxpAAAAABJRU5ErkJggg=='
11 |
12 | const colors = [
13 | '#953aff',
14 | '#ffc329',
15 | '#ff651a',
16 | '#7b5cff',
17 | '#4c7eff',
18 | '#47c0ff',
19 | '#ff5b86',
20 | '#e97ad0',
21 | '#ff2f27',
22 | ]
23 |
24 | const burstCells: EmitterCellType[] = colors.map((color): EmitterCellType => {
25 | return {
26 | imageData: circle,
27 | beginTime: 0.1,
28 | scale: 0.3,
29 | color,
30 | lifetime: 5.0,
31 | birthRate: 300,
32 | alphaSpeed: -0.21,
33 | scaleSpeed: -0.06,
34 | velocity: 50,
35 | emissionRange: Math.PI * 2,
36 | emissionLongitude: Math.PI * 2,
37 | duration: 0.24,
38 | }
39 | })
40 |
41 | const layerConfig: EmitterLayer = {
42 | emitterShape: 'rectangle',
43 | emitterCells: [
44 | {
45 | lifetime: 0.3,
46 | birthRate: 0.5,
47 | emitterCells: shuffle(burstCells),
48 | },
49 | ],
50 | }
51 |
52 | export function BurstEffect() {
53 | const dimensions = useWindowDimensions()
54 |
55 | const emitterConfig: EmitterConfigPropType = {
56 | layer: {
57 | ...layerConfig,
58 | emitterSize: { width: dimensions.width, height: dimensions.height },
59 | emitterPosition: { x: 0, y: dimensions.height / 2 },
60 | },
61 | }
62 |
63 | return
64 | }
65 |
66 | function shuffle(array: T[]) {
67 | const result = [...array]
68 | let currentIndex = result.length,
69 | temporaryValue,
70 | randomIndex
71 |
72 | while (currentIndex !== 0) {
73 | randomIndex = Math.floor(Math.random() * currentIndex)
74 | currentIndex -= 1
75 | temporaryValue = result[currentIndex]
76 | result[currentIndex] = result[randomIndex]
77 | result[randomIndex] = temporaryValue
78 | }
79 |
80 | return result
81 | }
82 |
--------------------------------------------------------------------------------
/example/examples/Confetti.tsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from 'react'
2 | import {
3 | Animated,
4 | Button,
5 | Easing,
6 | useWindowDimensions,
7 | View,
8 | } from 'react-native'
9 | import {
10 | EmitterLayer,
11 | EmitterConfigPropType,
12 | EmitterView,
13 | EmitterCellType,
14 | } from 'react-native-caemitterlayer'
15 |
16 | // Much of this pulled from: https://bryce.co/recreating-imessage-confetti/
17 | // https://github.com/bryce-co/RecreatingiMessageConfetti/blob/master/RecreatingiMessageConfetti.playground/Pages/Step%208.xcplaygroundpage/Contents.swift
18 |
19 | const colors = [
20 | '#953aff',
21 | '#ffc329',
22 | '#ff651a',
23 | '#7b5cff',
24 | '#4c7eff',
25 | '#47c0ff',
26 | '#ff5b86',
27 | '#e97ad0',
28 | '#ff2f27',
29 | ]
30 |
31 | const circle = require('../assets/contents/circle.png')
32 | const rectangle = require('../assets/contents/rectangle.png')
33 |
34 | const shapes = [circle, rectangle]
35 |
36 | const confettiLifetime = 6
37 |
38 | const allCells: EmitterCellType[] = shapes.flatMap((shape, index) =>
39 | colors.map((color): EmitterCellType => {
40 | return {
41 | imageContents: shape,
42 | beginTime: 0.1,
43 | scale: index === 0 ? 0.6 : 1,
44 | color,
45 | lifetime: confettiLifetime,
46 | birthRate: 20,
47 | spin: 4,
48 | spinRange: 8,
49 | velocity: 900,
50 | velocityRange: 150,
51 | xAcceleration: 50,
52 | emissionRange: Math.PI / 8,
53 | emissionLongitude: Math.PI * 1.5,
54 | yAcceleration: 500,
55 | values: {
56 | particleType: 'plane',
57 | orientationRange: Math.PI,
58 | orientationLongitude: Math.PI / 2,
59 | orientationLatitude: Math.PI / 2,
60 | },
61 | }
62 | }),
63 | )
64 |
65 | const layerConfig: EmitterLayer = {
66 | emitterShape: 'point',
67 | emitterCells: allCells,
68 | }
69 |
70 | export function Confetti() {
71 | const dimensions = useWindowDimensions()
72 |
73 | const animatedScaleRef = useRef(new Animated.Value(0))
74 |
75 | const [showingConfetti, setShowingConfetti] = useState(false)
76 | const [birthRate, setBirthRate] = useState(1)
77 |
78 | const emitterConfig: EmitterConfigPropType = {
79 | layer: {
80 | ...layerConfig,
81 | birthRate,
82 | emitterCells: allCells.map(cell => ({
83 | ...cell,
84 | })),
85 | emitterPosition: { x: dimensions.width / 2, y: dimensions.height },
86 | },
87 | }
88 |
89 | return (
90 | <>
91 | {showingConfetti && (
92 |
97 |
106 |
107 | )}
108 |
109 |
135 | >
136 | )
137 | }
138 |
--------------------------------------------------------------------------------
/example/examples/ConfettiCannon.tsx:
--------------------------------------------------------------------------------
1 | export function ConfettiCannon() {
2 | // TODO
3 | return null
4 | }
5 |
--------------------------------------------------------------------------------
/example/examples/Emoji.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native'
2 | import { EmitterConfigPropType, EmitterView } from 'react-native-caemitterlayer'
3 |
4 | const emitterConfig: EmitterConfigPropType = {
5 | layer: {
6 | // center the emission point in the middle of top edge of the view
7 | emitterPosition: {
8 | x: 50,
9 | y: 0,
10 | },
11 | emitterCells: [
12 | {
13 | stringContents: { value: '🦓' },
14 | lifetime: 5,
15 | contentsScale: 2,
16 | alphaSpeed: -0.2,
17 | velocity: 40,
18 | birthRate: 2,
19 | emissionLongitude: -Math.PI / 2, // emit particles up
20 | emissionRange: Math.PI / 4, // emit particles in a 45 degree cone
21 | },
22 | ],
23 | },
24 | }
25 |
26 | export function Emoji() {
27 | return (
28 |
35 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/example/examples/Fire.tsx:
--------------------------------------------------------------------------------
1 | import { View, ViewStyle } from 'react-native'
2 | import {
3 | EmitterCellType,
4 | EmitterConfigPropType,
5 | EmitterLayer,
6 | EmitterView,
7 | } from 'react-native-caemitterlayer'
8 |
9 | const flame = require('../assets/contents/flame.png')
10 |
11 | const flameCell: EmitterCellType = {
12 | imageContents: flame,
13 | color: '#EE8130',
14 | lifetime: 1.2,
15 | birthRate: 120,
16 | blueRange: 0.15,
17 | velocity: 4,
18 | velocityRange: 2,
19 | scale: 0.6,
20 | yAcceleration: -8,
21 | xAcceleration: 2,
22 | alphaSpeed: 0.4,
23 | emitterCells: [
24 | {
25 | imageContents: flame,
26 | lifetime: 1.4,
27 | beginTime: 1.18,
28 | yAcceleration: -14,
29 | scale: 1.0,
30 | scaleSpeed: -0.08,
31 | velocity: 20,
32 | birthRate: 1,
33 | alphaSpeed: -1.0,
34 | },
35 | ],
36 | }
37 |
38 | const layerConfig: EmitterLayer = {
39 | renderMode: 'additive',
40 | emitterPosition: {
41 | x: 50,
42 | y: 0,
43 | },
44 | emitterSize: {
45 | width: 100,
46 | height: 100,
47 | },
48 | emitterShape: 'line',
49 | emitterCells: [flameCell],
50 | }
51 |
52 | const emitterConfig: EmitterConfigPropType = {
53 | layer: layerConfig,
54 | }
55 |
56 | export function Fire() {
57 | return (
58 |
59 |
60 |
61 | )
62 | }
63 |
64 | const $containerStyle: ViewStyle = {
65 | width: '100%',
66 | height: '100%',
67 | justifyContent: 'center',
68 | alignItems: 'center',
69 | backgroundColor: '#E8EAEC',
70 | }
71 |
72 | const $emitterViewStyle: ViewStyle = {
73 | width: 100,
74 | height: 100,
75 | backgroundColor: 'white',
76 | borderRadius: 4,
77 | }
78 |
--------------------------------------------------------------------------------
/example/examples/Fireworks.tsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import { Button, useWindowDimensions, View } from 'react-native'
3 | import {
4 | EmitterLayer,
5 | EmitterConfigPropType,
6 | EmitterView,
7 | } from 'react-native-caemitterlayer'
8 |
9 | const flameImage = require('../assets/contents/flame.png')
10 |
11 | const layerConfig: EmitterLayer = {
12 | initialValues: {
13 | seed: 42,
14 | beginTime: 'currentTime',
15 | },
16 | renderMode: 'additive',
17 | emitterCells: [
18 | {
19 | imageContents: flameImage,
20 | color: '#7F7F7F',
21 | lifetime: 1.7,
22 | birthRate: 1,
23 | velocity: 350,
24 | velocityRange: 100,
25 | emissionRange: -Math.PI / 4,
26 | emissionLongitude: -Math.PI / 2,
27 | yAcceleration: 10,
28 | redRange: 0.9,
29 | greenRange: 0.9,
30 | blueRange: 0.9,
31 | emitterCells: [
32 | {
33 | imageContents: flameImage,
34 | lifetime: 0.5,
35 | birthRate: 45,
36 | velocity: 80,
37 | scale: 0.4,
38 | alphaSpeed: -0.7,
39 | scaleSpeed: -0.1,
40 | scaleRange: 0.1,
41 | emissionRange: Math.PI / 8,
42 | emissionLongitude: Math.PI * 2,
43 | yAcceleration: 350,
44 | beginTime: 0.01,
45 | duration: 1.7,
46 | },
47 | {
48 | imageContents: flameImage,
49 | lifetime: 5,
50 | birthRate: 4000,
51 | velocity: 130,
52 | scale: 0.6,
53 | spinRange: 3,
54 | alphaSpeed: -0.2,
55 | scaleSpeed: -0.1,
56 | emissionRange: Math.PI * 2,
57 | emissionLongitude: Math.PI * 2,
58 | yAcceleration: 80,
59 | beginTime: 1.5,
60 | duration: 0.1,
61 | },
62 | ],
63 | },
64 | ],
65 | }
66 |
67 | export function Fireworks() {
68 | const dimensions = useWindowDimensions()
69 |
70 | const [showFireworks, setShowFireworks] = useState(false)
71 |
72 | const emitterConfig: EmitterConfigPropType = {
73 | layer: {
74 | ...layerConfig,
75 | enabled: showFireworks,
76 | emitterPosition: { x: dimensions.width / 2, y: 0 },
77 | },
78 | }
79 |
80 | return (
81 |
89 |
114 | )
115 | }
116 |
--------------------------------------------------------------------------------
/example/examples/List.tsx:
--------------------------------------------------------------------------------
1 | import { FlatList, Text, TextStyle, View, ViewStyle } from 'react-native'
2 | import {
3 | EmitterCellType,
4 | EmitterLayer,
5 | EmitterView,
6 | } from 'react-native-caemitterlayer'
7 |
8 | import { pokemons, PokemonType } from './pokemons'
9 |
10 | const flameImage = require('../assets/contents/flame.png')
11 |
12 | const cellTemplate: EmitterCellType = {
13 | imageContents: flameImage,
14 | color: '#FFFFFF00',
15 | lifetime: 1.2,
16 | birthRate: 220,
17 | blueRange: 0.15,
18 | velocity: 4,
19 | velocityRange: 2,
20 | scale: 0.6,
21 | yAcceleration: -8,
22 | xAcceleration: 2,
23 | alphaSpeed: 0.4,
24 | emitterCells: [
25 | {
26 | imageContents: flameImage,
27 | lifetime: 1.4,
28 | beginTime: 1.18,
29 | yAcceleration: -14,
30 | scale: 1.0,
31 | scaleSpeed: -0.08,
32 | velocity: 20,
33 | birthRate: 1,
34 | alphaSpeed: -1.0,
35 | },
36 | ],
37 | }
38 |
39 | const layerConfig: EmitterLayer = {
40 | renderMode: 'additive',
41 | emitterPosition: {
42 | x: 45,
43 | y: 45,
44 | },
45 | emitterSize: {
46 | width: 90,
47 | height: 90,
48 | },
49 | emitterShape: 'rectangle',
50 | emitterCells: [cellTemplate],
51 | }
52 |
53 | const pokemonTypeToColor: Record = {
54 | fire: '#EE8130',
55 | water: '#6390F0',
56 | grass: '#7AC74C',
57 | electric: '#F7D02C',
58 | normal: '#A8A77A',
59 | ice: '#96D9D6',
60 | psychic: '#F95587',
61 | ghost: '#735797',
62 | dragon: '#6F35FC',
63 | fairy: '#D685AD',
64 | dark: '#705746',
65 | steel: '#B7B7CE',
66 | rock: '#B6A136',
67 | ground: '#E2BF65',
68 | flying: '#A98FF3',
69 | bug: '#A6B91A',
70 | poison: '#A33EA1',
71 | fighting: '#C22E28',
72 | }
73 |
74 | function PokemonListItem({ pokemon }: { pokemon: (typeof pokemons)[0] }) {
75 | const color = pokemonTypeToColor[pokemon.type]
76 |
77 | const config = {
78 | layer: {
79 | ...layerConfig,
80 | emitterCells: [
81 | {
82 | ...cellTemplate,
83 | color,
84 | },
85 | ],
86 | },
87 | }
88 |
89 | return (
90 |
91 |
92 |
93 |
94 |
95 | {pokemon.name}
96 | {pokemon.type}
97 |
98 |
99 | )
100 | }
101 |
102 | export function PokemonList() {
103 | return (
104 | }
107 | keyExtractor={item => item.name}
108 | contentContainerStyle={{ paddingTop: 46, paddingBottom: 110 }}
109 | style={$listStyle}
110 | />
111 | )
112 | }
113 |
114 | const $listStyle: ViewStyle = {
115 | flex: 1,
116 | width: '100%',
117 | backgroundColor: '#E8EAEC',
118 | }
119 |
120 | const $listItemStyle: ViewStyle = {
121 | backgroundColor: 'white',
122 | marginHorizontal: 16,
123 | marginVertical: 8,
124 | borderRadius: 8,
125 | borderWidth: 1,
126 | borderBottomWidth: 3,
127 | borderRightWidth: 3,
128 | padding: 12,
129 | flexDirection: 'row',
130 | }
131 |
132 | const $imagePlaceholderStyle: ViewStyle = {
133 | width: 100,
134 | height: 100,
135 | borderRadius: 4,
136 | }
137 |
138 | const $listItemTextStyle: TextStyle = {
139 | fontSize: 22,
140 | color: '#212121',
141 | fontFamily: 'Helvetica',
142 | }
143 |
144 | const $listItemSubTextStyle: TextStyle = {
145 | marginTop: 4,
146 | fontSize: 14,
147 | fontWeight: 'bold',
148 | fontFamily: 'Helvetica',
149 | textTransform: 'uppercase',
150 | }
151 |
--------------------------------------------------------------------------------
/example/examples/Snow.tsx:
--------------------------------------------------------------------------------
1 | import { useWindowDimensions, View } from 'react-native'
2 | import {
3 | EmitterLayer,
4 | EmitterConfigPropType,
5 | EmitterView,
6 | } from 'react-native-caemitterlayer'
7 |
8 | const snowflake = require('../assets/contents/snowflake.png')
9 |
10 | const fallingSnow: EmitterLayer = {
11 | initialValues: {
12 | beginTime: 'currentTime',
13 | },
14 | emitterShape: 'rectangle',
15 | emitterCells: [
16 | {
17 | imageContents: snowflake,
18 | color: '#FFFFFF7F',
19 | lifetime: 5.5,
20 | birthRate: 80,
21 | blueRange: 0.15,
22 | alphaRange: 0.5,
23 | velocity: 110,
24 | velocityRange: 60,
25 | scale: 0.24,
26 | scaleRange: 0.6,
27 | emissionRange: Math.PI / 4,
28 | emissionLongitude: Math.PI / 2,
29 | yAcceleration: 30,
30 | scaleSpeed: -0.07,
31 | alphaSpeed: -0.12,
32 | },
33 | ],
34 | }
35 |
36 | const snowLine: EmitterLayer = {
37 | initialValues: {
38 | beginTime: 'currentTime',
39 | },
40 | emitterShape: 'line',
41 | emitterCells: [
42 | {
43 | imageContents: snowflake,
44 | color: '#FFFFFF5F',
45 | lifetime: 5,
46 | birthRate: 5,
47 | blueRange: 0.15,
48 | alphaRange: 0.6,
49 | scale: 0.3,
50 | scaleRange: 0.2,
51 | velocity: 0,
52 | emissionRange: Math.PI / 2,
53 | emissionLongitude: Math.PI,
54 | scaleSpeed: -0.1,
55 | alphaSpeed: -0.2,
56 | beginTime: 3.8, // give falling snow time to reach this view/layer
57 | },
58 | ],
59 | }
60 |
61 | // Uncomment for blizzard-like snow
62 | // const busySnow: EmitterLayer = {
63 | // initialValues: {
64 | // beginTime: 'currentTime',
65 | // },
66 | // emitterShape: 'rectangle',
67 | // emitterCells: [
68 | // {
69 | // imageContents: snowflake,
70 | // color: '#FFFFFF7F',
71 | // lifetime: 5.5,
72 | // birthRate: 200,
73 | // blueRange: 0.15,
74 | // alphaRange: 0.5,
75 | // velocity: 10,
76 | // velocityRange: 300,
77 | // scale: 0.2,
78 | // scaleRange: 0.8,
79 | // emissionRange: Math.PI / 2,
80 | // emissionLongitude: Math.PI,
81 | // yAcceleration: 40,
82 | // scaleSpeed: -0.1,
83 | // alphaSpeed: -0.2,
84 | // },
85 | // ],
86 | // }
87 |
88 | export function Snow() {
89 | const dimensions = useWindowDimensions()
90 |
91 | // For a more blizzard-like effect, check out this
92 | // const busySnowConfig: EmitterConfigPropType = {
93 | // layer: {
94 | // ...fallingSnow,
95 | // emitterSize: { width: dimensions.width, height: dimensions.height },
96 | // emitterPosition: { x: dimensions.width / 2, y: dimensions.height / 2 },
97 | // },
98 | // }
99 |
100 | const fallingSnowConfig: EmitterConfigPropType = {
101 | layer: {
102 | ...fallingSnow,
103 | emitterSize: { width: dimensions.width, height: 200 },
104 | emitterPosition: { x: dimensions.width / 2, y: -100 },
105 | },
106 | }
107 |
108 | const snowLineEmitterConfig: EmitterConfigPropType = {
109 | layer: {
110 | ...snowLine,
111 | emitterSize: { width: 300, height: 1 },
112 | emitterPosition: { x: 150, y: 0 },
113 | },
114 | }
115 |
116 | return (
117 |
126 |
127 |
136 |
137 |
138 | )
139 | }
140 |
--------------------------------------------------------------------------------
/example/examples/pokemons.ts:
--------------------------------------------------------------------------------
1 | export type PokemonType =
2 | | 'grass'
3 | | 'water'
4 | | 'fire'
5 | | 'electric'
6 | | 'normal'
7 | | 'fairy'
8 | | 'dragon'
9 | | 'ghost'
10 | | 'ground'
11 | | 'psychic'
12 | | 'ice'
13 | | 'poison'
14 | | 'bug'
15 | | 'flying'
16 | | 'fighting'
17 | | 'rock'
18 | | 'steel'
19 | | 'dark'
20 |
21 | export const pokemons: { name: string; type: PokemonType }[] = [
22 | {
23 | name: 'Bulbasaur',
24 | type: 'grass',
25 | },
26 | {
27 | name: 'Squirtle',
28 | type: 'water',
29 | },
30 | {
31 | name: 'Charmander',
32 | type: 'fire',
33 | },
34 | {
35 | name: 'Pikachu',
36 | type: 'electric',
37 | },
38 | {
39 | name: 'Eevee',
40 | type: 'normal',
41 | },
42 | {
43 | name: 'Onix',
44 | type: 'rock',
45 | },
46 | {
47 | name: 'Growlithe',
48 | type: 'fire',
49 | },
50 | {
51 | name: 'Ghastly',
52 | type: 'ghost',
53 | },
54 | {
55 | name: 'Machop',
56 | type: 'fighting',
57 | },
58 | {
59 | name: 'Arbok',
60 | type: 'poison',
61 | },
62 | {
63 | name: 'Sandslash',
64 | type: 'ground',
65 | },
66 | {
67 | name: 'Vulpix',
68 | type: 'fire',
69 | },
70 | {
71 | name: 'Psyduck',
72 | type: 'water',
73 | },
74 | {
75 | name: 'Clefairy',
76 | type: 'fairy',
77 | },
78 | {
79 | name: 'Hitmonlee',
80 | type: 'fighting',
81 | },
82 | {
83 | name: 'Dratini',
84 | type: 'dragon',
85 | },
86 | {
87 | name: 'Jynx',
88 | type: 'ice',
89 | },
90 | {
91 | name: 'Mew',
92 | type: 'psychic',
93 | },
94 | {
95 | name: 'Jigglypuff',
96 | type: 'normal',
97 | },
98 | {
99 | name: 'Snorlax',
100 | type: 'normal',
101 | },
102 | {
103 | name: 'Dewgong',
104 | type: 'ice',
105 | },
106 | {
107 | name: 'Gengar',
108 | type: 'ghost',
109 | },
110 | {
111 | name: 'Magikarp',
112 | type: 'water',
113 | },
114 | {
115 | name: 'Poliwag',
116 | type: 'water',
117 | },
118 | {
119 | name: 'Houndour',
120 | type: 'fire',
121 | },
122 | {
123 | name: 'Pidgey',
124 | type: 'flying',
125 | },
126 | {
127 | name: 'Ponyta',
128 | type: 'fire',
129 | },
130 | {
131 | name: 'Shellder',
132 | type: 'ice',
133 | },
134 | {
135 | name: 'Oddish',
136 | type: 'grass',
137 | },
138 | ]
139 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | import { registerRootComponent } from 'expo'
2 |
3 | import App from './App'
4 |
5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6 | // It also ensures that whether you load the app in Expo Go or in a native build,
7 | // the environment is set up appropriately
8 | registerRootComponent(App)
9 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 | .xcode.env.local
25 |
26 | # Bundle artifacts
27 | *.jsbundle
28 |
29 | # CocoaPods
30 | /Pods/
31 |
--------------------------------------------------------------------------------
/example/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
3 | require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules")
4 |
5 | require 'json'
6 | podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
7 |
8 | ENV['RCT_NEW_ARCH_ENABLED'] = podfile_properties['newArchEnabled'] == 'true' ? '1' : '0'
9 |
10 | platform :ios, podfile_properties['ios.deploymentTarget'] || '13.0'
11 | install! 'cocoapods',
12 | :deterministic_uuids => false
13 |
14 | prepare_react_native_project!
15 |
16 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
17 | # because `react-native-flipper` depends on (FlipperKit,...), which will be excluded. To fix this,
18 | # you can also exclude `react-native-flipper` in `react-native.config.js`
19 | #
20 | # ```js
21 | # module.exports = {
22 | # dependencies: {
23 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
24 | # }
25 | # }
26 | # ```
27 | flipper_config = FlipperConfiguration.disabled
28 | if ENV['NO_FLIPPER'] == "1" || ENV['CI'] then
29 | # Explicitly disabled through environment variables
30 | flipper_config = FlipperConfiguration.disabled
31 | elsif podfile_properties.key?('ios.flipper') then
32 | # Configure Flipper in Podfile.properties.json
33 | if podfile_properties['ios.flipper'] == 'true' then
34 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"])
35 | elsif podfile_properties['ios.flipper'] != 'false' then
36 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"], { 'Flipper' => podfile_properties['ios.flipper'] })
37 | end
38 | end
39 |
40 | target 'reactnativecaemitterlayerexample' do
41 | use_expo_modules!
42 | config = use_native_modules!
43 |
44 | use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
45 | use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
46 |
47 | # Flags change depending on the env values.
48 | flags = get_default_flags()
49 |
50 | use_react_native!(
51 | :path => config[:reactNativePath],
52 | :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
53 | :fabric_enabled => flags[:fabric_enabled],
54 | # An absolute path to your application root.
55 | :app_path => "#{Pod::Config.instance.installation_root}/..",
56 | # Note that if you have use_frameworks! enabled, Flipper will not work if enabled
57 | :flipper_configuration => flipper_config
58 | )
59 |
60 | post_install do |installer|
61 | react_native_post_install(
62 | installer,
63 | config[:reactNativePath],
64 | # Set `mac_catalyst_enabled` to `true` in order to apply patches
65 | # necessary for Mac Catalyst builds
66 | :mac_catalyst_enabled => false
67 | )
68 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
69 |
70 | # This is necessary for Xcode 14, because it signs resource bundles by default
71 | # when building for devices.
72 | installer.target_installation_results.pod_target_installation_results
73 | .each do |pod_name, target_installation_result|
74 | target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
75 | resource_bundle_target.build_configurations.each do |config|
76 | config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
77 | end
78 | end
79 | end
80 | end
81 |
82 | post_integrate do |installer|
83 | begin
84 | expo_patch_react_imports!(installer)
85 | rescue => e
86 | Pod::UI.warn e
87 | end
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - boost (1.76.0)
3 | - DoubleConversion (1.1.6)
4 | - EXApplication (5.3.1):
5 | - ExpoModulesCore
6 | - EXConstants (14.4.2):
7 | - ExpoModulesCore
8 | - EXFileSystem (15.4.5):
9 | - ExpoModulesCore
10 | - EXFont (11.4.0):
11 | - ExpoModulesCore
12 | - Expo (49.0.23):
13 | - ExpoModulesCore
14 | - ExpoKeepAwake (12.3.0):
15 | - ExpoModulesCore
16 | - ExpoModulesCore (1.5.13):
17 | - RCT-Folly (= 2021.07.22.00)
18 | - React-Core
19 | - React-NativeModulesApple
20 | - React-RCTAppDelegate
21 | - ReactCommon/turbomodule/core
22 | - FBLazyVector (0.72.10)
23 | - FBReactNativeSpec (0.72.10):
24 | - RCT-Folly (= 2021.07.22.00)
25 | - RCTRequired (= 0.72.10)
26 | - RCTTypeSafety (= 0.72.10)
27 | - React-Core (= 0.72.10)
28 | - React-jsi (= 0.72.10)
29 | - ReactCommon/turbomodule/core (= 0.72.10)
30 | - fmt (6.2.1)
31 | - glog (0.3.5)
32 | - hermes-engine (0.71.3):
33 | - hermes-engine/Pre-built (= 0.71.3)
34 | - hermes-engine/Pre-built (0.71.3)
35 | - libevent (2.1.12)
36 | - RCT-Folly (2021.07.22.00):
37 | - boost
38 | - DoubleConversion
39 | - fmt (~> 6.2.1)
40 | - glog
41 | - RCT-Folly/Default (= 2021.07.22.00)
42 | - RCT-Folly/Default (2021.07.22.00):
43 | - boost
44 | - DoubleConversion
45 | - fmt (~> 6.2.1)
46 | - glog
47 | - RCT-Folly/Futures (2021.07.22.00):
48 | - boost
49 | - DoubleConversion
50 | - fmt (~> 6.2.1)
51 | - glog
52 | - libevent
53 | - RCTRequired (0.72.10)
54 | - RCTTypeSafety (0.72.10):
55 | - FBLazyVector (= 0.72.10)
56 | - RCTRequired (= 0.72.10)
57 | - React-Core (= 0.72.10)
58 | - React (0.72.10):
59 | - React-Core (= 0.72.10)
60 | - React-Core/DevSupport (= 0.72.10)
61 | - React-Core/RCTWebSocket (= 0.72.10)
62 | - React-RCTActionSheet (= 0.72.10)
63 | - React-RCTAnimation (= 0.72.10)
64 | - React-RCTBlob (= 0.72.10)
65 | - React-RCTImage (= 0.72.10)
66 | - React-RCTLinking (= 0.72.10)
67 | - React-RCTNetwork (= 0.72.10)
68 | - React-RCTSettings (= 0.72.10)
69 | - React-RCTText (= 0.72.10)
70 | - React-RCTVibration (= 0.72.10)
71 | - React-callinvoker (0.72.10)
72 | - React-Codegen (0.72.10):
73 | - DoubleConversion
74 | - FBReactNativeSpec
75 | - glog
76 | - hermes-engine
77 | - RCT-Folly
78 | - RCTRequired
79 | - RCTTypeSafety
80 | - React-Core
81 | - React-jsi
82 | - React-jsiexecutor
83 | - React-NativeModulesApple
84 | - React-rncore
85 | - ReactCommon/turbomodule/bridging
86 | - ReactCommon/turbomodule/core
87 | - React-Core (0.72.10):
88 | - glog
89 | - hermes-engine
90 | - RCT-Folly (= 2021.07.22.00)
91 | - React-Core/Default (= 0.72.10)
92 | - React-cxxreact
93 | - React-hermes
94 | - React-jsi
95 | - React-jsiexecutor
96 | - React-perflogger
97 | - React-runtimeexecutor
98 | - React-utils
99 | - SocketRocket (= 0.6.1)
100 | - Yoga
101 | - React-Core/CoreModulesHeaders (0.72.10):
102 | - glog
103 | - hermes-engine
104 | - RCT-Folly (= 2021.07.22.00)
105 | - React-Core/Default
106 | - React-cxxreact
107 | - React-hermes
108 | - React-jsi
109 | - React-jsiexecutor
110 | - React-perflogger
111 | - React-runtimeexecutor
112 | - React-utils
113 | - SocketRocket (= 0.6.1)
114 | - Yoga
115 | - React-Core/Default (0.72.10):
116 | - glog
117 | - hermes-engine
118 | - RCT-Folly (= 2021.07.22.00)
119 | - React-cxxreact
120 | - React-hermes
121 | - React-jsi
122 | - React-jsiexecutor
123 | - React-perflogger
124 | - React-runtimeexecutor
125 | - React-utils
126 | - SocketRocket (= 0.6.1)
127 | - Yoga
128 | - React-Core/DevSupport (0.72.10):
129 | - glog
130 | - hermes-engine
131 | - RCT-Folly (= 2021.07.22.00)
132 | - React-Core/Default (= 0.72.10)
133 | - React-Core/RCTWebSocket (= 0.72.10)
134 | - React-cxxreact
135 | - React-hermes
136 | - React-jsi
137 | - React-jsiexecutor
138 | - React-jsinspector (= 0.72.10)
139 | - React-perflogger
140 | - React-runtimeexecutor
141 | - React-utils
142 | - SocketRocket (= 0.6.1)
143 | - Yoga
144 | - React-Core/RCTActionSheetHeaders (0.72.10):
145 | - glog
146 | - hermes-engine
147 | - RCT-Folly (= 2021.07.22.00)
148 | - React-Core/Default
149 | - React-cxxreact
150 | - React-hermes
151 | - React-jsi
152 | - React-jsiexecutor
153 | - React-perflogger
154 | - React-runtimeexecutor
155 | - React-utils
156 | - SocketRocket (= 0.6.1)
157 | - Yoga
158 | - React-Core/RCTAnimationHeaders (0.72.10):
159 | - glog
160 | - hermes-engine
161 | - RCT-Folly (= 2021.07.22.00)
162 | - React-Core/Default
163 | - React-cxxreact
164 | - React-hermes
165 | - React-jsi
166 | - React-jsiexecutor
167 | - React-perflogger
168 | - React-runtimeexecutor
169 | - React-utils
170 | - SocketRocket (= 0.6.1)
171 | - Yoga
172 | - React-Core/RCTBlobHeaders (0.72.10):
173 | - glog
174 | - hermes-engine
175 | - RCT-Folly (= 2021.07.22.00)
176 | - React-Core/Default
177 | - React-cxxreact
178 | - React-hermes
179 | - React-jsi
180 | - React-jsiexecutor
181 | - React-perflogger
182 | - React-runtimeexecutor
183 | - React-utils
184 | - SocketRocket (= 0.6.1)
185 | - Yoga
186 | - React-Core/RCTImageHeaders (0.72.10):
187 | - glog
188 | - hermes-engine
189 | - RCT-Folly (= 2021.07.22.00)
190 | - React-Core/Default
191 | - React-cxxreact
192 | - React-hermes
193 | - React-jsi
194 | - React-jsiexecutor
195 | - React-perflogger
196 | - React-runtimeexecutor
197 | - React-utils
198 | - SocketRocket (= 0.6.1)
199 | - Yoga
200 | - React-Core/RCTLinkingHeaders (0.72.10):
201 | - glog
202 | - hermes-engine
203 | - RCT-Folly (= 2021.07.22.00)
204 | - React-Core/Default
205 | - React-cxxreact
206 | - React-hermes
207 | - React-jsi
208 | - React-jsiexecutor
209 | - React-perflogger
210 | - React-runtimeexecutor
211 | - React-utils
212 | - SocketRocket (= 0.6.1)
213 | - Yoga
214 | - React-Core/RCTNetworkHeaders (0.72.10):
215 | - glog
216 | - hermes-engine
217 | - RCT-Folly (= 2021.07.22.00)
218 | - React-Core/Default
219 | - React-cxxreact
220 | - React-hermes
221 | - React-jsi
222 | - React-jsiexecutor
223 | - React-perflogger
224 | - React-runtimeexecutor
225 | - React-utils
226 | - SocketRocket (= 0.6.1)
227 | - Yoga
228 | - React-Core/RCTSettingsHeaders (0.72.10):
229 | - glog
230 | - hermes-engine
231 | - RCT-Folly (= 2021.07.22.00)
232 | - React-Core/Default
233 | - React-cxxreact
234 | - React-hermes
235 | - React-jsi
236 | - React-jsiexecutor
237 | - React-perflogger
238 | - React-runtimeexecutor
239 | - React-utils
240 | - SocketRocket (= 0.6.1)
241 | - Yoga
242 | - React-Core/RCTTextHeaders (0.72.10):
243 | - glog
244 | - hermes-engine
245 | - RCT-Folly (= 2021.07.22.00)
246 | - React-Core/Default
247 | - React-cxxreact
248 | - React-hermes
249 | - React-jsi
250 | - React-jsiexecutor
251 | - React-perflogger
252 | - React-runtimeexecutor
253 | - React-utils
254 | - SocketRocket (= 0.6.1)
255 | - Yoga
256 | - React-Core/RCTVibrationHeaders (0.72.10):
257 | - glog
258 | - hermes-engine
259 | - RCT-Folly (= 2021.07.22.00)
260 | - React-Core/Default
261 | - React-cxxreact
262 | - React-hermes
263 | - React-jsi
264 | - React-jsiexecutor
265 | - React-perflogger
266 | - React-runtimeexecutor
267 | - React-utils
268 | - SocketRocket (= 0.6.1)
269 | - Yoga
270 | - React-Core/RCTWebSocket (0.72.10):
271 | - glog
272 | - hermes-engine
273 | - RCT-Folly (= 2021.07.22.00)
274 | - React-Core/Default (= 0.72.10)
275 | - React-cxxreact
276 | - React-hermes
277 | - React-jsi
278 | - React-jsiexecutor
279 | - React-perflogger
280 | - React-runtimeexecutor
281 | - React-utils
282 | - SocketRocket (= 0.6.1)
283 | - Yoga
284 | - React-CoreModules (0.72.10):
285 | - RCT-Folly (= 2021.07.22.00)
286 | - RCTTypeSafety (= 0.72.10)
287 | - React-Codegen (= 0.72.10)
288 | - React-Core/CoreModulesHeaders (= 0.72.10)
289 | - React-jsi (= 0.72.10)
290 | - React-RCTBlob
291 | - React-RCTImage (= 0.72.10)
292 | - ReactCommon/turbomodule/core (= 0.72.10)
293 | - SocketRocket (= 0.6.1)
294 | - React-cxxreact (0.72.10):
295 | - boost (= 1.76.0)
296 | - DoubleConversion
297 | - glog
298 | - hermes-engine
299 | - RCT-Folly (= 2021.07.22.00)
300 | - React-callinvoker (= 0.72.10)
301 | - React-debug (= 0.72.10)
302 | - React-jsi (= 0.72.10)
303 | - React-jsinspector (= 0.72.10)
304 | - React-logger (= 0.72.10)
305 | - React-perflogger (= 0.72.10)
306 | - React-runtimeexecutor (= 0.72.10)
307 | - React-debug (0.72.10)
308 | - React-hermes (0.72.10):
309 | - DoubleConversion
310 | - glog
311 | - hermes-engine
312 | - RCT-Folly (= 2021.07.22.00)
313 | - RCT-Folly/Futures (= 2021.07.22.00)
314 | - React-cxxreact (= 0.72.10)
315 | - React-jsi
316 | - React-jsiexecutor (= 0.72.10)
317 | - React-jsinspector (= 0.72.10)
318 | - React-perflogger (= 0.72.10)
319 | - React-jsi (0.72.10):
320 | - boost (= 1.76.0)
321 | - DoubleConversion
322 | - glog
323 | - hermes-engine
324 | - RCT-Folly (= 2021.07.22.00)
325 | - React-jsiexecutor (0.72.10):
326 | - DoubleConversion
327 | - glog
328 | - hermes-engine
329 | - RCT-Folly (= 2021.07.22.00)
330 | - React-cxxreact (= 0.72.10)
331 | - React-jsi (= 0.72.10)
332 | - React-perflogger (= 0.72.10)
333 | - React-jsinspector (0.72.10)
334 | - React-logger (0.72.10):
335 | - glog
336 | - react-native-safe-area-context (4.6.3):
337 | - RCT-Folly
338 | - RCTRequired
339 | - RCTTypeSafety
340 | - React-Core
341 | - ReactCommon/turbomodule/core
342 | - React-NativeModulesApple (0.72.10):
343 | - hermes-engine
344 | - React-callinvoker
345 | - React-Core
346 | - React-cxxreact
347 | - React-jsi
348 | - React-runtimeexecutor
349 | - ReactCommon/turbomodule/bridging
350 | - ReactCommon/turbomodule/core
351 | - React-perflogger (0.72.10)
352 | - React-RCTActionSheet (0.72.10):
353 | - React-Core/RCTActionSheetHeaders (= 0.72.10)
354 | - React-RCTAnimation (0.72.10):
355 | - RCT-Folly (= 2021.07.22.00)
356 | - RCTTypeSafety (= 0.72.10)
357 | - React-Codegen (= 0.72.10)
358 | - React-Core/RCTAnimationHeaders (= 0.72.10)
359 | - React-jsi (= 0.72.10)
360 | - ReactCommon/turbomodule/core (= 0.72.10)
361 | - React-RCTAppDelegate (0.72.10):
362 | - RCT-Folly
363 | - RCTRequired
364 | - RCTTypeSafety
365 | - React-Core
366 | - React-CoreModules
367 | - React-hermes
368 | - React-NativeModulesApple
369 | - React-RCTImage
370 | - React-RCTNetwork
371 | - React-runtimescheduler
372 | - ReactCommon/turbomodule/core
373 | - React-RCTBlob (0.72.10):
374 | - hermes-engine
375 | - RCT-Folly (= 2021.07.22.00)
376 | - React-Codegen (= 0.72.10)
377 | - React-Core/RCTBlobHeaders (= 0.72.10)
378 | - React-Core/RCTWebSocket (= 0.72.10)
379 | - React-jsi (= 0.72.10)
380 | - React-RCTNetwork (= 0.72.10)
381 | - ReactCommon/turbomodule/core (= 0.72.10)
382 | - React-RCTImage (0.72.10):
383 | - RCT-Folly (= 2021.07.22.00)
384 | - RCTTypeSafety (= 0.72.10)
385 | - React-Codegen (= 0.72.10)
386 | - React-Core/RCTImageHeaders (= 0.72.10)
387 | - React-jsi (= 0.72.10)
388 | - React-RCTNetwork (= 0.72.10)
389 | - ReactCommon/turbomodule/core (= 0.72.10)
390 | - React-RCTLinking (0.72.10):
391 | - React-Codegen (= 0.72.10)
392 | - React-Core/RCTLinkingHeaders (= 0.72.10)
393 | - React-jsi (= 0.72.10)
394 | - ReactCommon/turbomodule/core (= 0.72.10)
395 | - React-RCTNetwork (0.72.10):
396 | - RCT-Folly (= 2021.07.22.00)
397 | - RCTTypeSafety (= 0.72.10)
398 | - React-Codegen (= 0.72.10)
399 | - React-Core/RCTNetworkHeaders (= 0.72.10)
400 | - React-jsi (= 0.72.10)
401 | - ReactCommon/turbomodule/core (= 0.72.10)
402 | - React-RCTSettings (0.72.10):
403 | - RCT-Folly (= 2021.07.22.00)
404 | - RCTTypeSafety (= 0.72.10)
405 | - React-Codegen (= 0.72.10)
406 | - React-Core/RCTSettingsHeaders (= 0.72.10)
407 | - React-jsi (= 0.72.10)
408 | - ReactCommon/turbomodule/core (= 0.72.10)
409 | - React-RCTText (0.72.10):
410 | - React-Core/RCTTextHeaders (= 0.72.10)
411 | - React-RCTVibration (0.72.10):
412 | - RCT-Folly (= 2021.07.22.00)
413 | - React-Codegen (= 0.72.10)
414 | - React-Core/RCTVibrationHeaders (= 0.72.10)
415 | - React-jsi (= 0.72.10)
416 | - ReactCommon/turbomodule/core (= 0.72.10)
417 | - React-rncore (0.72.10)
418 | - React-runtimeexecutor (0.72.10):
419 | - React-jsi (= 0.72.10)
420 | - React-runtimescheduler (0.72.10):
421 | - glog
422 | - hermes-engine
423 | - RCT-Folly (= 2021.07.22.00)
424 | - React-callinvoker
425 | - React-debug
426 | - React-jsi
427 | - React-runtimeexecutor
428 | - React-utils (0.72.10):
429 | - glog
430 | - RCT-Folly (= 2021.07.22.00)
431 | - React-debug
432 | - ReactCommon/turbomodule/bridging (0.72.10):
433 | - DoubleConversion
434 | - glog
435 | - hermes-engine
436 | - RCT-Folly (= 2021.07.22.00)
437 | - React-callinvoker (= 0.72.10)
438 | - React-cxxreact (= 0.72.10)
439 | - React-jsi (= 0.72.10)
440 | - React-logger (= 0.72.10)
441 | - React-perflogger (= 0.72.10)
442 | - ReactCommon/turbomodule/core (0.72.10):
443 | - DoubleConversion
444 | - glog
445 | - hermes-engine
446 | - RCT-Folly (= 2021.07.22.00)
447 | - React-callinvoker (= 0.72.10)
448 | - React-cxxreact (= 0.72.10)
449 | - React-jsi (= 0.72.10)
450 | - React-logger (= 0.72.10)
451 | - React-perflogger (= 0.72.10)
452 | - ReactNativeCAEmitterLayer (0.3.0):
453 | - ExpoModulesCore
454 | - SocketRocket (0.6.1)
455 | - Yoga (1.14.0)
456 |
457 | DEPENDENCIES:
458 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
459 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
460 | - EXApplication (from `../node_modules/expo-application/ios`)
461 | - EXConstants (from `../node_modules/expo-constants/ios`)
462 | - EXFileSystem (from `../node_modules/expo-file-system/ios`)
463 | - EXFont (from `../node_modules/expo-font/ios`)
464 | - Expo (from `../node_modules/expo`)
465 | - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
466 | - ExpoModulesCore (from `../node_modules/expo-modules-core`)
467 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
468 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
469 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
470 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
471 | - libevent (~> 2.1.12)
472 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
473 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
474 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
475 | - React (from `../node_modules/react-native/`)
476 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
477 | - React-Codegen (from `build/generated/ios`)
478 | - React-Core (from `../node_modules/react-native/`)
479 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
480 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
481 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
482 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`)
483 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
484 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
485 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
486 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
487 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
488 | - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
489 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
490 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
491 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
492 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
493 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
494 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
495 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
496 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
497 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
498 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
499 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
500 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
501 | - React-rncore (from `../node_modules/react-native/ReactCommon`)
502 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
503 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
504 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
505 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
506 | - ReactNativeCAEmitterLayer (from `../../ios`)
507 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
508 |
509 | SPEC REPOS:
510 | trunk:
511 | - fmt
512 | - libevent
513 | - SocketRocket
514 |
515 | EXTERNAL SOURCES:
516 | boost:
517 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
518 | DoubleConversion:
519 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
520 | EXApplication:
521 | :path: "../node_modules/expo-application/ios"
522 | EXConstants:
523 | :path: "../node_modules/expo-constants/ios"
524 | EXFileSystem:
525 | :path: "../node_modules/expo-file-system/ios"
526 | EXFont:
527 | :path: "../node_modules/expo-font/ios"
528 | Expo:
529 | :path: "../node_modules/expo"
530 | ExpoKeepAwake:
531 | :path: "../node_modules/expo-keep-awake/ios"
532 | ExpoModulesCore:
533 | :path: "../node_modules/expo-modules-core"
534 | FBLazyVector:
535 | :path: "../node_modules/react-native/Libraries/FBLazyVector"
536 | FBReactNativeSpec:
537 | :path: "../node_modules/react-native/React/FBReactNativeSpec"
538 | glog:
539 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
540 | hermes-engine:
541 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
542 | RCT-Folly:
543 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
544 | RCTRequired:
545 | :path: "../node_modules/react-native/Libraries/RCTRequired"
546 | RCTTypeSafety:
547 | :path: "../node_modules/react-native/Libraries/TypeSafety"
548 | React:
549 | :path: "../node_modules/react-native/"
550 | React-callinvoker:
551 | :path: "../node_modules/react-native/ReactCommon/callinvoker"
552 | React-Codegen:
553 | :path: build/generated/ios
554 | React-Core:
555 | :path: "../node_modules/react-native/"
556 | React-CoreModules:
557 | :path: "../node_modules/react-native/React/CoreModules"
558 | React-cxxreact:
559 | :path: "../node_modules/react-native/ReactCommon/cxxreact"
560 | React-debug:
561 | :path: "../node_modules/react-native/ReactCommon/react/debug"
562 | React-hermes:
563 | :path: "../node_modules/react-native/ReactCommon/hermes"
564 | React-jsi:
565 | :path: "../node_modules/react-native/ReactCommon/jsi"
566 | React-jsiexecutor:
567 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
568 | React-jsinspector:
569 | :path: "../node_modules/react-native/ReactCommon/jsinspector"
570 | React-logger:
571 | :path: "../node_modules/react-native/ReactCommon/logger"
572 | react-native-safe-area-context:
573 | :path: "../node_modules/react-native-safe-area-context"
574 | React-NativeModulesApple:
575 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
576 | React-perflogger:
577 | :path: "../node_modules/react-native/ReactCommon/reactperflogger"
578 | React-RCTActionSheet:
579 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
580 | React-RCTAnimation:
581 | :path: "../node_modules/react-native/Libraries/NativeAnimation"
582 | React-RCTAppDelegate:
583 | :path: "../node_modules/react-native/Libraries/AppDelegate"
584 | React-RCTBlob:
585 | :path: "../node_modules/react-native/Libraries/Blob"
586 | React-RCTImage:
587 | :path: "../node_modules/react-native/Libraries/Image"
588 | React-RCTLinking:
589 | :path: "../node_modules/react-native/Libraries/LinkingIOS"
590 | React-RCTNetwork:
591 | :path: "../node_modules/react-native/Libraries/Network"
592 | React-RCTSettings:
593 | :path: "../node_modules/react-native/Libraries/Settings"
594 | React-RCTText:
595 | :path: "../node_modules/react-native/Libraries/Text"
596 | React-RCTVibration:
597 | :path: "../node_modules/react-native/Libraries/Vibration"
598 | React-rncore:
599 | :path: "../node_modules/react-native/ReactCommon"
600 | React-runtimeexecutor:
601 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
602 | React-runtimescheduler:
603 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler"
604 | React-utils:
605 | :path: "../node_modules/react-native/ReactCommon/react/utils"
606 | ReactCommon:
607 | :path: "../node_modules/react-native/ReactCommon"
608 | ReactNativeCAEmitterLayer:
609 | :path: "../../ios"
610 | Yoga:
611 | :path: "../node_modules/react-native/ReactCommon/yoga"
612 |
613 | SPEC CHECKSUMS:
614 | boost: 57d2868c099736d80fcd648bf211b4431e51a558
615 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
616 | EXApplication: 042aa2e3f05258a16962ea1a9914bf288db9c9a1
617 | EXConstants: ce5bbea779da8031ac818c36bea41b10e14d04e1
618 | EXFileSystem: f8b838a880254de42a5a7da20ed5ce12e2697c1b
619 | EXFont: 738c44c390953ebcbab075a4848bfbef025fd9ee
620 | Expo: ba9abdf444dc6d2c05a82c4c1b51a2400beb6167
621 | ExpoKeepAwake: be4cbd52d9b177cde0fd66daa1913afa3161fc1d
622 | ExpoModulesCore: cf14fc49a3d5df3ed3cf2a38fc758d073bfd1c13
623 | FBLazyVector: f91d538f197fa71a7d5b77ec2069d49550c0eb96
624 | FBReactNativeSpec: b13d1c23d6ed82d6b66aad7a253edf8ba76c4a4c
625 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
626 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
627 | hermes-engine: 38bfe887e456b33b697187570a08de33969f5db7
628 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
629 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
630 | RCTRequired: b4d3068afa6f52ec5260a8417053b1f1b421483d
631 | RCTTypeSafety: a4551b3d338c96435f63bf06d564055c1d3cc0ac
632 | React: 66caa2a8192a35d7ba466a5fdf5dc06ee4a5f6dd
633 | React-callinvoker: e5b55e46894c2dd1bcdc19d4f82b0f7f631d1237
634 | React-Codegen: 0cf41e00026c5eba61f6bdcabd6e4bf659754f33
635 | React-Core: 2ce84187a00913f287b96753c56c7819ed7d90d5
636 | React-CoreModules: 893e7c5eed1ef8fe9e1ee1d913581c946e55b305
637 | React-cxxreact: 075d98dc664c0e9607cc0c45d41dc052bcc7313b
638 | React-debug: abc6213dcb9eafcf5242cbb194fef4c70c91871f
639 | React-hermes: 133cfa220ef836406f693ed7db56a509032ce433
640 | React-jsi: 9b45fd040d575f8ae6771bf1960641a58eb0bdd4
641 | React-jsiexecutor: 45ef2ec6dcde31b90469175ec76ddac77b91dfc3
642 | React-jsinspector: de0198127395fec3058140a20c045167f761bb16
643 | React-logger: dc3a2b174d79c2da635059212747d8d929b54e06
644 | react-native-safe-area-context: 36cc67648134e89465663b8172336a19eeda493d
645 | React-NativeModulesApple: c3e696ff867e4bc212266cbdf7e862e48a0166fd
646 | React-perflogger: 43287389ea08993c300897a46f95cfac04bb6c1a
647 | React-RCTActionSheet: 923afe77f9bb89da7c1f98e2730bfc9dde0eed6d
648 | React-RCTAnimation: afd4d94c5e1f731e32ac99800850be06564ac642
649 | React-RCTAppDelegate: fb2e1447d014557f29e214fe2eb777442f808a3b
650 | React-RCTBlob: 167e2c6c3643f093058c51e76ecc653fc8236033
651 | React-RCTImage: 867de82a17630a08a3fa64b0cd6677dd19bf6eaf
652 | React-RCTLinking: 885dde8bc5d397c3e72c76315f1f9b5030b3a70e
653 | React-RCTNetwork: efec71102220b96ac8605d0253debd859ca0c817
654 | React-RCTSettings: 077065d0a4e925b017fe8538afa574d8fb52391f
655 | React-RCTText: 7adddb518ac362b2398fedf0c64105e0dab29441
656 | React-RCTVibration: de6b7218e415d82788e0965f278dddb2ef88b372
657 | React-rncore: f0d8c23481a6c263a343fa7fd3816d943754b720
658 | React-runtimeexecutor: 2b2c09edbca4c9a667428e8c93959f66b3b53140
659 | React-runtimescheduler: 6ca43e8deadf01ff06b3f01abf8f0e4d508e23c3
660 | React-utils: 372b83030a74347331636909278bf0a60ec30d59
661 | ReactCommon: 38824bfffaf4c51fbe03a2730b4fd874ef34d67b
662 | ReactNativeCAEmitterLayer: 967c956c3ec4ae2d9a156c8017e4893cf0833433
663 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
664 | Yoga: d0003f849d2b5224c072cef6568b540d8bb15cd3
665 |
666 | PODFILE CHECKSUM: 02de889b2c827e6b0f2e4ce6659e4f9934870dbb
667 |
668 | COCOAPODS: 1.11.3
669 |
--------------------------------------------------------------------------------
/example/ios/Podfile.properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo.jsEngine": "hermes"
3 | }
4 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample.xcodeproj/xcshareddata/xcschemes/reactnativecaemitterlayerexample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @interface AppDelegate : EXAppDelegateWrapper
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 | #import
5 |
6 | @implementation AppDelegate
7 |
8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
9 | {
10 | self.moduleName = @"main";
11 |
12 | // You can add your custom initial props in the dictionary below.
13 | // They will be passed down to the ViewController used by React Native.
14 | self.initialProps = @{};
15 |
16 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
17 | }
18 |
19 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
20 | {
21 | #if DEBUG
22 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
23 | #else
24 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
25 | #endif
26 | }
27 |
28 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
29 | ///
30 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
31 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
32 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
33 | - (BOOL)concurrentRootEnabled
34 | {
35 | return true;
36 | }
37 |
38 | // Linking API
39 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options {
40 | return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
41 | }
42 |
43 | // Universal Links
44 | - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler {
45 | BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
46 | return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
47 | }
48 |
49 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
50 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
51 | {
52 | return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
53 | }
54 |
55 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
56 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
57 | {
58 | return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
59 | }
60 |
61 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
62 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
63 | {
64 | return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "iphone",
5 | "size": "20x20",
6 | "scale": "2x",
7 | "filename": "App-Icon-20x20@2x.png"
8 | },
9 | {
10 | "idiom": "iphone",
11 | "size": "20x20",
12 | "scale": "3x",
13 | "filename": "App-Icon-20x20@3x.png"
14 | },
15 | {
16 | "idiom": "iphone",
17 | "size": "29x29",
18 | "scale": "1x",
19 | "filename": "App-Icon-29x29@1x.png"
20 | },
21 | {
22 | "idiom": "iphone",
23 | "size": "29x29",
24 | "scale": "2x",
25 | "filename": "App-Icon-29x29@2x.png"
26 | },
27 | {
28 | "idiom": "iphone",
29 | "size": "29x29",
30 | "scale": "3x",
31 | "filename": "App-Icon-29x29@3x.png"
32 | },
33 | {
34 | "idiom": "iphone",
35 | "size": "40x40",
36 | "scale": "2x",
37 | "filename": "App-Icon-40x40@2x.png"
38 | },
39 | {
40 | "idiom": "iphone",
41 | "size": "40x40",
42 | "scale": "3x",
43 | "filename": "App-Icon-40x40@3x.png"
44 | },
45 | {
46 | "idiom": "iphone",
47 | "size": "60x60",
48 | "scale": "2x",
49 | "filename": "App-Icon-60x60@2x.png"
50 | },
51 | {
52 | "idiom": "iphone",
53 | "size": "60x60",
54 | "scale": "3x",
55 | "filename": "App-Icon-60x60@3x.png"
56 | },
57 | {
58 | "idiom": "ipad",
59 | "size": "20x20",
60 | "scale": "1x",
61 | "filename": "App-Icon-20x20@1x.png"
62 | },
63 | {
64 | "idiom": "ipad",
65 | "size": "20x20",
66 | "scale": "2x",
67 | "filename": "App-Icon-20x20@2x.png"
68 | },
69 | {
70 | "idiom": "ipad",
71 | "size": "29x29",
72 | "scale": "1x",
73 | "filename": "App-Icon-29x29@1x.png"
74 | },
75 | {
76 | "idiom": "ipad",
77 | "size": "29x29",
78 | "scale": "2x",
79 | "filename": "App-Icon-29x29@2x.png"
80 | },
81 | {
82 | "idiom": "ipad",
83 | "size": "40x40",
84 | "scale": "1x",
85 | "filename": "App-Icon-40x40@1x.png"
86 | },
87 | {
88 | "idiom": "ipad",
89 | "size": "40x40",
90 | "scale": "2x",
91 | "filename": "App-Icon-40x40@2x.png"
92 | },
93 | {
94 | "idiom": "ipad",
95 | "size": "76x76",
96 | "scale": "1x",
97 | "filename": "App-Icon-76x76@1x.png"
98 | },
99 | {
100 | "idiom": "ipad",
101 | "size": "76x76",
102 | "scale": "2x",
103 | "filename": "App-Icon-76x76@2x.png"
104 | },
105 | {
106 | "idiom": "ipad",
107 | "size": "83.5x83.5",
108 | "scale": "2x",
109 | "filename": "App-Icon-83.5x83.5@2x.png"
110 | },
111 | {
112 | "idiom": "ios-marketing",
113 | "size": "1024x1024",
114 | "scale": "1x",
115 | "filename": "ItunesArtwork@2x.png"
116 | }
117 | ],
118 | "info": {
119 | "version": 1,
120 | "author": "expo"
121 | }
122 | }
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "expo"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/SplashScreen.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "image.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "scale": "2x"
11 | },
12 | {
13 | "idiom": "universal",
14 | "scale": "3x"
15 | }
16 | ],
17 | "info": {
18 | "version": 1,
19 | "author": "expo"
20 | }
21 | }
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/SplashScreen.imageset/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/SplashScreen.imageset/image.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/SplashScreenBackground.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "image.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "scale": "2x"
11 | },
12 | {
13 | "idiom": "universal",
14 | "scale": "3x"
15 | }
16 | ],
17 | "info": {
18 | "version": 1,
19 | "author": "expo"
20 | }
21 | }
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Images.xcassets/SplashScreenBackground.imageset/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DigitalZebra/react-native-caemitterlayer/ba343cd28bef0b44c8f2767eecf161b3ff20c492/example/ios/reactnativecaemitterlayerexample/Images.xcassets/SplashScreenBackground.imageset/image.png
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | react-native-caemitterlayer-example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0.0
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleURLSchemes
27 |
28 | expo.modules.caemitterlayer.example
29 |
30 |
31 |
32 | CFBundleVersion
33 | 1
34 | LSRequiresIPhoneOS
35 |
36 | NSAppTransportSecurity
37 |
38 | NSAllowsArbitraryLoads
39 |
40 | NSExceptionDomains
41 |
42 | localhost
43 |
44 | NSExceptionAllowsInsecureHTTPLoads
45 |
46 |
47 |
48 |
49 | UILaunchStoryboardName
50 | SplashScreen
51 | UIRequiredDeviceCapabilities
52 |
53 | armv7
54 |
55 | UIRequiresFullScreen
56 |
57 | UIStatusBarStyle
58 | UIStatusBarStyleDefault
59 | UISupportedInterfaceOrientations
60 |
61 | UIInterfaceOrientationPortrait
62 | UIInterfaceOrientationPortraitUpsideDown
63 |
64 | UISupportedInterfaceOrientations~ipad
65 |
66 | UIInterfaceOrientationPortrait
67 | UIInterfaceOrientationPortraitUpsideDown
68 | UIInterfaceOrientationLandscapeLeft
69 | UIInterfaceOrientationLandscapeRight
70 |
71 | UIUserInterfaceStyle
72 | Light
73 | UIViewControllerBasedStatusBarAppearance
74 |
75 |
76 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/SplashScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/Supporting/Expo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | EXUpdatesCheckOnLaunch
6 | ALWAYS
7 | EXUpdatesEnabled
8 |
9 | EXUpdatesLaunchWaitMs
10 | 0
11 | EXUpdatesSDKVersion
12 | 48.0.0
13 | EXUpdatesURL
14 | https://exp.host/@digitalzebra/react-native-caemitterlayer-example
15 |
16 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char * argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/noop-file.swift:
--------------------------------------------------------------------------------
1 | //
2 | // @generated
3 | // A blank Swift file must be created for native modules with Swift files to work correctly.
4 | //
5 |
--------------------------------------------------------------------------------
/example/ios/reactnativecaemitterlayerexample/reactnativecaemitterlayerexample.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 |
8 |
--------------------------------------------------------------------------------
/example/metro.config.js:
--------------------------------------------------------------------------------
1 | // Learn more https://docs.expo.io/guides/customizing-metro
2 | const { getDefaultConfig } = require('expo/metro-config');
3 | const path = require('path');
4 |
5 | const config = getDefaultConfig(__dirname);
6 |
7 | // npm v7+ will install ../node_modules/react-native because of peerDependencies.
8 | // To prevent the incompatible react-native bewtween ./node_modules/react-native and ../node_modules/react-native,
9 | // excludes the one from the parent folder when bundling.
10 | config.resolver.blockList = [
11 | ...Array.from(config.resolver.blockList ?? []),
12 | new RegExp(path.resolve('..', 'node_modules', 'react-native')),
13 | ];
14 |
15 | config.resolver.nodeModulesPaths = [
16 | path.resolve(__dirname, './node_modules'),
17 | path.resolve(__dirname, '../node_modules'),
18 | ];
19 |
20 | config.watchFolders = [path.resolve(__dirname, '..')];
21 |
22 | config.transformer.getTransformOptions = async () => ({
23 | transform: {
24 | experimentalImportSupport: false,
25 | inlineRequires: true,
26 | },
27 | });
28 |
29 | module.exports = config;
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-caemitterlayer-example",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "start": "expo start --dev-client",
6 | "android": "expo run:android",
7 | "ios": "expo run:ios",
8 | "web": "expo start --web"
9 | },
10 | "dependencies": {
11 | "expo": "^49.0.23",
12 | "react": "18.2.0",
13 | "react-native": "0.72.10",
14 | "react-native-safe-area-context": "4.6.3"
15 | },
16 | "devDependencies": {
17 | "@babel/core": "^7.20.0",
18 | "@types/react": "~18.2.14",
19 | "typescript": "^5.1.3"
20 | },
21 | "private": true,
22 | "expo": {
23 | "autolinking": {
24 | "nativeModulesDir": ".."
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "expo/tsconfig.base",
3 | "compilerOptions": {
4 | "strict": true,
5 | "paths": {
6 | "react-native-caemitterlayer": ["../src/index"],
7 | "react-native-caemitterlayer/*": ["../src/*"]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | const createConfigAsync = require('@expo/webpack-config');
2 | const path = require('path');
3 |
4 | module.exports = async (env, argv) => {
5 | const config = await createConfigAsync(
6 | {
7 | ...env,
8 | babel: {
9 | dangerouslyAddModulePathsToTranspile: ['react-native-caemitterlayer'],
10 | },
11 | },
12 | argv
13 | );
14 | config.resolve.modules = [
15 | path.resolve(__dirname, './node_modules'),
16 | path.resolve(__dirname, '../node_modules'),
17 | ];
18 |
19 | return config;
20 | };
21 |
--------------------------------------------------------------------------------
/expo-module.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "platforms": ["ios", "android", "web"],
3 | "ios": {
4 | "modules": ["ReactNativeCAEmitterLayerModule"]
5 | },
6 | "android": {
7 | "modules": ["expo.modules.caemitterlayer.ReactNativeCAEmitterLayerModule"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ios/CAEmitterLayer+InitialValuesSync.swift:
--------------------------------------------------------------------------------
1 | import ExpoModulesCore
2 | import Foundation
3 |
4 | protocol InitialValuesSync {
5 | func syncInitialValues(values: InitialLayerValues)
6 | }
7 |
8 | extension CAEmitterLayer {
9 | func syncInitialValues(values: InitialLayerValues) throws {
10 | if let seed = values.seed {
11 | self.seed = seed
12 | }
13 |
14 | if let beginTime = values.beginTime {
15 | switch beginTime {
16 | case let .number(d):
17 | self.beginTime = d
18 | case let .string(s):
19 | switch s {
20 | case "currentTime":
21 | self.beginTime = CACurrentMediaTime()
22 | default:
23 | throw LayerException(field: "beginTime")
24 | }
25 | }
26 | }
27 |
28 | if let timeOffset = values.timeOffset {
29 | self.timeOffset = timeOffset
30 | }
31 |
32 | if let repeatCount = values.repeatCount {
33 | self.repeatCount = repeatCount
34 | }
35 |
36 | if let repeatDuration = values.repeatDuration {
37 | self.repeatDuration = repeatDuration
38 | }
39 |
40 | if let autoreverses = values.autoreverses {
41 | self.autoreverses = autoreverses
42 | }
43 |
44 | if let fillMode = values.fillMode {
45 | self.fillMode = CAMediaTimingFillMode(rawValue: fillMode)
46 | }
47 |
48 | if let speed = values.speed {
49 | self.speed = speed
50 | }
51 |
52 | if let duration = values.duration {
53 | self.duration = duration
54 | }
55 | }
56 | }
57 |
58 | internal class LayerException: Exception {
59 | var field: String?
60 |
61 | convenience init(field: String) {
62 | self.init()
63 | }
64 |
65 | override var reason: String {
66 | let extra: String
67 |
68 | if let field = field {
69 | extra = "Field: \(field)"
70 | }
71 | else {
72 | extra = ""
73 | }
74 |
75 | return "Error mapping layer configuration to CAEmitterLayer. \(extra)"
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/ios/EmitterImageLoader.swift:
--------------------------------------------------------------------------------
1 | import Combine
2 | import ExpoModulesCore
3 | import Foundation
4 | import React
5 |
6 | enum ImageLoadingError: Error {
7 | case noImageLoaded
8 | }
9 |
10 | class EmitterImageLoader {
11 | let imageLoader: RCTImageLoader
12 |
13 | var cancellables = Set()
14 |
15 | init(rctImageLoader: RCTImageLoader) {
16 | imageLoader = rctImageLoader
17 | }
18 |
19 | private func gatherImageSources(cellConfigs: [CellConfig]?) -> Set {
20 | guard let cellConfigs, cellConfigs.count != 0 else { return Set() }
21 |
22 | var finalSet = Set()
23 | var cellsToCheck: [CellConfig] = cellConfigs
24 |
25 | while cellsToCheck.count > 0 {
26 | let cell = cellsToCheck.removeFirst()
27 |
28 | if let imageContents = cell.imageContents {
29 | finalSet.insert(imageContents.uri)
30 | }
31 |
32 | if let moreCells = cell.emitterCells {
33 | cellsToCheck.append(contentsOf: moreCells)
34 | }
35 | }
36 |
37 | return finalSet
38 | }
39 |
40 | public func loadImagesFor(cellConfigs: [CellConfig]?, completion: @escaping ([String: UIImage]) -> Void) {
41 | // drop any requests in progress
42 | cancellables = Set()
43 |
44 | let imageSources = gatherImageSources(cellConfigs: cellConfigs)
45 |
46 | guard !imageSources.isEmpty else {
47 | completion([:])
48 | return
49 | }
50 |
51 | try? loadImagesAsync(images: imageSources, completion: completion)
52 | }
53 |
54 | private func loadImagesAsync(images: Set, completion: @escaping ([String: UIImage]) -> Void) throws {
55 | let futures = try images.map { uri in
56 | guard let url = URL(string: uri) else {
57 | throw GenericException("Error creating URL from URI string")
58 | }
59 |
60 | return AnyPublisher(Future<(String, UIImage), Error> { [weak self] promise in
61 | self?.imageLoader.loadImage(with: URLRequest(url: url)) { error, image in
62 | guard let image = image else {
63 | promise(.failure(error ?? ImageLoadingError.noImageLoaded))
64 | return
65 | }
66 |
67 | promise(.success((uri, image)))
68 | }
69 | })
70 | }
71 |
72 | Publishers.MergeMany(futures).collect().sink(receiveCompletion: { completion in
73 | switch completion {
74 | case .finished:
75 | // no-op
76 | break
77 | case .failure(let err):
78 | // TODO: what to do if there's an error..?
79 | print(err)
80 | }
81 | }, receiveValue: { images in
82 | let imageMap: [String: UIImage] = images.reduce(into: [:]) { result, tuple in
83 | let (key, value) = tuple
84 | result[key] = value
85 | }
86 |
87 | completion(imageMap)
88 | }).store(in: &cancellables)
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/ios/Helpers.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct Helpers {
4 | static func testCell() -> CAEmitterCell {
5 | UIGraphicsBeginImageContextWithOptions(CGSize(width: 20, height: 20), false, 0)
6 | let ctx = UIGraphicsGetCurrentContext()!
7 | ctx.saveGState()
8 |
9 | let rect = CGRect(x: 0, y: 0, width: 20, height: 20)
10 | ctx.setFillColor(UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.5).cgColor)
11 | ctx.fillEllipse(in: rect)
12 |
13 | ctx.restoreGState()
14 | let img = UIGraphicsGetImageFromCurrentImageContext()!
15 | UIGraphicsEndImageContext()
16 |
17 | let c = CAEmitterCell()
18 | c.velocity = 10
19 | c.emissionLongitude = .pi / 2
20 | c.emissionLatitude = .pi / 2
21 | c.birthRate = 10
22 | c.lifetime = 1.4
23 | c.lifetimeRange = 0.1
24 | c.velocity = 32
25 | c.velocityRange = 6
26 | c.emissionRange = 0
27 | c.yAcceleration = -60
28 | c.xAcceleration = -30
29 | c.scaleSpeed = -0.2
30 |
31 | if #available(iOS 13.0, *) {
32 | c.color = CGColor(red: 0.1, green: 0.4, blue: 0.2, alpha: 0.1)
33 | }
34 |
35 | c.contents = img.cgImage
36 |
37 | return c
38 | }
39 |
40 | func createImage() -> CGImage? {
41 | UIGraphicsBeginImageContextWithOptions(CGSize(width: 20, height: 20), false, 0)
42 | let ctx = UIGraphicsGetCurrentContext()!
43 | ctx.saveGState()
44 |
45 | let rect = CGRect(x: 0, y: 0, width: 20, height: 20)
46 | ctx.setFillColor(UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.5).cgColor)
47 | ctx.fillEllipse(in: rect)
48 |
49 | ctx.restoreGState()
50 | let img = UIGraphicsGetImageFromCurrentImageContext()!
51 | UIGraphicsEndImageContext()
52 |
53 | return img.cgImage
54 | }
55 |
56 | static func createImage(from: String) -> CGImage? {
57 | let font = UIFont.systemFont(ofSize: 16.0)
58 |
59 | let string = NSString(string: from)
60 | let attributes: [NSAttributedString.Key: Any] = [
61 | .font: font
62 | ]
63 | let size = string.size(withAttributes: attributes)
64 |
65 | return UIGraphicsImageRenderer(size: size).image { _ in
66 | string.draw(at: .zero, withAttributes: attributes)
67 | }.cgImage
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ios/Mapping/AnyValue.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | enum AnyValue: Decodable {
4 | case number(Double), string(String)
5 |
6 | init(from decoder: Decoder) throws {
7 | if let numValue = try? decoder.singleValueContainer().decode(Double.self) {
8 | self = .number(numValue)
9 | return
10 | }
11 |
12 | if let stringValue = try? decoder.singleValueContainer().decode(String.self) {
13 | self = .string(stringValue)
14 | return
15 | }
16 |
17 | throw AnyValueError.missingValue
18 | }
19 |
20 | var anyValue: Any {
21 | switch self {
22 | case let .number(n):
23 | return n
24 | case let .string(s):
25 | return s
26 | }
27 | }
28 |
29 | enum AnyValueError: Error {
30 | case missingValue
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ios/Mapping/EmitterConfiguration.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct EmitterConfiguration: JsonConvertible {
4 | let layer: LayerConfig
5 | }
6 |
7 | struct LayerConfig: Decodable {
8 | let initialValues: InitialLayerValues
9 | let enabled: Bool
10 |
11 | let scale: Float
12 | let spin: Float
13 | let velocity: Float
14 | let birthRate: Float
15 | let lifetime: Float
16 | let preservesDepth: Bool
17 |
18 | let renderMode: String
19 | let emitterZPosition: CGFloat
20 | let emitterDepth: CGFloat
21 | let emitterSize: Size
22 |
23 | let emitterPosition: Position
24 |
25 | let emitterMode: String // todo - this needs to deserialize to an enum
26 | let emitterShape: String // todo - this needs to deserialize to an enum
27 |
28 | let emitterCells: [CellConfig]
29 | }
30 |
31 | struct Size: Decodable {
32 | let width: Double
33 | let height: Double
34 | }
35 |
36 | struct Position: Decodable {
37 | let x: Double
38 | let y: Double
39 | }
40 |
41 | struct InitialLayerValues: Decodable {
42 | let seed: UInt32?
43 |
44 | // CAMediaTiming properties
45 | let beginTime: AnyValue?
46 | let timeOffset: Double?
47 | let repeatCount: Float?
48 | let repeatDuration: Double?
49 | let autoreverses: Bool?
50 | let fillMode: String?
51 | let speed: Float?
52 | let duration: Double?
53 | }
54 |
55 | struct CellConfig: Decodable {
56 |
57 | // MARK: Contents types
58 | let imageData: String?
59 | let imageContents: DecodableRCTCAImageSource?
60 | let stringContents: StringContents?
61 | let contents: StringContents?
62 |
63 | let isEnabled: Bool
64 |
65 | let color: String
66 |
67 | let contentsScale: CGFloat
68 |
69 | let emissionLatitude: CGFloat
70 | let emissionLongitude: CGFloat
71 | let emissionRange: CGFloat
72 |
73 | let redRange: Float
74 | let greenRange: Float
75 | let blueRange: Float
76 | let alphaRange: Float
77 |
78 | let redSpeed: Float
79 | let greenSpeed: Float
80 | let blueSpeed: Float
81 | let alphaSpeed: Float
82 |
83 | let scale: CGFloat
84 | let scaleRange: CGFloat
85 | let scaleSpeed: CGFloat
86 |
87 | let spin: CGFloat
88 | let spinRange: CGFloat
89 |
90 | let lifetime: Float
91 | let lifetimeRange: Float
92 |
93 | let birthRate: Float
94 |
95 | let velocity: CGFloat
96 | let velocityRange: CGFloat
97 |
98 | let xAcceleration: CGFloat
99 | let yAcceleration: CGFloat
100 | let zAcceleration: CGFloat
101 |
102 | // CAMediaTiming propertimes
103 | let beginTime: Double?
104 | let timeOffset: Double?
105 | let repeatCount: Float?
106 | let repeatDuration: Double?
107 | let autoreverses: Bool?
108 | let fillMode: String?
109 | let speed: Float?
110 | let duration: Double?
111 |
112 | let values: [String: AnyValue]
113 |
114 | let emitterCells: [CellConfig]?
115 | }
116 |
--------------------------------------------------------------------------------
/ios/Mapping/JsonConvertible.swift:
--------------------------------------------------------------------------------
1 | import ExpoModulesCore
2 | import Foundation
3 |
4 | // An object that is Convertible from JSON
5 | protocol JsonConvertible: Decodable, Convertible, AnyArgument {}
6 |
7 | extension JsonConvertible {
8 | static func convert(from value: Any?, appContext: AppContext) throws -> Self {
9 | let vstring = value as? String
10 |
11 | guard let vstring else {
12 | throw ConversionException()
13 | }
14 |
15 | let d = Data(vstring.utf8)
16 | let r = try JSONDecoder().decode(Self.self, from: d)
17 |
18 | return r
19 | }
20 | }
21 |
22 | internal class ConversionException: Exception {
23 | override var reason: String {
24 | "Something went wrong hydrating module props."
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ios/Mapping/RCTCAImageSource.swift:
--------------------------------------------------------------------------------
1 | import ExpoModulesCore
2 | import Foundation
3 |
4 | struct RCTCAImageSource: Record {
5 | @Field
6 | var width: Double = 0.0
7 |
8 | @Field
9 | var height: Double = 0.0
10 |
11 | @Field
12 | var uri: URL? = nil
13 |
14 | @Field
15 | var scale: Double = 1.0
16 | }
17 |
18 | struct DecodableRCTCAImageSource: Decodable {
19 | let width: Double
20 |
21 | let height: Double
22 |
23 | let uri: String
24 |
25 | let scale: Double
26 | }
27 |
--------------------------------------------------------------------------------
/ios/Mapping/StringContents.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | struct StringContents: Decodable {
4 | let value: String
5 | }
6 |
--------------------------------------------------------------------------------
/ios/ReactNativeCAEmitterLayer.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = 'ReactNativeCAEmitterLayer'
7 | s.version = package['version']
8 | s.summary = package['description']
9 | s.description = package['description']
10 | s.license = package['license']
11 | s.author = package['author']
12 | s.homepage = package['homepage']
13 | s.platform = :ios, '13.0'
14 | s.swift_version = '5.4'
15 | s.source = { git: 'https://github.com/DigitalZebra/react-native-caemitterlayer' }
16 | s.static_framework = true
17 |
18 | s.dependency 'ExpoModulesCore'
19 |
20 | # Swift/Objective-C compatibility
21 | s.pod_target_xcconfig = {
22 | 'DEFINES_MODULE' => 'YES',
23 | 'SWIFT_COMPILATION_MODE' => 'wholemodule'
24 | }
25 |
26 | s.source_files = "**/*.{h,m,swift}"
27 | end
28 |
--------------------------------------------------------------------------------
/ios/ReactNativeCAEmitterLayerModule.swift:
--------------------------------------------------------------------------------
1 | import ExpoModulesCore
2 |
3 | public class ReactNativeCAEmitterLayerModule: Module {
4 | public func definition() -> ModuleDefinition {
5 | Name("ReactNativeCAEmitterLayer")
6 |
7 | View(ReactNativeCAEmitterLayerView.self) {
8 | Prop("config") { (view: ReactNativeCAEmitterLayerView, prop: EmitterConfiguration) in
9 | do {
10 | try view.setCellConfig(config: prop)
11 | }
12 | catch {
13 | // TODO: is there an Expo way to re-throw these errors...?
14 | print("\(error)")
15 | }
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ios/ReactNativeCAEmitterLayerView.swift:
--------------------------------------------------------------------------------
1 | import ExpoModulesCore
2 | import Foundation
3 | import React
4 |
5 | class ReactNativeCAEmitterLayerView: ExpoView {
6 | var isEmitting: Bool = false
7 | var emitterImageLoader: EmitterImageLoader?
8 |
9 | private let emitter: CAEmitterLayer = {
10 | let emitterLayer = CAEmitterLayer()
11 |
12 | return emitterLayer
13 | }()
14 |
15 | func setUpEmitter() {
16 | layer.addSublayer(emitter)
17 | }
18 |
19 | required init(appContext: AppContext? = nil) {
20 | super.init(appContext: appContext)
21 |
22 | let imageLoader = appContext?.reactBridge?.module(for: RCTImageLoader.self) as? RCTImageLoader
23 | if let imageLoader {
24 | emitterImageLoader = EmitterImageLoader(rctImageLoader: imageLoader)
25 | }
26 |
27 | setUpEmitter()
28 | }
29 |
30 | func recursivelyMapCells(cellConfigs: [CellConfig]?, images: [String: UIImage]) -> [CAEmitterCell]? {
31 | guard let cellConfigs, cellConfigs.count != 0 else { return nil }
32 |
33 | let mappedCells = cellConfigs.map { (cellConfig: CellConfig) in
34 | let cell = CAEmitterCell()
35 | cell.isEnabled = cellConfig.isEnabled
36 |
37 | cell.contentsScale = cellConfig.contentsScale
38 |
39 | cell.emissionLatitude = cellConfig.emissionLatitude
40 | cell.emissionLongitude = cellConfig.emissionLongitude
41 | cell.emissionRange = cellConfig.emissionRange
42 |
43 | cell.redRange = cellConfig.redRange
44 | cell.greenRange = cellConfig.greenRange
45 | cell.blueRange = cellConfig.blueRange
46 | cell.alphaRange = cellConfig.alphaRange
47 |
48 | cell.redSpeed = cellConfig.redSpeed
49 | cell.greenSpeed = cellConfig.greenSpeed
50 | cell.blueSpeed = cellConfig.blueSpeed
51 | cell.alphaSpeed = cellConfig.alphaSpeed
52 |
53 | cell.scale = cellConfig.scale
54 | cell.scaleRange = cellConfig.scaleRange
55 | cell.scaleSpeed = cellConfig.scaleSpeed
56 |
57 | cell.spin = cellConfig.spin
58 | cell.spinRange = cellConfig.spinRange
59 |
60 | cell.lifetime = cellConfig.lifetime
61 | cell.lifetimeRange = cellConfig.lifetimeRange
62 |
63 | cell.birthRate = cellConfig.birthRate
64 | cell.velocity = cellConfig.velocity
65 | cell.velocityRange = cellConfig.velocityRange
66 |
67 | cell.xAcceleration = cellConfig.xAcceleration
68 | cell.yAcceleration = cellConfig.yAcceleration
69 | cell.zAcceleration = cellConfig.zAcceleration
70 |
71 | // CAMediaTiming properties - dangerous! check these, handle them differently
72 | if let beginTime = cellConfig.beginTime {
73 | cell.beginTime = beginTime
74 | }
75 |
76 | if let timeOffset = cellConfig.timeOffset {
77 | cell.timeOffset = timeOffset
78 | }
79 |
80 | if let repeatCount = cellConfig.repeatCount {
81 | cell.repeatCount = repeatCount
82 | }
83 |
84 | if let repeatDuration = cellConfig.repeatDuration {
85 | cell.repeatDuration = repeatDuration
86 | }
87 |
88 | if let autoReverses = cellConfig.autoreverses {
89 | cell.autoreverses = autoReverses
90 | }
91 |
92 | if let cellDuration = cellConfig.duration {
93 | cell.duration = cellDuration
94 | }
95 |
96 | if let speed = cellConfig.speed {
97 | cell.speed = speed
98 | }
99 |
100 | if let fillMode = cellConfig.fillMode {
101 | cell.fillMode = CAMediaTimingFillMode(rawValue: fillMode)
102 | }
103 |
104 | // TODO: don't silently fail here
105 | if let appContext = appContext {
106 | cell.color = try? CGColor.convert(from: cellConfig.color, appContext: appContext)
107 | }
108 |
109 | cellConfig.values.forEach { x in
110 | cell.setValue(x.value.anyValue, forKey: x.key)
111 | }
112 |
113 | cell.emitterCells = recursivelyMapCells(cellConfigs: cellConfig.emitterCells, images: images)
114 | cell.contents = contentsImageFor(cell: cellConfig, images: images)
115 |
116 | return cell
117 | }
118 |
119 | return mappedCells
120 | }
121 |
122 | private func contentsImageFor(cell: CellConfig, images: [String: UIImage]) -> CGImage? {
123 | if let stringContents = cell.contents {
124 | return Helpers.createImage(from: stringContents.value)
125 | }
126 | else if let stringContents = cell.stringContents {
127 | return Helpers.createImage(from: stringContents.value)
128 | }
129 | else if let imageData = cell.imageData {
130 | guard let data = Data(base64Encoded: imageData), let image = UIImage(data: data) else {
131 | return nil
132 | }
133 |
134 | return image.cgImage
135 | }
136 | else if let imageContents = cell.imageContents {
137 | return images[imageContents.uri]?.cgImage
138 | }
139 |
140 | // TODO: throw here?
141 | return nil
142 | }
143 |
144 | func setCellConfig(config: EmitterConfiguration) throws {
145 | let layer = config.layer
146 |
147 | emitter.velocity = layer.velocity
148 | emitter.scale = layer.scale
149 | emitter.spin = layer.spin
150 | emitter.lifetime = layer.lifetime
151 |
152 | emitter.renderMode = CAEmitterLayerRenderMode(rawValue: layer.renderMode)
153 | emitter.position = CGPoint(x: layer.emitterPosition.x, y: layer.emitterPosition.y)
154 | emitter.emitterZPosition = layer.emitterZPosition
155 | emitter.emitterDepth = layer.emitterDepth
156 |
157 | emitter.emitterMode = CAEmitterLayerEmitterMode(rawValue: layer.emitterMode)
158 | emitter.emitterShape = CAEmitterLayerEmitterShape(rawValue: layer.emitterShape)
159 | emitter.emitterSize = CGSize(width: layer.emitterSize.width, height: layer.emitterSize.height)
160 |
161 | emitterImageLoader?.loadImagesFor(cellConfigs: layer.emitterCells) { images in
162 | self.runOnMain {
163 | self.emitter.emitterCells = self.recursivelyMapCells(cellConfigs: layer.emitterCells, images: images)
164 | }
165 | }
166 |
167 | // If not emitting, and we want to emit, set initial values (if applicable)
168 | if !isEmitting, config.layer.enabled {
169 | emitter.birthRate = layer.birthRate
170 | try emitter.syncInitialValues(values: config.layer.initialValues)
171 | }
172 | else if !config.layer.enabled {
173 | emitter.birthRate = 0
174 | }
175 | else {
176 | // for updates
177 | emitter.birthRate = layer.birthRate
178 | }
179 |
180 | isEmitting = config.layer.enabled
181 | }
182 |
183 | private func runOnMain(execute: @escaping () -> Void) {
184 | if Thread.isMainThread {
185 | execute()
186 | }
187 | else {
188 | DispatchQueue.main.async(execute: execute)
189 | }
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-caemitterlayer",
3 | "version": "0.4.0",
4 | "description": "An Expo module bridging CAEmitterLayer",
5 | "main": "build/index.js",
6 | "types": "build/index.d.ts",
7 | "scripts": {
8 | "build": "expo-module build",
9 | "clean": "expo-module clean",
10 | "lint": "expo-module lint",
11 | "test": "expo-module test",
12 | "prepare": "expo-module prepare",
13 | "prepublishOnly": "expo-module prepublishOnly",
14 | "expo-module": "expo-module",
15 | "open:ios": "open -a \"Xcode\" example/ios",
16 | "open:android": "open -a \"Android Studio\" example/android"
17 | },
18 | "keywords": [
19 | "react-native",
20 | "expo",
21 | "react-native-caemitterlayer",
22 | "ReactNativeCAEmitterLayer"
23 | ],
24 | "repository": "https://github.com/DigitalZebra/react-native-caemitterlayer",
25 | "bugs": {
26 | "url": "https://github.com/DigitalZebra/react-native-caemitterlayer/issues"
27 | },
28 | "author": "DigitalZebra (https://github.com/DigitalZebra)",
29 | "license": "MIT",
30 | "homepage": "https://github.com/DigitalZebra/react-native-caemitterlayer#readme",
31 | "dependencies": {},
32 | "devDependencies": {
33 | "@types/react": "^18.0.25",
34 | "@types/react-native": "^0.70.6",
35 | "expo-module-scripts": "3.4.1",
36 | "expo-modules-core": "1.11.9"
37 | },
38 | "peerDependencies": {
39 | "expo": "*",
40 | "react": "*",
41 | "react-native": "*"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/EmitterView.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import type { ImageResolvedAssetSource } from 'react-native'
3 | import { Image, Platform, View, ViewProps } from 'react-native'
4 |
5 | import { ReactNativeCAEmitterLayerView } from './ReactNativeCAEmitterLayerView'
6 | import type {
7 | EmitterCellType,
8 | EmitterCellValues,
9 | EmitterLayer,
10 | ImageDataContentsOption,
11 | LegacyEmitterCellContents,
12 | StringContents,
13 | StringContentsOption,
14 | } from './types'
15 |
16 | type NativeCellContents =
17 | | StringContentsOption
18 | | LegacyEmitterCellContents
19 | | ImageDataContentsOption
20 | | {
21 | imageContents: ImageResolvedAssetSource
22 | stringContents?: never
23 | imageData?: never
24 | contents?: never
25 | }
26 |
27 | type NativeCellType = Required & NativeCellContents
28 |
29 | type NativeCellConfiguration = NativeCellType & {
30 | emitterCells: NativeCellType[]
31 | }
32 |
33 | type NativeLayerConfiguration = Required & {
34 | emitterCells: NativeCellConfiguration[]
35 | }
36 |
37 | type NativeEmitterConfiguration = { layer: NativeLayerConfiguration }
38 |
39 | export type EmitterConfigPropType = {
40 | layer: EmitterLayer
41 | }
42 |
43 | export type EmitterViewProps = {
44 | emitterConfig: EmitterConfigPropType
45 | } & ViewProps
46 |
47 | /**
48 | * @deprecated This and associated {@link StringContents} will be removed in a future release. Consider using {@link StringContentsOption} instead.
49 | */
50 | export function stringContents(value: string): StringContents {
51 | return {
52 | type: 'string',
53 | value,
54 | }
55 | }
56 |
57 | function EmitterViewIOS({ emitterConfig, ...rest }: EmitterViewProps) {
58 | const layersWithDefaults: NativeLayerConfiguration = Object.assign(
59 | {},
60 | defaultLayerConfig,
61 | emitterConfig.layer,
62 | {
63 | emitterCells: recursivelyApplyDefaults(
64 | emitterConfig.layer?.emitterCells ?? [],
65 | ),
66 | },
67 | )
68 |
69 | const config: NativeEmitterConfiguration = {
70 | layer: layersWithDefaults,
71 | }
72 |
73 | return (
74 |
75 | )
76 | }
77 |
78 | function EmitterViewDefault({ emitterConfig, ...rest }: EmitterViewProps) {
79 | return
80 | }
81 |
82 | export const EmitterView = Platform.select({
83 | ios: EmitterViewIOS,
84 | default: EmitterViewDefault,
85 | })
86 |
87 | const defaultLayerConfig: Omit, 'emitterCells'> = {
88 | scale: 1,
89 | spin: 1,
90 | velocity: 1,
91 | birthRate: 1,
92 | lifetime: 1,
93 | preservesDepth: false,
94 | renderMode: 'unordered',
95 | emitterPosition: {
96 | x: 0,
97 | y: 0,
98 | },
99 | emitterZPosition: 0,
100 | emitterDepth: 0,
101 | emitterShape: 'point',
102 | emitterMode: 'volume',
103 | emitterSize: {
104 | width: 0,
105 | height: 0,
106 | },
107 | enabled: true,
108 | initialValues: {
109 | seed: undefined,
110 |
111 | beginTime: undefined,
112 | timeOffset: undefined,
113 | repeatCount: undefined,
114 | repeatDuration: undefined,
115 | autoreverses: undefined,
116 | fillMode: undefined,
117 | speed: undefined,
118 | duration: undefined,
119 | },
120 | }
121 |
122 | const defaultCellConfig: Required = {
123 | color: 'white',
124 | isEnabled: true,
125 | contentsScale: 1,
126 | emissionLatitude: 0,
127 | emissionLongitude: 0,
128 | emissionRange: 0,
129 | redRange: 0,
130 | greenRange: 0,
131 | blueRange: 0,
132 | alphaRange: 0,
133 | redSpeed: 0,
134 | greenSpeed: 0,
135 | blueSpeed: 0,
136 | alphaSpeed: 0,
137 | scale: 1,
138 | scaleRange: 0,
139 | scaleSpeed: 0,
140 | spin: 0,
141 | spinRange: 0,
142 | lifetime: 0,
143 | lifetimeRange: 0,
144 | birthRate: 0,
145 | velocity: 0,
146 | velocityRange: 0,
147 | xAcceleration: 0,
148 | yAcceleration: 0,
149 | zAcceleration: 0,
150 |
151 | values: {},
152 |
153 | // CAMediaTiming properties
154 | beginTime: null,
155 | timeOffset: null,
156 | repeatCount: null,
157 | repeatDuration: null,
158 | duration: null,
159 | autoreverses: null,
160 | fillMode: null,
161 | speed: null,
162 | }
163 |
164 | function recursivelyApplyDefaults(
165 | cells: EmitterCellType[],
166 | ): NativeCellConfiguration[] {
167 | const defaultedCells: NativeCellConfiguration[] = []
168 |
169 | cells.forEach(cell => {
170 | const subCells = cell.emitterCells ?? []
171 |
172 | // TODO: might be a cleaner way to do this...?
173 | const cellWithDefaults: NativeCellConfiguration = Object.assign(
174 | {},
175 | { emitterCells: [] },
176 | defaultCellConfig,
177 | cell,
178 | cell.imageContents
179 | ? { imageContents: Image.resolveAssetSource(cell.imageContents) }
180 | : {},
181 | )
182 |
183 | cellWithDefaults.emitterCells = recursivelyApplyDefaults(subCells)
184 |
185 | defaultedCells.push(cellWithDefaults)
186 | })
187 |
188 | return defaultedCells
189 | }
190 |
--------------------------------------------------------------------------------
/src/ReactNativeCAEmitterLayerView.ts:
--------------------------------------------------------------------------------
1 | import { requireNativeViewManager } from 'expo-modules-core'
2 | import { ViewProps } from 'react-native'
3 |
4 | export type ReactNativeCAEmitterLayerViewProps = {
5 | config: string
6 | } & ViewProps
7 |
8 | export const ReactNativeCAEmitterLayerView: React.ComponentType =
9 | requireNativeViewManager('ReactNativeCAEmitterLayer')
10 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './EmitterView'
2 | export * from './types'
3 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { ImageRequireSource } from 'react-native'
2 |
3 | export type RenderMode =
4 | | 'unordered'
5 | | 'oldestFirst'
6 | | 'oldestLast'
7 | | 'backToFront'
8 | | 'additive'
9 |
10 | export type EmitterShape =
11 | | 'point'
12 | | 'line'
13 | | 'rectangle'
14 | | 'cuboid'
15 | | 'sphere'
16 | | 'circle'
17 |
18 | export type EmitterMode = 'points' | 'outline' | 'surface' | 'volume'
19 |
20 | export type EmitterLayer = {
21 | /**
22 | * `true` to emit particles, `false` to not emit particles.
23 | */
24 | enabled?: boolean
25 |
26 | /**
27 | * Values to be set on initial mount and whenever {@link EmitterLayer.enabled} flips from false to true.
28 | */
29 | initialValues?: {
30 | seed?: number
31 |
32 | // CAMediaTiming properties
33 | beginTime?: number | 'currentTime'
34 | timeOffset?: number
35 | repeatCount?: number
36 | repeatDuration?: number
37 | autoreverses?: boolean
38 | fillMode?: FillMode
39 | speed?: number
40 | duration?: number | null
41 | }
42 |
43 | scale?: number
44 | spin?: number
45 | velocity?: number
46 | birthRate?: number
47 | lifetime?: number
48 | preservesDepth?: boolean
49 |
50 | renderMode?: RenderMode
51 | emitterPosition?: { x: number; y: number }
52 | emitterZPosition?: number
53 | emitterDepth?: number
54 |
55 | emitterMode?: EmitterMode
56 | emitterShape?: EmitterShape
57 | emitterSize?: { width: number; height: number }
58 |
59 | /**
60 | * Particles to be emitted by this layer.
61 | */
62 | emitterCells?: EmitterCellType[]
63 | }
64 |
65 | export type FillMode = 'forwards' | 'backwards' | 'both' | 'removed'
66 |
67 | /**
68 | * @deprecated Use {@link StringContentsOption} instead. Will be removed in a future release.
69 | */
70 | export type StringContents = {
71 | type: 'string'
72 | value: string
73 | }
74 |
75 | /**
76 | * @deprecated Use {@link StringContentsOption} instead. Will be removed in a future release.
77 | */
78 | export type ContentsType = StringContents
79 |
80 | export type StringContentsOption = {
81 | stringContents?: {
82 | value: string
83 | }
84 | imageContents?: never
85 | imageData?: never
86 | contents?: never
87 | }
88 |
89 | export type ImageContentsOption = {
90 | imageContents?: ImageRequireSource
91 | stringContents?: never
92 | imageData?: never
93 | contents?: never
94 | }
95 |
96 | export type ImageDataContentsOption = {
97 | imageData?: string
98 | imageContents?: never
99 | stringContents?: never
100 | contents?: never
101 | }
102 |
103 | /**
104 | * @deprecated Use {@link ImageContentsOption.imageContents}, {@link StringContentsOption.stringContents} or {@link ImageDataContentsOption.imageData} instead. This type will be removed in a future release.
105 | */
106 | export type LegacyEmitterCellContents = {
107 | /**
108 | * @deprecated Use {@link EmitterCellType.stringContents}, {@link EmitterCellType.imageContents} or {@link EmitterCellType.imageData} instead. Will be removed in a future release.
109 | */
110 | contents?: ContentsType | null
111 | imageContents?: never
112 | stringContents?: never
113 | imageData?: never
114 | }
115 |
116 | export type EmitterCellContents =
117 | | StringContentsOption
118 | | ImageContentsOption
119 | | ImageDataContentsOption
120 | | LegacyEmitterCellContents
121 |
122 | export type EmitterCellValues = {
123 | color?: string
124 | contentsScale?: number
125 |
126 | isEnabled?: boolean
127 |
128 | emissionLatitude?: number
129 | emissionLongitude?: number
130 | emissionRange?: number
131 |
132 | redRange?: number
133 | greenRange?: number
134 | blueRange?: number
135 | alphaRange?: number
136 |
137 | redSpeed?: number
138 | greenSpeed?: number
139 | blueSpeed?: number
140 | alphaSpeed?: number
141 |
142 | scale?: number
143 | scaleRange?: number
144 | scaleSpeed?: number
145 |
146 | spin?: number
147 | spinRange?: number
148 |
149 | lifetime?: number
150 | lifetimeRange?: number
151 |
152 | birthRate?: number
153 |
154 | velocity?: number
155 | velocityRange?: number
156 |
157 | xAcceleration?: number
158 | yAcceleration?: number
159 | zAcceleration?: number
160 |
161 | /**
162 | * Maps to NSKeyValueCoding's `setValue` function:
163 | * https://developer.apple.com/documentation/objectivec/nsobject/1415969-setvalue
164 | */
165 | values?: { [key: string]: number | string }
166 |
167 | // CAMediaTiming properties
168 | beginTime?: number | null
169 | timeOffset?: number | null
170 | repeatCount?: number | null
171 | repeatDuration?: number | null
172 | autoreverses?: boolean | null
173 | fillMode?: FillMode | null
174 | speed?: number | null
175 | duration?: number | null
176 | }
177 |
178 | export type EmitterCellType = {
179 | /**
180 | * Sub particles to be emitted by this cell.
181 | */
182 | emitterCells?: EmitterCellType[]
183 | } & EmitterCellContents &
184 | EmitterCellValues
185 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | // @generated by expo-module-scripts
2 | {
3 | "extends": "expo-module-scripts/tsconfig.base",
4 | "compilerOptions": {
5 | "outDir": "./build"
6 | },
7 | "include": ["./src"],
8 | "exclude": ["**/__mocks__/*", "**/__tests__/*"]
9 | }
10 |
--------------------------------------------------------------------------------