react-native-blur-vibe 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -33,7 +33,7 @@ class BlurVibeView(context: Context) : ReactViewGroup(context) {
|
|
|
33
33
|
|
|
34
34
|
init {
|
|
35
35
|
setWillNotDraw(false)
|
|
36
|
-
|
|
36
|
+
// DO NOT call setBackgroundColor — see BlurVibeViewApi31 for explanation.
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
@@ -137,8 +137,10 @@ class BlurVibeView(context: Context) : ReactViewGroup(context) {
|
|
|
137
137
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
138
138
|
|
|
139
139
|
private fun mapBlurAmount(amount: Float): Float {
|
|
140
|
+
// Linear 0→1, 100→25 (RenderScript max kernel is 25)
|
|
141
|
+
// With 3 blur rounds this gives equivalent spread to Api31's 120px single-pass
|
|
140
142
|
val t = amount.coerceIn(0f, 100f) / 100f
|
|
141
|
-
return
|
|
143
|
+
return (1f + t * 24f) // 1–25 linear, rounds=3 gives wide spread
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
private fun findBlurRoot(): ViewGroup? {
|
|
@@ -117,7 +117,12 @@ class BlurVibeViewApi31(context: Context) : ReactViewGroup(context) {
|
|
|
117
117
|
|
|
118
118
|
init {
|
|
119
119
|
setWillNotDraw(false)
|
|
120
|
-
|
|
120
|
+
// DO NOT call setBackgroundColor here.
|
|
121
|
+
// ReactViewGroup manages its own ReactViewBackgroundDrawable which handles
|
|
122
|
+
// all RN style props: borderRadius, borderColor, borderWidth, opacity,
|
|
123
|
+
// backgroundColor, shadow, elevation etc.
|
|
124
|
+
// Calling super.setBackgroundColor() replaces that drawable with a plain
|
|
125
|
+
// ColorDrawable — destroying all style prop handling.
|
|
121
126
|
}
|
|
122
127
|
|
|
123
128
|
// ── Lifecycle ──────────────────────────────────────────────────────────────
|
|
@@ -219,18 +224,24 @@ class BlurVibeViewApi31(context: Context) : ReactViewGroup(context) {
|
|
|
219
224
|
nodeCanvas.drawBitmap(bitmap, 0f, 0f, null)
|
|
220
225
|
renderNode.endRecording()
|
|
221
226
|
|
|
222
|
-
// ④ Apply GPU blur + tint as
|
|
223
|
-
|
|
224
|
-
|
|
227
|
+
// ④ Apply GPU blur + tint as chained RenderEffects
|
|
228
|
+
// Double-pass blur: two Gaussian passes = wider spread kernel
|
|
229
|
+
// Equivalent to sqrt(2) wider sigma — gives frosted-glass light diffusion
|
|
230
|
+
// CLAMP tile mode: no edge reflection artifacts
|
|
231
|
+
val radius = blurRadiusFromAmount(blurAmount)
|
|
232
|
+
val pass1 = RenderEffect.createBlurEffect(radius, radius, Shader.TileMode.CLAMP)
|
|
233
|
+
val pass2 = RenderEffect.createBlurEffect(radius * 0.5f, radius * 0.5f, Shader.TileMode.CLAMP)
|
|
234
|
+
val doubleBlur = RenderEffect.createChainEffect(pass2, pass1) // pass1 first, then pass2
|
|
235
|
+
|
|
225
236
|
renderNode.setRenderEffect(
|
|
226
237
|
if (Color.alpha(overlayColor) > 0) {
|
|
227
238
|
RenderEffect.createChainEffect(
|
|
228
239
|
RenderEffect.createColorFilterEffect(
|
|
229
240
|
BlendModeColorFilter(overlayColor, BlendMode.SRC_ATOP)
|
|
230
241
|
),
|
|
231
|
-
|
|
242
|
+
doubleBlur
|
|
232
243
|
)
|
|
233
|
-
} else
|
|
244
|
+
} else doubleBlur
|
|
234
245
|
)
|
|
235
246
|
|
|
236
247
|
invalidate()
|
|
@@ -394,8 +405,16 @@ class BlurVibeViewApi31(context: Context) : ReactViewGroup(context) {
|
|
|
394
405
|
}
|
|
395
406
|
}
|
|
396
407
|
|
|
397
|
-
private fun blurRadiusFromAmount(amount: Float): Float
|
|
398
|
-
|
|
408
|
+
private fun blurRadiusFromAmount(amount: Float): Float {
|
|
409
|
+
// Linear mapping: 0→1px, 10→13px, 25→31px, 50→61px, 75→91px, 100→120px
|
|
410
|
+
// These values match CSS backdrop-filter feel:
|
|
411
|
+
// blurAmount=10 ≈ backdrop-blur-sm (4px CSS = ~13px GPU after downsample)
|
|
412
|
+
// blurAmount=25 ≈ backdrop-blur-md (12px CSS ≈ 31px GPU)
|
|
413
|
+
// blurAmount=50 ≈ backdrop-blur-xl (24px CSS ≈ 61px GPU)
|
|
414
|
+
// blurAmount=100 ≈ backdrop-blur-3xl (64px CSS = fully frosted glass)
|
|
415
|
+
val t = amount.coerceIn(0f, 100f) / 100f
|
|
416
|
+
return (1f + t * 119f) // 1–120 linear
|
|
417
|
+
}
|
|
399
418
|
|
|
400
419
|
private fun findBlurRoot(): ViewGroup? {
|
|
401
420
|
var p = parent
|
|
@@ -33,9 +33,17 @@ internal class LegacyBlurController(
|
|
|
33
33
|
) {
|
|
34
34
|
|
|
35
35
|
companion object {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
// DOWNSAMPLE_FACTOR = 2: capture at 1/4 pixels (less than before).
|
|
37
|
+
// Less downsampling = higher quality capture = crisper blur result.
|
|
38
|
+
// The blur hides pixel detail so 1/4 is the sweet spot.
|
|
39
|
+
private const val DOWNSAMPLE_FACTOR = 2f
|
|
40
|
+
|
|
41
|
+
// Default radius when blurAmount maps here.
|
|
42
|
+
// The actual radius per frame comes from view.blurRadius set by setBlurAmount().
|
|
43
|
+
private const val BLUR_RADIUS = 25f // max RenderScript kernel
|
|
44
|
+
|
|
45
|
+
// 3 rounds: more passes = wider spread = true frosted glass feel
|
|
46
|
+
private const val BLUR_ROUNDS = 3
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
// ── Bitmap pool ────────────────────────────────────────────────────────────
|
package/package.json
CHANGED