ProgressiveBlurView
ProgressiveBlurView renders a variable/gradient blur that transitions smoothly instead of applying a uniform blur intensity. It works on iOS, Android, and Web, though the underlying implementations differ:
- iOS: private Core Animation filters for true variable blur.
- Android: wraps QmBlurView’s
BlurViewwith custom gradient masking. - Web: stacks several CSS
backdrop-filterlayers with gradient masks, halving the radius per layer — a genuine blur-radius ramp (fromblurAmountpx down to sharp), not a single blur fading in opacity.
On web, blurAmount is the maximum radius in px (matching native), and browsers without backdrop-filter fall back to the directional tint gradient alone. Since 6.0, startOffset means the same thing on every platform — see Platform differences for how the fade is constructed per backend.
Basic usage
import { ProgressiveBlurView } from '@sbaiahmed1/react-native-blur';
<ProgressiveBlurView
blurType="light"
blurAmount={30}
direction="blurredTopClearBottom"
startOffset={0}
style={{ height: 200 }}
>
<Text>Progressive blur from top (blurred) to bottom (clear)</Text>
</ProgressiveBlurView>
Center blur
direction="blurredCenterClearTopAndBottom" creates a blur body that peaks in the center and fades to clear at both edges.
<ProgressiveBlurView
blurType="regular"
blurAmount={35}
direction="blurredCenterClearTopAndBottom"
startOffset={0} // keep 0 for the longest blur body; raise toward 0.3 to shorten it
style={{ height: 220, borderRadius: 16 }}
>
<Text>Clear at top</Text>
<Text>Blurred at center</Text>
<Text>Clear at bottom</Text>
</ProgressiveBlurView>
Locked content / paywall pattern
<View style={{ position: 'relative' }}>
<Text>Long content here...</Text>
<ProgressiveBlurView
blurType="light"
blurAmount={20}
direction="blurredBottomClearTop"
startOffset={0.5} // bottom half fully blurred, fade over the top half
style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 200 }}
>
<Text>🔒 Unlock to read more</Text>
<Button title="Purchase" />
</ProgressiveBlurView>
</View>
Platform differences
The three backends aim for the same look but get there differently:
- Blur ramp. iOS and Web ramp the blur radius from
blurAmountdown to 0 across the gradient. Android renders one fixed-radius blur and ramps its opacity with a perceptually tuned eased mask that approximates the same look. The iOS and Android fade curves are shaped in opposite directions (ease-in on the radius, ease-out on the opacity) so that content legibility fades comparably across platforms. startOffsetmeans the same thing on every platform: for the edge directions it grows a fully-blurred plateau from the blurred edge —0.4means the nearest 40% of the view is uniformly blurred and the fade spans the remaining 60%. For the center direction it insets the fade start from the edges (clamped to 0.3), shortening the blur body —0gives the longest body.
Changed in 6.0: before 6.0, iOS interpreted startOffset inversely for the edge directions — it grew the fully-clear region from the clear edge — and Web’s center direction grew the blurred band instead of shrinking it. If you tuned startOffset per platform (e.g. via Platform.select), collapse it to a single value and re-check the iOS fade geometry.
Android backend notes
On Android, the blur works by capturing the surrounding view tree — scoped to the nearest react-native-screens Screen, falling back to the React root — into a downsampled bitmap and blurring it. Two practical consequences:
- Capture and blur both cost work. Captures use a downsampled bitmap, and each
blurRoundsiteration adds a native blur pass. Lowering it trades quality for less blur work; measure on target devices to determine whether capture or blur is the bottleneck. - Other foreground content can be captured too. Android captures the surrounding view tree rather than only pixels behind the effect. This component’s children live inside the native view and are excluded with its subtree; they render sharp above the masked blur. Other foreground siblings inside the capture root can still produce a blurred halo. If necessary, move those siblings outside the capture root (e.g. a portal above the navigator).
Direction values
| Value | Description |
|---|---|
| blurredTopClearBottom | Blurred at the top, fading to clear at the bottom (default). |
| blurredBottomClearTop | Blurred at the bottom, fading to clear at the top. |
| blurredCenterClearTopAndBottom | Blur peaks in the center and fades to clear at both edges. |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| blurType | BlurType | 'regular' | The type of blur effect to apply. |
| blurAmount | number | 20 | Maximum blur radius at the most-blurred point. |
| blurRounds | number | 5 | AndroidNumber of blur interactions for a smoother effect (1-15). |
| direction | 'blurredTopClearBottom' | 'blurredBottomClearTop' | 'blurredCenterClearTopAndBottom' | 'blurredTopClearBottom' | Direction of the blur gradient. |
| startOffset | number | 0.0 | Plateau size (0.0-1.0): grows the fully-blurred zone from the blurred edge, so for edge directions 0 gives the longest fade. For the center direction the fade occupies fixed edge bands and startOffset insets them (max 0.3), so 0 gives the longest center blur body. Same meaning on all platforms. |
| reducedTransparencyFallbackColor | string | '#FFFFFF' | iOSFallback color when reduced transparency is enabled. |
| overlayColor | ColorValue | undefined | An overlay color to apply on top of the blur effect. |
| style | StyleProp<ViewStyle> | undefined | Style object for the blur view. |
| children | React.ReactNode | undefined | Child components to render inside the blur view. |