expo-cloudy
v0.1.1
Published
Blur and progressive (gradient) blur for Expo and React Native — a native port of skydoves/Cloudy
Maintainers
Readme
expo-cloudy
Blur and progressive (gradient) blur for Expo and React Native — a native port of skydoves/Cloudy.
Wrap any subtree in <CloudyView> to blur it. Use the progressive prop to fade the blur across the surface — ideal for scroll-edge fades or vignettes.
Features
- ☁️ Content blur: blurs the children you wrap, not just the backdrop.
- 🌈 Progressive (gradient) blur:
topToBottom,bottomToTop,leftToRight,rightToLeft, andedges(vignette). - ⚡ Native performance: GPU
RenderEffect+ AGSL runtime shader on Android, liveUIVisualEffectViewon iOS, CSS on web. - 🎛️ Configurable ramp: control where the blur starts and reaches full strength.
Installation
npx expo install expo-cloudyThen rebuild your dev client / native project (npx expo prebuild + run), since this ships native code.
Usage
Uniform blur
import { CloudyView } from 'expo-cloudy';
<CloudyView radius={25} style={{ borderRadius: 16 }}>
<Image source={...} style={{ width: 300, height: 200 }} />
</CloudyView>Progressive (gradient) blur
import { CloudyView, CloudyProgressive } from 'expo-cloudy';
// Blur is strongest at the top and fades to clear toward the bottom
<CloudyView radius={25} progressive={CloudyProgressive.TopToBottom()}>
{content}
</CloudyView>
// Vignette: clear center, blurred edges
<CloudyView radius={30} progressive={CloudyProgressive.Edges(0.4)}>
{content}
</CloudyView>
// Or pass a plain direction string
<CloudyView radius={20} progressive="bottomToTop">
{content}
</CloudyView>You can also fine-tune the ramp with start / end (normalized 0..1 fractions along the direction axis):
<CloudyView
radius={25}
progressive={CloudyProgressive.TopToBottom(0.2, 0.8)}
>
{content}
</CloudyView>Props
| Prop | Type | Default | Description |
| :------------ | :----------------------------------------------- | :------- | :----------------------------------------------------------------- |
| radius | number | 20 | Blur radius in pixels. Must be non-negative. |
| enabled | boolean | true | Toggle the effect on/off without unmounting children. |
| progressive | CloudyProgressiveType \| CloudyProgressiveConfig | 'none' | Direction/config for the gradient blur. See below. |
| style | ViewStyle | – | Standard React Native view style (size, border radius, etc.). |
CloudyProgressive helpers
| Helper | Effect |
| :---------------------------------- | :-------------------------------------------------- |
| CloudyProgressive.None() | Uniform blur (default). |
| CloudyProgressive.TopToBottom(start?, end?) | Blur strongest at top, fades toward bottom. |
| CloudyProgressive.BottomToTop(start?, end?) | Blur strongest at bottom, fades toward top. |
| CloudyProgressive.LeftToRight(start?, end?) | Blur strongest at left, fades toward right. |
| CloudyProgressive.RightToLeft(start?, end?) | Blur strongest at right, fades toward left. |
| CloudyProgressive.Edges(fadeDistance?) | Blur at edges, clear in the center (vignette). |
Platform support
| Platform | Blur backend | Progressive |
| :------- | :----------- | :---------- |
| Android 33+ | RenderEffect + AGSL RuntimeShader (GPU) | ✅ true per-pixel gradient blur |
| Android 31–32 | RenderEffect.createBlurEffect (GPU) | ⚠️ falls back to uniform blur |
| Android < 31 | – | ⚠️ children render unaltered (no GPU blur API) |
| iOS | Live UIVisualEffectView masked by a CAGradientLayer | ✅ (live; updates as content scrolls/animates) |
| Web | CSS filter: blur() + mask-image gradient | ✅ |
iOS note: the blur is a live
UIVisualEffectViewlayered over the children, so it tracks scrolling and animation in real time. UIKit exposes blur as material styles rather than an arbitrary pixel radius, soradiusis mapped to a blur-intensity bucket rather than an exact pixel value.
License
MIT
