About this animation
A glass onboarding bubble rises, contracts into an interactive fountain button, and releases a field of luminous marbles.
How it works
- The component measures its own container and derives every position and size from its width and height.
- One entry progress value drives the opening glass bubble, the button morph, the headline, and the staggered actions.
- A UI-thread frame callback updates compact shared arrays for position, velocity, size, lifetime, and particle state without React renders per frame.
- Up to 70 bubbles are drawn in one Skia canvas with layered radial gradients, specular highlights, inner shading, and occasional marble rings.
- A pan applies a soft radial force to nearby bubbles, a tap splits a bubble into six short-lived droplets, and holding the glass button accelerates the fountain.
Why this one
The transformation is only the opening moment. The resulting scene stays tactile: bubbles yield to a finger, individual marbles burst into droplets, and the source visibly strains when held. Reduced motion replaces the fountain with a composed field of 18 still bubbles instead of merely slowing the same effect.
Install
npx expo install @shopify/react-native-skia expo-blur expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-workletsSkia web support is configured automatically by Expo. The first CanvasKit load can take longer than native startup, so the component keeps its opening copy and glass surface in regular React Native views.
Usage
import GlassBubbleWelcome from './GlassBubbleWelcome';
export function WelcomeScreen() {
return (
<GlassBubbleWelcome
primaryAction={{ label: 'Continue with email', onPress: signInWithEmail }}
secondaryAction={{ label: 'Continue with passkey', onPress: signInWithPasskey }}
/>
);
}Customize the personality and control the sequence:
import { useRef } from 'react';
import GlassBubbleWelcome, { type GlassBubbleWelcomeRef } from './GlassBubbleWelcome';
export function StudioWelcome() {
const welcomeRef = useRef<GlassBubbleWelcomeRef>(null);
return (
<GlassBubbleWelcome
ref={welcomeRef}
title="Meet your studio."
subtitle={'Shape an idea.\nShip something real.'}
rate={18}
maxBubbles={60}
palette={[
['#3478FF', '#32D9F4', '#C7F8FF'],
['#7557FF', '#E05BFF', '#F1C7FF'],
]}
onEnter={() => trackWelcomeComplete()}
/>
);
}The forwarded ref exposes enter(), reset(), and burst().
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | 'Welcome.' | Main headline after the morph. |
subtitle | string | 'Your personal\ncreative studio.' | Supporting message. |
introText | string | 'A new era of\napps is here.' | Opening message. |
swipeHint | string | 'Swipe up to enter' | Hint inside the opening bubble. |
primaryAction | { label: string; onPress: () => void } | Email action | Light action. |
secondaryAction | { label: string; onPress: () => void } | Passkey action | Dark action. |
palette | [string, string, string][] | Six curated color sets | Bubble gradient colors. |
rate | number | 14 | Bubbles emitted per second. |
maxBubbles | number | 70 | Live simulation slots, clamped from 18 to 70. |
autoplay | boolean | false | Enters automatically after 600 ms. |
fontFamily | string | System font | Supporting copy and controls. |
titleFontFamily | string | System font | Intro and main headline. |
onEnter | () => void | — | Called when the entry morph finishes. |
style | StyleProp<ViewStyle> | — | Outer-container style. |
testID | string | — | Test identifier. |
Compatibility
- Expo SDK 57
- React Native 0.86
- Reanimated 4.5, Worklets 0.10, and Skia 2.6
- iOS: supported, not yet verified on a device
- Android: supported, not yet verified on a device
- Web: supported, not yet verified
- Works in Expo Go because its native dependencies are included in Expo SDK 57
Accessibility
The fountain and both actions expose button roles and labels, and tapping the opening scene provides an alternative to swiping. With reduced motion enabled, the morph becomes a short fade, continuous emission and parallax stop, and 18 static bubbles appear as a decorative composition.




