react-native-parity-blur 0.1.0
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.
- package/LICENSE +20 -0
- package/ParityBlur.podspec +20 -0
- package/README.md +198 -0
- package/android/build.gradle +57 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/parityblur/AndroidBlurCalibration.kt +82 -0
- package/android/src/main/java/com/parityblur/BlurEngine.kt +132 -0
- package/android/src/main/java/com/parityblur/ParityBlurDebug.kt +24 -0
- package/android/src/main/java/com/parityblur/ParityBlurPackage.kt +17 -0
- package/android/src/main/java/com/parityblur/ParityBlurView.kt +542 -0
- package/android/src/main/java/com/parityblur/ParityBlurViewManager.kt +161 -0
- package/android/src/main/java/com/parityblur/PipelineMath.kt +202 -0
- package/android/src/main/java/com/parityblur/PixelCopySnapshotProvider.kt +108 -0
- package/android/src/main/java/com/parityblur/SoftwareSnapshotProvider.kt +173 -0
- package/android/src/main/java/com/parityblur/WindowBlurContext.kt +116 -0
- package/android/src/test/java/com/parityblur/MiniJson.kt +179 -0
- package/android/src/test/java/com/parityblur/PipelineFixturesTest.kt +222 -0
- package/ios/BlurEngine.swift +106 -0
- package/ios/ColorPipeline.swift +72 -0
- package/ios/MetalPresentationSurface.swift +51 -0
- package/ios/ParityBlurCoreView.swift +382 -0
- package/ios/ParityBlurDebug.swift +18 -0
- package/ios/ParityBlurView.h +14 -0
- package/ios/ParityBlurView.mm +135 -0
- package/ios/PipelineMath.swift +177 -0
- package/ios/SnapshotProvider.swift +128 -0
- package/ios/WindowBlurContext.swift +111 -0
- package/lib/module/BlurView.js +124 -0
- package/lib/module/BlurView.js.map +1 -0
- package/lib/module/ParityBlurViewNativeComponent.ts +82 -0
- package/lib/module/defaults.js +13 -0
- package/lib/module/defaults.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/pipeline/androidCalibration.js +55 -0
- package/lib/module/pipeline/androidCalibration.js.map +1 -0
- package/lib/module/pipeline/captureRect.js +151 -0
- package/lib/module/pipeline/captureRect.js.map +1 -0
- package/lib/module/pipeline/color.js +82 -0
- package/lib/module/pipeline/color.js.map +1 -0
- package/lib/module/pipeline/constants.js +65 -0
- package/lib/module/pipeline/constants.js.map +1 -0
- package/lib/module/pipeline/downsample.js +61 -0
- package/lib/module/pipeline/downsample.js.map +1 -0
- package/lib/module/pipeline/index.js +23 -0
- package/lib/module/pipeline/index.js.map +1 -0
- package/lib/module/pipeline/overlay.js +56 -0
- package/lib/module/pipeline/overlay.js.map +1 -0
- package/lib/module/pipeline/saturation.js +52 -0
- package/lib/module/pipeline/saturation.js.map +1 -0
- package/lib/module/pipeline/types.js +23 -0
- package/lib/module/pipeline/types.js.map +1 -0
- package/lib/module/pipeline/units.js +33 -0
- package/lib/module/pipeline/units.js.map +1 -0
- package/lib/module/presets.js +96 -0
- package/lib/module/presets.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/BlurView.d.ts +16 -0
- package/lib/typescript/src/BlurView.d.ts.map +1 -0
- package/lib/typescript/src/ParityBlurViewNativeComponent.d.ts +63 -0
- package/lib/typescript/src/ParityBlurViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/defaults.d.ts +12 -0
- package/lib/typescript/src/defaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/androidCalibration.d.ts +42 -0
- package/lib/typescript/src/pipeline/androidCalibration.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/captureRect.d.ts +84 -0
- package/lib/typescript/src/pipeline/captureRect.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/color.d.ts +19 -0
- package/lib/typescript/src/pipeline/color.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/constants.d.ts +52 -0
- package/lib/typescript/src/pipeline/constants.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/downsample.d.ts +31 -0
- package/lib/typescript/src/pipeline/downsample.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/index.d.ts +20 -0
- package/lib/typescript/src/pipeline/index.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/overlay.d.ts +31 -0
- package/lib/typescript/src/pipeline/overlay.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/saturation.d.ts +38 -0
- package/lib/typescript/src/pipeline/saturation.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/types.d.ts +32 -0
- package/lib/typescript/src/pipeline/types.d.ts.map +1 -0
- package/lib/typescript/src/pipeline/units.d.ts +23 -0
- package/lib/typescript/src/pipeline/units.d.ts.map +1 -0
- package/lib/typescript/src/presets.d.ts +57 -0
- package/lib/typescript/src/presets.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +116 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +167 -0
- package/src/BlurView.tsx +195 -0
- package/src/ParityBlurViewNativeComponent.ts +82 -0
- package/src/defaults.ts +20 -0
- package/src/index.ts +10 -0
- package/src/pipeline/androidCalibration.ts +64 -0
- package/src/pipeline/captureRect.ts +172 -0
- package/src/pipeline/color.ts +66 -0
- package/src/pipeline/constants.ts +65 -0
- package/src/pipeline/downsample.ts +74 -0
- package/src/pipeline/index.ts +20 -0
- package/src/pipeline/overlay.ts +46 -0
- package/src/pipeline/saturation.ts +65 -0
- package/src/pipeline/types.ts +37 -0
- package/src/pipeline/units.ts +32 -0
- package/src/presets.ts +103 -0
- package/src/types.ts +132 -0
package/src/presets.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Material-like presets (plan §11, plan §41 / Milestone 8).
|
|
3
|
+
*
|
|
4
|
+
* A preset is nothing more than a fixed, explicit
|
|
5
|
+
* `{ blurRadius, saturation, overlayColor }` prop bundle. There is no
|
|
6
|
+
* hidden or platform-specific behavior: applying `BlurPresets.dark` is
|
|
7
|
+
* exactly equivalent to spreading that plain object onto `<BlurView>`
|
|
8
|
+
* yourself, and the resulting three numbers/strings go through the same
|
|
9
|
+
* calibrated pipeline as any other explicit props (docs/PIPELINE_SPEC.md).
|
|
10
|
+
* Because blurRadius/saturation/overlayColor are calibrated to match
|
|
11
|
+
* cross-platform (docs/CALIBRATION_REPORT.md — worst measured ΔE76 0.90,
|
|
12
|
+
* SSIM ≥ 0.983), a given preset renders the same on iOS and Android.
|
|
13
|
+
*
|
|
14
|
+
* These are *approximations* of the visual weight of iOS system materials
|
|
15
|
+
* (UIBlurEffect styles), chosen by eye against reasonable blurRadius /
|
|
16
|
+
* saturation / overlayColor values — they are not derived from, measured
|
|
17
|
+
* against, or guaranteed to match `UIVisualEffectView` output, and Android
|
|
18
|
+
* has no equivalent native material to match at all. Treat the names as a
|
|
19
|
+
* starting point, not a parity claim (plan §43 — nested/material stacking
|
|
20
|
+
* is deterministic, not an Apple material emulation).
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <BlurView {...BlurPresets.dark} style={styles.sheet}>
|
|
25
|
+
* {children}
|
|
26
|
+
* </BlurView>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Every field is a plain public prop, so you can still override any one of
|
|
30
|
+
* them by spreading the preset first and your own prop second:
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <BlurView {...BlurPresets.dark} blurRadius={30} />
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Or, for the same effect without spreading, pass the `preset` prop
|
|
36
|
+
* directly to `<BlurView>` (`src/BlurView.tsx`) — it resolves to this same
|
|
37
|
+
* object client-side before any explicit blurRadius/saturation/overlayColor
|
|
38
|
+
* prop is applied on top of it. Both forms are pure JS convenience; neither
|
|
39
|
+
* adds a native prop.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/** One named preset: an explicit bundle of public BlurView props. */
|
|
43
|
+
export interface BlurPreset {
|
|
44
|
+
/** Gaussian sigma in dp — see `BlurViewProps.blurRadius`. */
|
|
45
|
+
blurRadius: number;
|
|
46
|
+
/** See `BlurViewProps.saturation`. */
|
|
47
|
+
saturation: number;
|
|
48
|
+
/** See `BlurViewProps.overlayColor`. */
|
|
49
|
+
overlayColor: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Keys of {@link BlurPresets}. */
|
|
53
|
+
export type BlurPresetName =
|
|
54
|
+
'ultraThin' | 'thin' | 'regular' | 'thick' | 'chrome' | 'light' | 'dark';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Named material-like preset table. See the module doc comment above for
|
|
58
|
+
* semantics and the "not a parity claim" caveat.
|
|
59
|
+
*/
|
|
60
|
+
export const BlurPresets: Readonly<Record<BlurPresetName, BlurPreset>> = {
|
|
61
|
+
/** Barely-there frosted glass: minimal blur, faint light tint. */
|
|
62
|
+
ultraThin: {
|
|
63
|
+
blurRadius: 10,
|
|
64
|
+
saturation: 1.3,
|
|
65
|
+
overlayColor: 'rgba(255,255,255,0.15)',
|
|
66
|
+
},
|
|
67
|
+
/** Light frosted glass, subtle. */
|
|
68
|
+
thin: {
|
|
69
|
+
blurRadius: 14,
|
|
70
|
+
saturation: 1.4,
|
|
71
|
+
overlayColor: 'rgba(255,255,255,0.25)',
|
|
72
|
+
},
|
|
73
|
+
/** Neutral, medium-weight — a reasonable default over photos/color. */
|
|
74
|
+
regular: {
|
|
75
|
+
blurRadius: 20,
|
|
76
|
+
saturation: 1.2,
|
|
77
|
+
overlayColor: 'rgba(128,128,128,0.16)',
|
|
78
|
+
},
|
|
79
|
+
/** Heavier blur, more opaque neutral-dark tint. */
|
|
80
|
+
thick: {
|
|
81
|
+
blurRadius: 28,
|
|
82
|
+
saturation: 1.3,
|
|
83
|
+
overlayColor: 'rgba(20,20,20,0.35)',
|
|
84
|
+
},
|
|
85
|
+
/** Near-opaque, low-saturation — for toolbar/nav-bar-like surfaces. */
|
|
86
|
+
chrome: {
|
|
87
|
+
blurRadius: 24,
|
|
88
|
+
saturation: 1.1,
|
|
89
|
+
overlayColor: 'rgba(230,230,230,0.55)',
|
|
90
|
+
},
|
|
91
|
+
/** Classic light material: strong blur, warm-white tint, boosted saturation. */
|
|
92
|
+
light: {
|
|
93
|
+
blurRadius: 20,
|
|
94
|
+
saturation: 1.8,
|
|
95
|
+
overlayColor: 'rgba(255,255,255,0.4)',
|
|
96
|
+
},
|
|
97
|
+
/** Classic dark material: strong blur, near-black tint, boosted saturation. */
|
|
98
|
+
dark: {
|
|
99
|
+
blurRadius: 20,
|
|
100
|
+
saturation: 1.5,
|
|
101
|
+
overlayColor: 'rgba(16,16,16,0.45)',
|
|
102
|
+
},
|
|
103
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { BlurPresetName } from './presets';
|
|
5
|
+
|
|
6
|
+
/** Public blur mode (plan §20/§21). default: 'static'. */
|
|
7
|
+
export type BlurMode = 'static' | 'live';
|
|
8
|
+
|
|
9
|
+
/** Public quality tier (plan §13). default: 'balanced'. */
|
|
10
|
+
export type BlurQuality = 'high' | 'balanced' | 'performance';
|
|
11
|
+
|
|
12
|
+
/** Public downsample selector (plan §12). default: 'auto'. */
|
|
13
|
+
export type BlurDownsample = 'auto' | 1 | 2 | 4 | 8;
|
|
14
|
+
|
|
15
|
+
export interface BlurViewProps {
|
|
16
|
+
/**
|
|
17
|
+
* Gaussian sigma in dp (plan §5.1) — the same canonical unit on both
|
|
18
|
+
* platforms (iOS pt ≡ Android dp semantically). Internally converted to
|
|
19
|
+
* each native backend's own blur parameter (docs/PIPELINE_SPEC.md §2), so
|
|
20
|
+
* the same number produces calibrated matching visual weight on iOS and
|
|
21
|
+
* Android (worst measured ΔE76 0.90, SSIM ≥ 0.983 across the parity
|
|
22
|
+
* suite — docs/CALIBRATION_REPORT.md). `0` (or omitted) renders no blur.
|
|
23
|
+
* Non-finite or negative values clamp to 0 with a DEV warning.
|
|
24
|
+
* default: 0.
|
|
25
|
+
*/
|
|
26
|
+
blurRadius?: number;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* `'static'` captures the backdrop once (on mount, layout change, or a
|
|
30
|
+
* prop change that affects the capture) and presents a still blurred
|
|
31
|
+
* snapshot; call `refresh()` to recapture after the backdrop changes
|
|
32
|
+
* underneath it. `'live'` recaptures continuously (throttled by
|
|
33
|
+
* `maxFps`) while the view is on screen. default: 'static'.
|
|
34
|
+
*/
|
|
35
|
+
mode?: BlurMode;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Named material-like preset (plan §11) resolved client-side to a base
|
|
39
|
+
* `{ blurRadius, saturation, overlayColor }` bundle before this
|
|
40
|
+
* component's own explicit props are applied on top — see
|
|
41
|
+
* `BlurPresets`/`BlurPresetName` in `presets.ts` for the exact values.
|
|
42
|
+
* Pure JS convenience: it does not add a native prop, and any of those
|
|
43
|
+
* three props passed explicitly alongside `preset` overrides the
|
|
44
|
+
* preset's value for that prop only. default: none.
|
|
45
|
+
*/
|
|
46
|
+
preset?: BlurPresetName;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Straight-alpha color composited source-over the blurred + saturated
|
|
50
|
+
* result (docs/PIPELINE_SPEC.md §8) — the only tint anywhere in the
|
|
51
|
+
* pipeline; there is no hidden per-platform tint. An unparseable color
|
|
52
|
+
* resolves to "no overlay" with a DEV warning. default: 'transparent'
|
|
53
|
+
* (no overlay).
|
|
54
|
+
*/
|
|
55
|
+
overlayColor?: string;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Post-blur saturation multiplier (docs/PIPELINE_SPEC.md §7), applied
|
|
59
|
+
* after blur and before the overlay: `1` = unchanged, `0` = Rec.709
|
|
60
|
+
* grayscale, values `> 1` boost saturation. Negative or non-finite values
|
|
61
|
+
* clamp to the default with a DEV warning. default: 1.
|
|
62
|
+
*/
|
|
63
|
+
saturation?: number;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Consumer-friendly quality tier that biases automatic downsample
|
|
67
|
+
* selection (plan §13): `'high'` prefers 1x/2x snapshots, `'balanced'`
|
|
68
|
+
* prefers 2x/4x, `'performance'` prefers 4x/8x. Has no effect when
|
|
69
|
+
* `downsample` is an explicit numeric override. default: 'balanced'.
|
|
70
|
+
*/
|
|
71
|
+
quality?: BlurQuality;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Snapshot downsample factor (plan §12). `'auto'` derives a factor from
|
|
75
|
+
* requested sigma, capture area, and `quality` (docs/PIPELINE_SPEC.md
|
|
76
|
+
* §4); `1 | 2 | 4 | 8` forces that exact factor for advanced tuning.
|
|
77
|
+
* default: 'auto'.
|
|
78
|
+
*/
|
|
79
|
+
downsample?: BlurDownsample;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Upper bound on live-mode recapture rate, in frames per second. Ignored
|
|
83
|
+
* in `'static'` mode. Clamped to `[1, 120]` with a DEV warning outside
|
|
84
|
+
* that range. default: 30.
|
|
85
|
+
*/
|
|
86
|
+
maxFps?: number;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Color rendered in place of a real blur wherever real blur is
|
|
90
|
+
* unavailable: Android below API 31 (no `RenderEffect`) or, on either
|
|
91
|
+
* platform, when the OS-level "Reduce Transparency" accessibility
|
|
92
|
+
* setting is on. Has no effect on a device/OS combination where real
|
|
93
|
+
* blur runs. default: none (renders fully transparent when the fallback
|
|
94
|
+
* path is active and no `fallbackColor` is set).
|
|
95
|
+
*/
|
|
96
|
+
fallbackColor?: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Target view whose subtree should be captured as the blur backdrop,
|
|
100
|
+
* instead of the default (the content behind this `BlurView` within its
|
|
101
|
+
* own window) (plan §18). **Not implemented in v1** — accepted only to
|
|
102
|
+
* keep the public API shape stable for a later release; passing it
|
|
103
|
+
* currently has no native-side effect. Deferred to v1.1 — see
|
|
104
|
+
* docs/LIMITATIONS.md.
|
|
105
|
+
*/
|
|
106
|
+
blurTarget?: React.RefObject<any>;
|
|
107
|
+
|
|
108
|
+
/** Content rendered on top of the blur; unaffected by it. */
|
|
109
|
+
children?: React.ReactNode;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Standard React Native view style. `borderRadius` (and other clipping
|
|
113
|
+
* styles) clip the blur output itself, not just the children (plan §31).
|
|
114
|
+
*/
|
|
115
|
+
style?: StyleProp<ViewStyle>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Imperative handle exposed via ref (plan §29).
|
|
120
|
+
*/
|
|
121
|
+
export interface BlurViewRef {
|
|
122
|
+
/**
|
|
123
|
+
* Schedules a coalesced recapture of the backdrop on the next valid
|
|
124
|
+
* frame — fully implemented end-to-end on both native backends (not a
|
|
125
|
+
* no-op). Repeated calls before the pending capture runs coalesce into a
|
|
126
|
+
* single recapture. Primarily useful in `mode="static"` after the
|
|
127
|
+
* backdrop has changed; in `mode="live"` the view is already recapturing
|
|
128
|
+
* continuously, so `refresh()` has no additional effect beyond nudging
|
|
129
|
+
* the next scheduled frame.
|
|
130
|
+
*/
|
|
131
|
+
refresh(): void;
|
|
132
|
+
}
|