@kesbyte/capacitor-animated-splashscreen
v1.0.0
Published
Capacitor plugin for animated splash screens with Lottie animations and sound support
Maintainers
Readme
@kesbyte/capacitor-animated-splashscreen
A Capacitor plugin for animated splash screens with Lottie animations and sound support. Seamlessly transitions from the native Launch Screen to a Lottie-powered animation overlay with full control over timing, looping, and audio.
Features
- Lottie JSON animation support on iOS and Android
- Seamless transition from native Launch Screen to animation overlay
- Loop or play-once animation modes
- Duration override for Lottie animations
- Static image fallback when Lottie file is unavailable
- Sound playback with delay, volume, and mute switch support
- Fade-out effect with configurable duration
- Event-driven API (animationComplete, dismissed, soundComplete)
- Android 12+ SplashScreen API integration
- iOS Safe Area and Dynamic Island support
- Graceful fallback chain: Lottie -> staticImage -> backgroundColor
- Memory-optimized: full resource cleanup after dismiss
Installation
pnpm add @kesbyte/capacitor-animated-splashscreen
npx cap syncQuick Start
Add the plugin configuration to your capacitor.config.ts:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'My App',
webDir: 'www',
plugins: {
AnimatedSplash: {
lottieFile: 'splash_animation.json',
backgroundColor: '#1A1A2E',
loopUntilDismiss: true,
fadeOutDuration: 500,
},
},
};
export default config;Then hide the splash when your app is ready:
import { AnimatedSplash } from '@kesbyte/capacitor-animated-splashscreen';
// Hide splash after initialization
await AnimatedSplash.hide({ fadeOutDuration: 500 });API Reference
Methods
hide(options?: HideOptions): Promise<void>
Hides the splash screen. Fires the dismissed event after completion. Safe to call multiple times (no-op if already hidden).
| Parameter | Type | Description |
|---|---|---|
| options.fadeOutDuration | number | Fade-out duration in ms (overrides config, clamped to 0-5000) |
await AnimatedSplash.hide({ fadeOutDuration: 300 });show(options?: ShowOptions): Promise<void>
Shows the splash screen again. Useful for app-resume scenarios or scene changes. If the splash is currently visible, it is dismissed first before re-showing.
| Parameter | Type | Description |
|---|---|---|
| options.lottieFile | string | Alternative Lottie file for this call |
| options.soundFile | string | Alternative sound file for this call |
await AnimatedSplash.show({
lottieFile: 'resume_animation.json',
soundFile: 'resume_sound.m4a',
});isVisible(): Promise<VisibilityResult>
Returns whether the splash screen is currently visible. Thread-safe on all platforms.
const { visible } = await AnimatedSplash.isVisible();
console.log('Splash visible:', visible);setSound(options: SoundOptions): Promise<void>
Changes sound settings at runtime. On web, this tracks state for API consistency but does not produce audio.
| Parameter | Type | Description |
|---|---|---|
| options.enabled | boolean | Enable or disable sound |
| options.volume | number | Volume level (0.0 to 1.0, values outside range are clamped) |
// Mute the splash sound
await AnimatedSplash.setSound({ enabled: false });
// Set volume to 50%
await AnimatedSplash.setSound({ volume: 0.5 });
// Change both at once
await AnimatedSplash.setSound({ enabled: true, volume: 0.8 });Events
animationComplete
Fires when the animation completes one full loop. In loop mode (loopUntilDismiss: true), this event fires after each loop iteration. In single play mode, it fires once when the animation ends.
const handle = await AnimatedSplash.addListener('animationComplete', () => {
console.log('Animation completed one loop');
});
// Remove this specific listener later
await handle.remove();dismissed
Fires when the splash screen is fully hidden (after the fade-out animation completes). Does not fire if the splash was already hidden.
await AnimatedSplash.addListener('dismissed', () => {
console.log('Splash dismissed — app UI is now visible');
// Good place to start loading content
});soundComplete
Fires when sound playback finishes naturally. Does not fire if sound was stopped manually via hide() or setSound({ enabled: false }).
await AnimatedSplash.addListener('soundComplete', () => {
console.log('Sound playback finished');
});removeAllListeners(): Promise<void>
Removes all event listeners for this plugin.
await AnimatedSplash.removeAllListeners();Configuration Options
All options are set in capacitor.config.ts under plugins.AnimatedSplash.
Animation Options
| Option | Type | Default | Description |
|---|---|---|---|
| lottieFile | string | (required) | Path to the Lottie JSON file in native assets |
| staticImage | string | undefined | PNG fallback image when Lottie file is unavailable |
| backgroundColor | string | "#FFFFFF" | Background color as hex value (must match Launch Screen) |
| autoHide | boolean | false | Auto-hide splash after one complete animation loop |
| duration | number | undefined | Animation duration in ms (overrides Lottie internal duration). Values below 100ms or above 30000ms are ignored |
| loopUntilDismiss | boolean | true | Loop animation until hide() is called. When false, animation plays once and stops on the last frame |
| fadeOutDuration | number | 300 | Duration of the fade-out effect in ms (clamped to 0-5000) |
Sound Options
| Option | Type | Default | Description |
|---|---|---|---|
| soundFile | string | undefined | Path to audio file in native assets. Supported formats: .m4a, .aac, .wav, .mp3 |
| soundEnabled | boolean | true (when soundFile set) | Enable or disable sound playback |
| soundDelay | number | 0 | Delay between animation start and sound start in ms (clamped to >= 0) |
| respectMuteSwitch | boolean | true | Respect device mute switch (iOS) / silent mode (Android). When true, uses ambient audio category; when false, uses playback category |
| soundVolume | number | 1.0 | Sound volume (clamped to 0.0-1.0) |
Full Configuration Example
const config: CapacitorConfig = {
plugins: {
AnimatedSplash: {
// Animation
lottieFile: 'splash_animation.json',
staticImage: 'splash_fallback.png',
backgroundColor: '#1A1A2E',
autoHide: false,
duration: 3000,
loopUntilDismiss: true,
fadeOutDuration: 500,
// Sound
soundFile: 'splash_sound.m4a',
soundEnabled: true,
soundDelay: 200,
respectMuteSwitch: true,
soundVolume: 0.8,
},
},
};Platform Setup
iOS
- Place your Lottie JSON file in the Xcode project (add to the app target).
- If using a static fallback image, add the PNG to the asset catalog.
- If using sound, add the audio file to the app bundle (ensure it is included in "Copy Bundle Resources").
- Ensure the Launch Screen background color matches the
backgroundColorconfig value for a seamless transition.
Dependencies: The plugin uses lottie-ios (added via Swift Package Manager through the Capacitor plugin).
Sound Behavior: By default (respectMuteSwitch: true), the plugin uses AVAudioSession .ambient category, which respects the hardware mute switch. Set respectMuteSwitch: false to use .playback category and ignore the mute switch.
Android
- Place your Lottie JSON file in
android/app/src/main/assets/. - If using a static fallback image, place the PNG in
android/app/src/main/assets/. - If using sound, place the audio file in
android/app/src/main/assets/. - For Android 12+ (API 31+), the plugin integrates with the system SplashScreen API via
installSplashScreen()for a seamless transition. - For API 24-30, the plugin overlay is shown directly on top of the activity content.
Dependencies: The plugin uses lottie-android and the AndroidX SplashScreen compat library.
Sound Behavior: The plugin uses SoundPool for audio files under 1MB and MediaPlayer for larger files. When respectMuteSwitch is true, sound is suppressed in silent/vibrate mode.
Compatibility
| Component | Minimum | Recommended | |---|---|---| | Capacitor | 8.0.0 | 8.x (latest) | | iOS | 15.0 | 16.0+ | | Android API Level | 24 (Android 7.0) | 28+ (Android 9.0+) | | lottie-ios | 4.0.0 | 4.x (latest) | | lottie-android | 6.0.0 | 6.x (latest) | | TypeScript | 5.0.0 | 5.7+ | | Node.js | 22.0.0 | 22.x LTS |
How It Works
- App launches -- the OS displays the native Launch Screen (static).
- Plugin loads -- the plugin creates a full-screen overlay with the same background color as the Launch Screen, ensuring a seamless visual transition.
- Animation starts -- the Lottie animation plays over the overlay. If the Lottie file is unavailable and a
staticImageis configured, the static image is displayed instead. If neither is available, only the background color is shown. - Sound plays -- if
soundFileis configured, audio playback starts after the configuredsoundDelay. Missing sound files are gracefully handled (warning logged, animation continues). - App calls
hide()-- the overlay fades out with the configuredfadeOutDuration, revealing the app UI underneath. All resources (animation, sound, views) are released for memory optimization. - Events fire --
animationCompletefires after each loop,dismissedfires after the fade-out completes, andsoundCompletefires when audio finishes naturally.
Troubleshooting
Flicker between Launch Screen and animation
Make sure the backgroundColor in your plugin config exactly matches the background color of your native Launch Screen storyboard (iOS) or splash theme (Android). Even a slight difference will cause a visible flash.
Sound not playing
- Check file path: Ensure the sound file is in the correct assets folder (
android/app/src/main/assets/for Android, added to app target for iOS). - Check format: Supported formats are
.m4a,.aac,.wav, and.mp3. - Check mute switch: If
respectMuteSwitchistrue(default), sound will not play when the device is muted. - Check logs: The plugin logs warnings when sound files cannot be loaded. Look for
[AnimatedSplash] Warning:in the console.
Animation not appearing
- Check file path: Ensure the Lottie JSON file is in the correct location. On Android, it must be in
assets/. On iOS, it must be added to the app target. - Check fallback: If the Lottie file fails to load, the plugin falls back to
staticImage(if configured), then to showing only thebackgroundColor. - Check logs: Look for
[AnimatedSplash] Warning:messages about missing files.
Memory usage is high
The plugin automatically cleans up all resources after hide() is called:
- Lottie animation views are removed from the view hierarchy and deallocated
- Sound players are stopped and released
- Image bitmaps are recycled (Android)
If you notice high memory usage, ensure you are calling hide() when the splash is no longer needed.
Android 12+ system splash conflicts
The plugin automatically integrates with the Android 12+ SplashScreen API. If you see theme-related errors, ensure your values-v31/themes.xml includes the Theme.SplashScreen parent theme. The plugin handles installSplashScreen() failures gracefully.
iPad Split View / Slide Over
The plugin handles iPad multitasking modes. The splash overlay adjusts to size changes via Auto Layout constraints and viewWillTransition(to:with:).
Foldable Android devices
The splash overlay uses MATCH_PARENT layout params, which automatically adapts to fold/unfold configuration changes.
Contributing
Contributions are welcome! Please read the Contributing Guide for details on the development setup, branch strategy, commit conventions, and pull request process.
License
MIT -- see the LICENSE file for details. This plugin has no copyleft dependencies and is free to use in any project, commercial or otherwise.
Third-Party Licenses
This plugin bundles or depends on the following open-source components:
| Component | License | |---|---| | lottie-ios | Apache-2.0 | | lottie-android | Apache-2.0 | | AndroidX (appcompat, core-ktx, core-splashscreen) | Apache-2.0 | | Capacitor | MIT |
