@buoy-gg/shared-ui 7.0.22 → 7.0.23
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/lib/commonjs/JsModal.js +39 -16
- package/lib/commonjs/dataViewer/JsonStringNotice.js +59 -0
- package/lib/commonjs/dataViewer/ThemedSplitView.js +20 -1
- package/lib/commonjs/dataViewer/TimestampDeltaBar.js +96 -0
- package/lib/commonjs/dataViewer/index.js +52 -0
- package/lib/commonjs/dataViewer/jsonStringValue.js +94 -0
- package/lib/commonjs/dataViewer/timestampDiff.js +146 -0
- package/lib/commonjs/hooks/safe-area-impl.js +1 -1
- package/lib/commonjs/index.js +50 -1
- package/lib/commonjs/license/FeatureGate.js +43 -10
- package/lib/commonjs/license/FreeAccountPrompt.js +181 -0
- package/lib/commonjs/license/index.js +57 -42
- package/lib/commonjs/license/licenseModule.js +99 -0
- package/lib/commonjs/license/tierLimits.js +165 -0
- package/lib/commonjs/ui/backgrounds/BackgroundSwitcher.js +180 -0
- package/lib/commonjs/ui/backgrounds/README.md +115 -0
- package/lib/commonjs/ui/backgrounds/ToolBackground.js +74 -0
- package/lib/commonjs/ui/backgrounds/backgroundStore.js +116 -0
- package/lib/commonjs/ui/backgrounds/index.js +70 -0
- package/lib/commonjs/ui/backgrounds/primitives.js +333 -0
- package/lib/commonjs/ui/backgrounds/registry.js +112 -0
- package/lib/commonjs/ui/backgrounds/rng.js +72 -0
- package/lib/commonjs/ui/backgrounds/types.js +1 -0
- package/lib/commonjs/ui/backgrounds/variants/deepField.js +351 -0
- package/lib/commonjs/ui/backgrounds/variants/lattice.js +579 -0
- package/lib/commonjs/ui/backgrounds/variants/starfield.js +210 -0
- package/lib/commonjs/ui/index.js +15 -3
- package/lib/module/JsModal.js +39 -16
- package/lib/module/dataViewer/JsonStringNotice.js +54 -0
- package/lib/module/dataViewer/ThemedSplitView.js +20 -1
- package/lib/module/dataViewer/TimestampDeltaBar.js +91 -0
- package/lib/module/dataViewer/index.js +4 -0
- package/lib/module/dataViewer/jsonStringValue.js +89 -0
- package/lib/module/dataViewer/timestampDiff.js +139 -0
- package/lib/module/hooks/safe-area-impl.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/license/FeatureGate.js +43 -10
- package/lib/module/license/FreeAccountPrompt.js +176 -0
- package/lib/module/license/index.js +5 -40
- package/lib/module/license/licenseModule.js +92 -0
- package/lib/module/license/tierLimits.js +158 -0
- package/lib/module/ui/backgrounds/BackgroundSwitcher.js +176 -0
- package/lib/module/ui/backgrounds/README.md +115 -0
- package/lib/module/ui/backgrounds/ToolBackground.js +70 -0
- package/lib/module/ui/backgrounds/backgroundStore.js +111 -0
- package/lib/module/ui/backgrounds/index.js +9 -0
- package/lib/module/ui/backgrounds/primitives.js +328 -0
- package/lib/module/ui/backgrounds/registry.js +105 -0
- package/lib/module/ui/backgrounds/rng.js +65 -0
- package/lib/module/ui/backgrounds/types.js +1 -0
- package/lib/module/ui/backgrounds/variants/deepField.js +347 -0
- package/lib/module/ui/backgrounds/variants/lattice.js +575 -0
- package/lib/module/ui/backgrounds/variants/starfield.js +206 -0
- package/lib/module/ui/index.js +3 -0
- package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/JsonStringNotice.d.ts +6 -0
- package/lib/typescript/commonjs/dataViewer/JsonStringNotice.d.ts.map +1 -0
- package/lib/typescript/commonjs/dataViewer/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/TimestampDeltaBar.d.ts +7 -0
- package/lib/typescript/commonjs/dataViewer/TimestampDeltaBar.d.ts.map +1 -0
- package/lib/typescript/commonjs/dataViewer/index.d.ts +6 -0
- package/lib/typescript/commonjs/dataViewer/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/jsonStringValue.d.ts +25 -0
- package/lib/typescript/commonjs/dataViewer/jsonStringValue.d.ts.map +1 -0
- package/lib/typescript/commonjs/dataViewer/timestampDiff.d.ts +55 -0
- package/lib/typescript/commonjs/dataViewer/timestampDiff.d.ts.map +1 -0
- package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -2
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/FeatureGate.d.ts +19 -3
- package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts +23 -0
- package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts.map +1 -0
- package/lib/typescript/commonjs/license/index.d.ts +6 -15
- package/lib/typescript/commonjs/license/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/licenseModule.d.ts +55 -0
- package/lib/typescript/commonjs/license/licenseModule.d.ts.map +1 -0
- package/lib/typescript/commonjs/license/tierLimits.d.ts +143 -0
- package/lib/typescript/commonjs/license/tierLimits.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/BackgroundSwitcher.d.ts +13 -0
- package/lib/typescript/commonjs/ui/backgrounds/BackgroundSwitcher.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts +30 -0
- package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/backgroundStore.d.ts +43 -0
- package/lib/typescript/commonjs/ui/backgrounds/backgroundStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/index.d.ts +7 -0
- package/lib/typescript/commonjs/ui/backgrounds/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/primitives.d.ts +106 -0
- package/lib/typescript/commonjs/ui/backgrounds/primitives.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts +28 -0
- package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/rng.d.ts +27 -0
- package/lib/typescript/commonjs/ui/backgrounds/rng.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/types.d.ts +14 -0
- package/lib/typescript/commonjs/ui/backgrounds/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/deepField.d.ts +65 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/deepField.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/lattice.d.ts +33 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/lattice.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/starfield.d.ts +12 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/starfield.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/index.d.ts +1 -0
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/JsModal.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/JsonStringNotice.d.ts +6 -0
- package/lib/typescript/module/dataViewer/JsonStringNotice.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/TimestampDeltaBar.d.ts +7 -0
- package/lib/typescript/module/dataViewer/TimestampDeltaBar.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/index.d.ts +6 -0
- package/lib/typescript/module/dataViewer/index.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/jsonStringValue.d.ts +25 -0
- package/lib/typescript/module/dataViewer/jsonStringValue.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/timestampDiff.d.ts +55 -0
- package/lib/typescript/module/dataViewer/timestampDiff.d.ts.map +1 -0
- package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/module/index.d.ts +2 -2
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/license/FeatureGate.d.ts +19 -3
- package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
- package/lib/typescript/module/license/FreeAccountPrompt.d.ts +23 -0
- package/lib/typescript/module/license/FreeAccountPrompt.d.ts.map +1 -0
- package/lib/typescript/module/license/index.d.ts +6 -15
- package/lib/typescript/module/license/index.d.ts.map +1 -1
- package/lib/typescript/module/license/licenseModule.d.ts +55 -0
- package/lib/typescript/module/license/licenseModule.d.ts.map +1 -0
- package/lib/typescript/module/license/tierLimits.d.ts +143 -0
- package/lib/typescript/module/license/tierLimits.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/BackgroundSwitcher.d.ts +13 -0
- package/lib/typescript/module/ui/backgrounds/BackgroundSwitcher.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts +30 -0
- package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/backgroundStore.d.ts +43 -0
- package/lib/typescript/module/ui/backgrounds/backgroundStore.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/index.d.ts +7 -0
- package/lib/typescript/module/ui/backgrounds/index.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/primitives.d.ts +106 -0
- package/lib/typescript/module/ui/backgrounds/primitives.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/registry.d.ts +28 -0
- package/lib/typescript/module/ui/backgrounds/registry.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/rng.d.ts +27 -0
- package/lib/typescript/module/ui/backgrounds/rng.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/types.d.ts +14 -0
- package/lib/typescript/module/ui/backgrounds/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/variants/deepField.d.ts +65 -0
- package/lib/typescript/module/ui/backgrounds/variants/deepField.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/variants/lattice.d.ts +33 -0
- package/lib/typescript/module/ui/backgrounds/variants/lattice.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/variants/starfield.d.ts +12 -0
- package/lib/typescript/module/ui/backgrounds/variants/starfield.d.ts.map +1 -0
- package/lib/typescript/module/ui/index.d.ts +1 -0
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/scripts/detect-safe-area.js +0 -20
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DeepFieldTunable = exports.DeepField = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _absoluteFill = require("../../../utils/absoluteFill.js");
|
|
10
|
+
var _primitives = require("../primitives.js");
|
|
11
|
+
var _rng = require("../rng.js");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
/**
|
|
14
|
+
* Deep Field — a faithful port of the Everlights `ParallaxDriftBackground`.
|
|
15
|
+
*
|
|
16
|
+
* The sibling `Starfield` preset is a cheap approximation of the same idea: 99
|
|
17
|
+
* stars quantised into five depth bands. This one reproduces the original's
|
|
18
|
+
* field exactly — same seed, same generator call order, same 160 stars, same
|
|
19
|
+
* `z = zNear + zSpan·√rnd()` far-plane bias, same sizes, brightnesses, palette
|
|
20
|
+
* and drift. Drop the constants below into the Skia version and you get the
|
|
21
|
+
* same sky.
|
|
22
|
+
*
|
|
23
|
+
* WHAT COULDN'T COME ACROSS 1:1, and what was done instead:
|
|
24
|
+
*
|
|
25
|
+
* - **Continuous per-star speed.** The original runs a worklet per star, so
|
|
26
|
+
* every one of the 160 drifts at its own `drift/z`. Here a distinct speed
|
|
27
|
+
* means a distinct animated node, so SPEED (and only speed) is quantised
|
|
28
|
+
* into 18 bands — banded uniformly in 1/z, which is what speed is
|
|
29
|
+
* proportional to, so the steps are even. Size, brightness, colour and
|
|
30
|
+
* twinkle phase all stay per-star and exact, and those are the properties
|
|
31
|
+
* the eye actually reads as depth.
|
|
32
|
+
*
|
|
33
|
+
* - **The soft bulb sprite.** The original bakes one 64px sprite (blurred halo
|
|
34
|
+
* at r=6/α.30 over a blurred core at r=4/α1) and stamps it at `dia`. That is
|
|
35
|
+
* why stars stay fine points even at dia=20 — the lit core is only ~13% of
|
|
36
|
+
* the stamp. There is no blur primitive here, so each star is a small solid
|
|
37
|
+
* core at that same 13%, and the nearer ones get one or two concentric
|
|
38
|
+
* discs standing in for the halo. Far stars end up a single ~1px dot, which
|
|
39
|
+
* is what the sprite renders them as anyway.
|
|
40
|
+
*
|
|
41
|
+
* - **Additive blending.** `blendMode="plus"` becomes ordinary alpha
|
|
42
|
+
* compositing. Over a near-black base the two agree except where stars
|
|
43
|
+
* overlap, which at this density is rare.
|
|
44
|
+
*
|
|
45
|
+
* It costs roughly twice the cheap Starfield — see `registry.tsx` — which is
|
|
46
|
+
* the whole reason both are in the catalogue.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// The original's shipping constants, verbatim.
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
const COUNT = 160;
|
|
53
|
+
const DRIFT = 0.016; // horizontal travel/sec at z=1, as a fraction of width
|
|
54
|
+
const BASE_DIA = 5; // sprite diameter px at z=1
|
|
55
|
+
const Z_NEAR = 0.25;
|
|
56
|
+
const Z_FAR = 1.0;
|
|
57
|
+
const Z_SPAN = Z_FAR - Z_NEAR;
|
|
58
|
+
const MAX_DIA = BASE_DIA / Z_NEAR;
|
|
59
|
+
const TWINKLE = 0.08;
|
|
60
|
+
|
|
61
|
+
/** The classic white/blue mix — `[r,g,b]` 0..1 in the original. */
|
|
62
|
+
const PALETTE = ["#FFFFFF", "#B3D9FF", "#8CB3FF"];
|
|
63
|
+
|
|
64
|
+
/** The backdrop the field sits on — also what `opaque` mode flattens against. */
|
|
65
|
+
const BASE_COLOR = "#050609";
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Default speed bands. 18 is the point where stepping stops being visible:
|
|
69
|
+
* adjacent bands differ by ~6% in speed, well under what reads as a seam. The
|
|
70
|
+
* bench route sweeps this, since it is the main lever on cost.
|
|
71
|
+
*/
|
|
72
|
+
const BAND_COUNT = 18;
|
|
73
|
+
/** Twinkle groups — bands are round-robined across these. */
|
|
74
|
+
const TWINKLE_GROUPS = 4;
|
|
75
|
+
const TWINKLE_MS = [4200, 4900, 5600, 6300];
|
|
76
|
+
|
|
77
|
+
/** How the ±8% brightness wobble is applied. */
|
|
78
|
+
|
|
79
|
+
/** How many concentric discs stand in for the sprite's blurred halo. */
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The original field, regenerated.
|
|
83
|
+
*
|
|
84
|
+
* The generator order matters as much as the seed: the source pulls fx, fy, z
|
|
85
|
+
* and tw off ONE mulberry32 stream per star, so drawing them in any other order
|
|
86
|
+
* — four separate `scatter()` calls, say — gives a different sky from the same
|
|
87
|
+
* seed. Built once at module load.
|
|
88
|
+
*/
|
|
89
|
+
function buildField(count) {
|
|
90
|
+
const rnd = (0, _rng.mulberry32)((0x5747 ^ count) >>> 0);
|
|
91
|
+
const stars = [];
|
|
92
|
+
for (let i = 0; i < count; i++) {
|
|
93
|
+
const fx = rnd();
|
|
94
|
+
const fy = rnd();
|
|
95
|
+
// Bias toward the far plane so close, fast streaks stay sparse.
|
|
96
|
+
const z = Z_NEAR + Z_SPAN * Math.sqrt(rnd());
|
|
97
|
+
const tw = rnd() * Math.PI * 2;
|
|
98
|
+
const dia = Math.min(BASE_DIA / z, MAX_DIA);
|
|
99
|
+
const near = (Z_FAR - z) / Z_SPAN; // 0 far → 1 near
|
|
100
|
+
stars.push({
|
|
101
|
+
fx,
|
|
102
|
+
fy,
|
|
103
|
+
z,
|
|
104
|
+
tw,
|
|
105
|
+
// 0.15·dia ≈ the sprite's lit core (r=4 of 64, blurred), with a 1.1px
|
|
106
|
+
// floor so the farthest stars still land on a pixel.
|
|
107
|
+
core: Math.max(1.1, dia * 0.15),
|
|
108
|
+
halo: dia * 0.3,
|
|
109
|
+
haloDiscs: z < 0.45 ? 2 : z < 0.7 ? 1 : 0,
|
|
110
|
+
alpha: 0.2 + 0.8 * near,
|
|
111
|
+
color: PALETTE[Math.floor((tw * 0.5 + 0.5) * PALETTE.length) % PALETTE.length]
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return stars;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Fields by star count, built on demand.
|
|
119
|
+
*
|
|
120
|
+
* 160 is the real preset. The larger counts exist for AMPLIFIED benchmarking:
|
|
121
|
+
* at 160 the difference between two rendering structures is ~2 CPU points,
|
|
122
|
+
* which on real hardware sits under a noise floor several times that — so the
|
|
123
|
+
* variants are compared at a scale where the difference is unmistakable, and
|
|
124
|
+
* the structure that wins there is the one worth shipping at 160.
|
|
125
|
+
*
|
|
126
|
+
* Note the seed is `0x5747 ^ count`, exactly as the original does it, so each
|
|
127
|
+
* count is its own field rather than a prefix of a bigger one. That is fine
|
|
128
|
+
* here: only the 160 field has to match Everlights.
|
|
129
|
+
*/
|
|
130
|
+
const fieldCache = new Map();
|
|
131
|
+
function getField(count) {
|
|
132
|
+
const cached = fieldCache.get(count);
|
|
133
|
+
if (cached) return cached;
|
|
134
|
+
const built = buildField(count);
|
|
135
|
+
fieldCache.set(count, built);
|
|
136
|
+
return built;
|
|
137
|
+
}
|
|
138
|
+
const FIELD = getField(COUNT);
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Bucket by 1/z (∝ speed) rather than by z, so the bands are evenly spaced in
|
|
142
|
+
* the quantity being quantised. Each band carries its member stars and the
|
|
143
|
+
* speed of its centre. Cached per count — the bench route asks for several.
|
|
144
|
+
*/
|
|
145
|
+
const bandCache = new Map();
|
|
146
|
+
function buildBands(count, starCount) {
|
|
147
|
+
const key = `${count}:${starCount}`;
|
|
148
|
+
const cached = bandCache.get(key);
|
|
149
|
+
if (cached) return cached;
|
|
150
|
+
const field = getField(starCount);
|
|
151
|
+
const invNear = 1 / Z_NEAR; // 4
|
|
152
|
+
const invFar = 1 / Z_FAR; // 1
|
|
153
|
+
const span = invNear - invFar;
|
|
154
|
+
const buckets = Array.from({
|
|
155
|
+
length: count
|
|
156
|
+
}, () => []);
|
|
157
|
+
for (const star of field) {
|
|
158
|
+
const t = (1 / star.z - invFar) / span;
|
|
159
|
+
const idx = Math.min(count - 1, Math.max(0, Math.floor(t * count)));
|
|
160
|
+
buckets[idx].push(star);
|
|
161
|
+
}
|
|
162
|
+
const bands = buckets.map((stars, i) => ({
|
|
163
|
+
stars,
|
|
164
|
+
// z at the band's centre, back out of the 1/z bucketing.
|
|
165
|
+
z: 1 / (invFar + (i + 0.5) / count * span)
|
|
166
|
+
}));
|
|
167
|
+
bandCache.set(key, bands);
|
|
168
|
+
return bands;
|
|
169
|
+
}
|
|
170
|
+
const DeepBand = /*#__PURE__*/(0, _react.memo)(function DeepBand({
|
|
171
|
+
bands,
|
|
172
|
+
index,
|
|
173
|
+
width,
|
|
174
|
+
height,
|
|
175
|
+
animated,
|
|
176
|
+
raster,
|
|
177
|
+
halo,
|
|
178
|
+
opaque,
|
|
179
|
+
drift,
|
|
180
|
+
opacity
|
|
181
|
+
}) {
|
|
182
|
+
const band = bands[index];
|
|
183
|
+
// One full width of travel takes z / DRIFT seconds, exactly as in the
|
|
184
|
+
// original's `phase = fx - t·(drift/z)`.
|
|
185
|
+
const driftValue = (0, _primitives.useLoop)(band.z / DRIFT * 1000, animated && drift);
|
|
186
|
+
const translateX = driftValue.interpolate({
|
|
187
|
+
inputRange: [0, 1],
|
|
188
|
+
outputRange: [0, -width]
|
|
189
|
+
});
|
|
190
|
+
// Over a known backdrop an opaque colour is pixel-identical to the
|
|
191
|
+
// translucent one — the GPU just skips the blend.
|
|
192
|
+
const paint = (color, alpha) => opaque ? (0, _rng.flattenOver)(color, alpha, BASE_COLOR) : (0, _rng.withAlpha)(color, alpha);
|
|
193
|
+
const parts = [];
|
|
194
|
+
for (let i = 0; i < band.stars.length; i++) {
|
|
195
|
+
const star = band.stars[i];
|
|
196
|
+
const y = star.fy * height;
|
|
197
|
+
const discs = halo === "none" ? 0 : halo === "flat" ? star.haloDiscs > 0 ? 1 : 0 : star.haloDiscs;
|
|
198
|
+
// Drawn twice, one width apart, so the layer tiles seamlessly when the
|
|
199
|
+
// loop snaps back to 0.
|
|
200
|
+
for (let copy = 0; copy < 2; copy++) {
|
|
201
|
+
const x = star.fx * width + copy * width;
|
|
202
|
+
const key = `${i}-${copy}`;
|
|
203
|
+
for (let h = 0; h < discs; h++) {
|
|
204
|
+
const d = star.halo * (h === 0 ? 1 : 0.6);
|
|
205
|
+
parts.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
206
|
+
style: {
|
|
207
|
+
position: "absolute",
|
|
208
|
+
left: x - d / 2,
|
|
209
|
+
top: y - d / 2,
|
|
210
|
+
width: d,
|
|
211
|
+
height: d,
|
|
212
|
+
borderRadius: d / 2,
|
|
213
|
+
// The sprite's halo is α.30 of the core; scaled by the star's own
|
|
214
|
+
// depth brightness like everything else.
|
|
215
|
+
backgroundColor: paint(star.color, star.alpha * 0.3)
|
|
216
|
+
}
|
|
217
|
+
}, `${key}-h${h}`));
|
|
218
|
+
}
|
|
219
|
+
parts.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
220
|
+
style: {
|
|
221
|
+
position: "absolute",
|
|
222
|
+
left: x - star.core / 2,
|
|
223
|
+
top: y - star.core / 2,
|
|
224
|
+
width: star.core,
|
|
225
|
+
height: star.core,
|
|
226
|
+
borderRadius: star.core / 2,
|
|
227
|
+
backgroundColor: paint(star.color, star.alpha)
|
|
228
|
+
}
|
|
229
|
+
}, key));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
233
|
+
style: [{
|
|
234
|
+
position: "absolute",
|
|
235
|
+
left: 0,
|
|
236
|
+
top: 0,
|
|
237
|
+
width: width * 2,
|
|
238
|
+
height
|
|
239
|
+
},
|
|
240
|
+
// Fused mode puts the wobble on THIS layer instead of a wrapper above
|
|
241
|
+
// it, so the twinkle costs no extra composited surface.
|
|
242
|
+
opacity ? {
|
|
243
|
+
opacity,
|
|
244
|
+
transform: [{
|
|
245
|
+
translateX
|
|
246
|
+
}]
|
|
247
|
+
} : {
|
|
248
|
+
transform: [{
|
|
249
|
+
translateX
|
|
250
|
+
}]
|
|
251
|
+
}],
|
|
252
|
+
pointerEvents: "none",
|
|
253
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.RasterLayer, {
|
|
254
|
+
raster: raster,
|
|
255
|
+
style: {
|
|
256
|
+
width: width * 2,
|
|
257
|
+
height
|
|
258
|
+
},
|
|
259
|
+
children: parts
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* The four wobble values. The original wobbles each star by
|
|
266
|
+
* `1 + 0.08·sin(t·3 + tw)`; per-star that would be 160 nodes, so bands are
|
|
267
|
+
* round-robined across four pulses at slightly different periods — same ±8%
|
|
268
|
+
* amplitude, and the differing periods keep the sky from pulsing as a unit.
|
|
269
|
+
*
|
|
270
|
+
* Fixed count, called unconditionally, so hook order never varies with props.
|
|
271
|
+
*/
|
|
272
|
+
function useTwinkles(animated, enabled) {
|
|
273
|
+
const a = (0, _primitives.usePulse)(TWINKLE_MS[0], animated && enabled);
|
|
274
|
+
const b = (0, _primitives.usePulse)(TWINKLE_MS[1], animated && enabled);
|
|
275
|
+
const c = (0, _primitives.usePulse)(TWINKLE_MS[2], animated && enabled);
|
|
276
|
+
const d = (0, _primitives.usePulse)(TWINKLE_MS[3], animated && enabled);
|
|
277
|
+
const range = {
|
|
278
|
+
inputRange: [0, 1],
|
|
279
|
+
outputRange: [1 - TWINKLE, 1]
|
|
280
|
+
};
|
|
281
|
+
return [a.interpolate(range), b.interpolate(range), c.interpolate(range), d.interpolate(range)];
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* The tunable body. `DeepField` below is this with the shipping defaults; the
|
|
285
|
+
* bench route (`example-dev-build/app/bg-bench.tsx`) drives the knobs so every
|
|
286
|
+
* measured variant is this exact code, not a copy of it.
|
|
287
|
+
*/
|
|
288
|
+
const DeepFieldTunable = exports.DeepFieldTunable = /*#__PURE__*/(0, _react.memo)(function DeepFieldTunable({
|
|
289
|
+
width,
|
|
290
|
+
height,
|
|
291
|
+
animated,
|
|
292
|
+
bandCount = BAND_COUNT,
|
|
293
|
+
raster = true,
|
|
294
|
+
twinkle = "group",
|
|
295
|
+
halo = "full",
|
|
296
|
+
opaque = false,
|
|
297
|
+
drift = true,
|
|
298
|
+
starCount = COUNT
|
|
299
|
+
}) {
|
|
300
|
+
const bands = buildBands(bandCount, starCount);
|
|
301
|
+
const twinkles = useTwinkles(animated, twinkle !== "off");
|
|
302
|
+
const bandViews = [];
|
|
303
|
+
for (let i = 0; i < bandCount; i++) {
|
|
304
|
+
bandViews.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(DeepBand, {
|
|
305
|
+
bands: bands,
|
|
306
|
+
index: i,
|
|
307
|
+
width: width,
|
|
308
|
+
height: height,
|
|
309
|
+
animated: animated,
|
|
310
|
+
raster: raster,
|
|
311
|
+
halo: halo,
|
|
312
|
+
opaque: opaque,
|
|
313
|
+
drift: drift,
|
|
314
|
+
opacity: twinkle === "fused" ? twinkles[i % TWINKLE_GROUPS] : undefined
|
|
315
|
+
}, i));
|
|
316
|
+
}
|
|
317
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
318
|
+
style: _absoluteFill.absoluteFill,
|
|
319
|
+
pointerEvents: "none",
|
|
320
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Base, {
|
|
321
|
+
color: BASE_COLOR
|
|
322
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.RadialGlow, {
|
|
323
|
+
size: width * 1.7,
|
|
324
|
+
color: "#1E3A8A",
|
|
325
|
+
alpha: 0.16,
|
|
326
|
+
rings: 8,
|
|
327
|
+
falloff: 2.1,
|
|
328
|
+
style: {
|
|
329
|
+
position: "absolute",
|
|
330
|
+
left: -width * 0.35,
|
|
331
|
+
top: -width
|
|
332
|
+
}
|
|
333
|
+
}), twinkle === "group" ?
|
|
334
|
+
// Group mode: one full-screen Animated.View per pulse, each wrapping
|
|
335
|
+
// its share of the bands. Costs four extra composited surfaces.
|
|
336
|
+
Array.from({
|
|
337
|
+
length: TWINKLE_GROUPS
|
|
338
|
+
}, (_, g) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
339
|
+
style: [_absoluteFill.absoluteFill, {
|
|
340
|
+
opacity: twinkles[g]
|
|
341
|
+
}],
|
|
342
|
+
pointerEvents: "none",
|
|
343
|
+
children: bandViews.filter((_, i) => i % TWINKLE_GROUPS === g)
|
|
344
|
+
}, g)) : bandViews]
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
const DeepField = exports.DeepField = /*#__PURE__*/(0, _react.memo)(function DeepField(props) {
|
|
348
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(DeepFieldTunable, {
|
|
349
|
+
...props
|
|
350
|
+
});
|
|
351
|
+
});
|