@buoy-gg/shared-ui 7.0.22 → 7.0.24
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,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "BACKGROUND_PRESETS", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _registry.BACKGROUND_PRESETS;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "BackgroundSwitcher", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _BackgroundSwitcher.BackgroundSwitcher;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "DEFAULT_BACKGROUND", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _registry.DEFAULT_BACKGROUND;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "DeepFieldTunable", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _deepField.DeepFieldTunable;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "ToolBackground", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _ToolBackground.ToolBackground;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "backgroundStore", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _backgroundStore.backgroundStore;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "getPreset", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _registry.getPreset;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "presetAt", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _registry.presetAt;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "presetIndex", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _registry.presetIndex;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "useToolBackground", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _backgroundStore.useToolBackground;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
var _ToolBackground = require("./ToolBackground.js");
|
|
67
|
+
var _BackgroundSwitcher = require("./BackgroundSwitcher.js");
|
|
68
|
+
var _backgroundStore = require("./backgroundStore.js");
|
|
69
|
+
var _registry = require("./registry.js");
|
|
70
|
+
var _deepField = require("./variants/deepField.js");
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.hairline = exports.Vignette = exports.RasterLayer = exports.RadialGlow = exports.LinearFade = exports.Base = void 0;
|
|
7
|
+
exports.useLoop = useLoop;
|
|
8
|
+
exports.usePulse = usePulse;
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
var _absoluteFill = require("../../utils/absoluteFill.js");
|
|
12
|
+
var _rng = require("./rng.js");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
/**
|
|
15
|
+
* Drawing + animation primitives for the tool backgrounds.
|
|
16
|
+
*
|
|
17
|
+
* HARD CONSTRAINT: Buoy's packages peer-depend on nothing but `react` and
|
|
18
|
+
* `react-native`. No Skia, no Reanimated, no SVG, no gradient library — a
|
|
19
|
+
* devtool cannot force a native dependency into someone's app. So every
|
|
20
|
+
* background here is built out of plain `View`s plus `Animated`, and the
|
|
21
|
+
* gradients/glows below are *faked* by stacking translucent layers.
|
|
22
|
+
*
|
|
23
|
+
* That sounds expensive. It isn't, because of two rules every preset follows:
|
|
24
|
+
*
|
|
25
|
+
* 1. **Every animation is native-driven.** `useNativeDriver: true` on a
|
|
26
|
+
* looping `Animated.timing` means the whole loop is handed to the UI thread
|
|
27
|
+
* once and never touches JS again — no per-frame callback, no re-render, no
|
|
28
|
+
* bridge traffic while it runs. A preset animates a handful of *layers*
|
|
29
|
+
* (transform on one parent view), never per-particle.
|
|
30
|
+
*
|
|
31
|
+
* 2. **Every static layer is rasterized.** `shouldRasterizeIOS` /
|
|
32
|
+
* `renderToHardwareTextureAndroid` turn a layer of 40 dots into a single
|
|
33
|
+
* cached GPU texture, so sliding it is one composite — the same cost as
|
|
34
|
+
* sliding one view. See `RasterLayer`.
|
|
35
|
+
*
|
|
36
|
+
* The result: a preset costs a one-time mount of static views and then ~0
|
|
37
|
+
* JS-thread work per frame. See `packages/shared/src/ui/backgrounds/README.md`.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Animation
|
|
42
|
+
// ============================================================================
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A native-driven 0→1 loop.
|
|
46
|
+
*
|
|
47
|
+
* The returned value is only ever consumed by `interpolate` inside an
|
|
48
|
+
* `Animated.View` style, so React never re-renders while it runs. The loop is
|
|
49
|
+
* stopped when the app backgrounds (a background animation is pure battery
|
|
50
|
+
* burn) and restarted on foreground.
|
|
51
|
+
*/
|
|
52
|
+
function useLoop(durationMs, enabled = true) {
|
|
53
|
+
const value = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
54
|
+
(0, _react.useEffect)(() => {
|
|
55
|
+
if (!enabled) return;
|
|
56
|
+
let anim = null;
|
|
57
|
+
const start = () => {
|
|
58
|
+
if (anim) return;
|
|
59
|
+
value.setValue(0);
|
|
60
|
+
anim = _reactNative.Animated.loop(_reactNative.Animated.timing(value, {
|
|
61
|
+
toValue: 1,
|
|
62
|
+
duration: durationMs,
|
|
63
|
+
easing: _reactNative.Easing.linear,
|
|
64
|
+
useNativeDriver: true
|
|
65
|
+
}));
|
|
66
|
+
anim.start();
|
|
67
|
+
};
|
|
68
|
+
const stop = () => {
|
|
69
|
+
anim?.stop();
|
|
70
|
+
anim = null;
|
|
71
|
+
value.setValue(0);
|
|
72
|
+
};
|
|
73
|
+
start();
|
|
74
|
+
const sub = _reactNative.AppState.addEventListener("change", state => {
|
|
75
|
+
if (state === "active") start();else stop();
|
|
76
|
+
});
|
|
77
|
+
return () => {
|
|
78
|
+
stop();
|
|
79
|
+
sub.remove();
|
|
80
|
+
};
|
|
81
|
+
}, [durationMs, enabled, value]);
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A native-driven 0→1→0 breathe, for glows that pulse rather than travel.
|
|
87
|
+
* Same no-JS-per-frame guarantee as `useLoop`.
|
|
88
|
+
*/
|
|
89
|
+
function usePulse(durationMs, enabled = true) {
|
|
90
|
+
const value = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
91
|
+
(0, _react.useEffect)(() => {
|
|
92
|
+
if (!enabled) return;
|
|
93
|
+
let anim = null;
|
|
94
|
+
const start = () => {
|
|
95
|
+
if (anim) return;
|
|
96
|
+
value.setValue(0);
|
|
97
|
+
anim = _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(value, {
|
|
98
|
+
toValue: 1,
|
|
99
|
+
duration: durationMs / 2,
|
|
100
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.quad),
|
|
101
|
+
useNativeDriver: true
|
|
102
|
+
}), _reactNative.Animated.timing(value, {
|
|
103
|
+
toValue: 0,
|
|
104
|
+
duration: durationMs / 2,
|
|
105
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.quad),
|
|
106
|
+
useNativeDriver: true
|
|
107
|
+
})]));
|
|
108
|
+
anim.start();
|
|
109
|
+
};
|
|
110
|
+
const stop = () => {
|
|
111
|
+
anim?.stop();
|
|
112
|
+
anim = null;
|
|
113
|
+
};
|
|
114
|
+
start();
|
|
115
|
+
const sub = _reactNative.AppState.addEventListener("change", state => {
|
|
116
|
+
if (state === "active") start();else stop();
|
|
117
|
+
});
|
|
118
|
+
return () => {
|
|
119
|
+
stop();
|
|
120
|
+
sub.remove();
|
|
121
|
+
};
|
|
122
|
+
}, [durationMs, enabled, value]);
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// Layers
|
|
128
|
+
// ============================================================================
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A layer whose children are static and should be flattened into one GPU
|
|
132
|
+
* texture. Wrap anything that gets translated/scaled as a whole — this is what
|
|
133
|
+
* makes a 40-dot star band cost the same to move as a single view.
|
|
134
|
+
*/
|
|
135
|
+
const RasterLayer = exports.RasterLayer = /*#__PURE__*/(0, _react.memo)(function RasterLayer({
|
|
136
|
+
style,
|
|
137
|
+
raster = true,
|
|
138
|
+
children
|
|
139
|
+
}) {
|
|
140
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
141
|
+
style: style,
|
|
142
|
+
pointerEvents: "none"
|
|
143
|
+
// Both are no-ops on the platform they don't belong to, and on web
|
|
144
|
+
// (react-native-web) neither exists — there the browser already
|
|
145
|
+
// composites a transformed subtree on the GPU.
|
|
146
|
+
,
|
|
147
|
+
shouldRasterizeIOS: raster && _reactNative.Platform.OS === "ios",
|
|
148
|
+
renderToHardwareTextureAndroid: raster && _reactNative.Platform.OS === "android",
|
|
149
|
+
children: children
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Fake radial gradient: concentric rounded views, each a constant per-ring
|
|
155
|
+
* alpha, with radii shrinking on a curve. Alpha compositing of N equal layers
|
|
156
|
+
* gives `1 - (1-a)^N` at the centre, so `a` is solved from the requested peak
|
|
157
|
+
* alpha and the falloff comes from the radius curve.
|
|
158
|
+
*
|
|
159
|
+
* 8 rings is the sweet spot on a dark surface — below that you can see banding,
|
|
160
|
+
* above it you're paying for views nobody can distinguish.
|
|
161
|
+
*/
|
|
162
|
+
const RadialGlow = exports.RadialGlow = /*#__PURE__*/(0, _react.memo)(function RadialGlow({
|
|
163
|
+
size,
|
|
164
|
+
color,
|
|
165
|
+
alpha = 0.35,
|
|
166
|
+
rings = 8,
|
|
167
|
+
falloff = 1.7,
|
|
168
|
+
style
|
|
169
|
+
}) {
|
|
170
|
+
const per = 1 - Math.pow(1 - alpha, 1 / rings);
|
|
171
|
+
const layers = [];
|
|
172
|
+
for (let i = 0; i < rings; i++) {
|
|
173
|
+
const d = size * Math.pow((rings - i) / rings, falloff);
|
|
174
|
+
layers.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
175
|
+
style: {
|
|
176
|
+
position: "absolute",
|
|
177
|
+
left: (size - d) / 2,
|
|
178
|
+
top: (size - d) / 2,
|
|
179
|
+
width: d,
|
|
180
|
+
height: d,
|
|
181
|
+
borderRadius: d / 2,
|
|
182
|
+
backgroundColor: (0, _rng.withAlpha)(color, per)
|
|
183
|
+
}
|
|
184
|
+
}, i));
|
|
185
|
+
}
|
|
186
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
187
|
+
style: [{
|
|
188
|
+
width: size,
|
|
189
|
+
height: size
|
|
190
|
+
}, style],
|
|
191
|
+
pointerEvents: "none",
|
|
192
|
+
shouldRasterizeIOS: _reactNative.Platform.OS === "ios",
|
|
193
|
+
renderToHardwareTextureAndroid: _reactNative.Platform.OS === "android",
|
|
194
|
+
children: layers
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Fake linear gradient: `bands` stacked strips with linearly interpolated
|
|
200
|
+
* alpha. Used for scrims (keep text readable over a busy field) and for
|
|
201
|
+
* horizon glows. 12–16 bands is invisible as banding at these alphas.
|
|
202
|
+
*/
|
|
203
|
+
const LinearFade = exports.LinearFade = /*#__PURE__*/(0, _react.memo)(function LinearFade({
|
|
204
|
+
color,
|
|
205
|
+
from = 0,
|
|
206
|
+
to = 1,
|
|
207
|
+
bands = 14,
|
|
208
|
+
direction = "down",
|
|
209
|
+
style
|
|
210
|
+
}) {
|
|
211
|
+
const vertical = direction === "down" || direction === "up";
|
|
212
|
+
const reversed = direction === "up" || direction === "left";
|
|
213
|
+
const pct = 100 / bands;
|
|
214
|
+
const strips = [];
|
|
215
|
+
for (let i = 0; i < bands; i++) {
|
|
216
|
+
const t = (i + 0.5) / bands;
|
|
217
|
+
const a = from + (to - from) * (reversed ? 1 - t : t);
|
|
218
|
+
strips.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
219
|
+
style: vertical ? {
|
|
220
|
+
position: "absolute",
|
|
221
|
+
left: 0,
|
|
222
|
+
right: 0,
|
|
223
|
+
top: `${i * pct}%`,
|
|
224
|
+
height: `${pct + 1.2}%`,
|
|
225
|
+
backgroundColor: (0, _rng.withAlpha)(color, a)
|
|
226
|
+
} : {
|
|
227
|
+
position: "absolute",
|
|
228
|
+
top: 0,
|
|
229
|
+
bottom: 0,
|
|
230
|
+
left: `${i * pct}%`,
|
|
231
|
+
width: `${pct + 1.2}%`,
|
|
232
|
+
backgroundColor: (0, _rng.withAlpha)(color, a)
|
|
233
|
+
}
|
|
234
|
+
}, i));
|
|
235
|
+
}
|
|
236
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
237
|
+
style: [_absoluteFill.absoluteFill, style],
|
|
238
|
+
pointerEvents: "none",
|
|
239
|
+
children: strips
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Edge darkening. Four `LinearFade`s rather than a real radial vignette —
|
|
245
|
+
* cheaper, and at these alphas the corners read as round anyway.
|
|
246
|
+
*/
|
|
247
|
+
const Vignette = exports.Vignette = /*#__PURE__*/(0, _react.memo)(function Vignette({
|
|
248
|
+
color = "#000000",
|
|
249
|
+
alpha = 0.55,
|
|
250
|
+
spread = 0.34
|
|
251
|
+
}) {
|
|
252
|
+
// Each fade fills its own positioned band, rather than trying to unset
|
|
253
|
+
// `absoluteFill`'s edges through the style array.
|
|
254
|
+
const band = `${spread * 100}%`;
|
|
255
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
256
|
+
style: _absoluteFill.absoluteFill,
|
|
257
|
+
pointerEvents: "none",
|
|
258
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
259
|
+
style: {
|
|
260
|
+
position: "absolute",
|
|
261
|
+
left: 0,
|
|
262
|
+
right: 0,
|
|
263
|
+
top: 0,
|
|
264
|
+
height: band
|
|
265
|
+
},
|
|
266
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
|
|
267
|
+
color: color,
|
|
268
|
+
from: alpha,
|
|
269
|
+
to: 0,
|
|
270
|
+
direction: "down",
|
|
271
|
+
bands: 10
|
|
272
|
+
})
|
|
273
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
274
|
+
style: {
|
|
275
|
+
position: "absolute",
|
|
276
|
+
left: 0,
|
|
277
|
+
right: 0,
|
|
278
|
+
bottom: 0,
|
|
279
|
+
height: band
|
|
280
|
+
},
|
|
281
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
|
|
282
|
+
color: color,
|
|
283
|
+
from: 0,
|
|
284
|
+
to: alpha,
|
|
285
|
+
direction: "down",
|
|
286
|
+
bands: 10
|
|
287
|
+
})
|
|
288
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
289
|
+
style: {
|
|
290
|
+
position: "absolute",
|
|
291
|
+
top: 0,
|
|
292
|
+
bottom: 0,
|
|
293
|
+
left: 0,
|
|
294
|
+
width: band
|
|
295
|
+
},
|
|
296
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
|
|
297
|
+
color: color,
|
|
298
|
+
from: alpha,
|
|
299
|
+
to: 0,
|
|
300
|
+
direction: "right",
|
|
301
|
+
bands: 8
|
|
302
|
+
})
|
|
303
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
304
|
+
style: {
|
|
305
|
+
position: "absolute",
|
|
306
|
+
top: 0,
|
|
307
|
+
bottom: 0,
|
|
308
|
+
right: 0,
|
|
309
|
+
width: band
|
|
310
|
+
},
|
|
311
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LinearFade, {
|
|
312
|
+
color: color,
|
|
313
|
+
from: 0,
|
|
314
|
+
to: alpha,
|
|
315
|
+
direction: "right",
|
|
316
|
+
bands: 8
|
|
317
|
+
})
|
|
318
|
+
})]
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
/** Flat wash used as the base coat under every preset. */
|
|
323
|
+
const Base = exports.Base = /*#__PURE__*/(0, _react.memo)(function Base({
|
|
324
|
+
color
|
|
325
|
+
}) {
|
|
326
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
327
|
+
style: [_absoluteFill.absoluteFill, {
|
|
328
|
+
backgroundColor: color
|
|
329
|
+
}],
|
|
330
|
+
pointerEvents: "none"
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
const hairline = exports.hairline = _reactNative.StyleSheet.hairlineWidth;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEFAULT_BACKGROUND = exports.BACKGROUND_PRESETS = void 0;
|
|
7
|
+
exports.getPreset = getPreset;
|
|
8
|
+
exports.presetAt = presetAt;
|
|
9
|
+
exports.presetIndex = presetIndex;
|
|
10
|
+
var _lattice = require("./variants/lattice.js");
|
|
11
|
+
var _deepField = require("./variants/deepField.js");
|
|
12
|
+
var _starfield = require("./variants/starfield.js");
|
|
13
|
+
/**
|
|
14
|
+
* The catalogue. Adding a preset means adding one entry here — the switcher,
|
|
15
|
+
* the persisted selection and every tool surface read from this list.
|
|
16
|
+
*
|
|
17
|
+
* `nodes` and `views` are not decoration: they are the number of native
|
|
18
|
+
* animated nodes the preset runs and the rough count of static views it mounts,
|
|
19
|
+
* so the switcher can show what each look costs while you compare them. Keep
|
|
20
|
+
* them honest.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const BACKGROUND_PRESETS = exports.BACKGROUND_PRESETS = [{
|
|
24
|
+
id: "off",
|
|
25
|
+
label: "Off",
|
|
26
|
+
blurb: "Plain black — the baseline to compare against",
|
|
27
|
+
nodes: 0,
|
|
28
|
+
views: 1,
|
|
29
|
+
Component: null
|
|
30
|
+
}, {
|
|
31
|
+
id: "starfield",
|
|
32
|
+
label: "Starfield",
|
|
33
|
+
blurb: "Five depth bands drifting at parallax speeds",
|
|
34
|
+
nodes: 6,
|
|
35
|
+
views: 222,
|
|
36
|
+
Component: _starfield.Starfield
|
|
37
|
+
}, {
|
|
38
|
+
id: "deepfield",
|
|
39
|
+
label: "Deep Field",
|
|
40
|
+
blurb: "The Everlights field, 1:1 — 160 stars, richer but pricier",
|
|
41
|
+
nodes: 22,
|
|
42
|
+
views: 462,
|
|
43
|
+
Component: _deepField.DeepField
|
|
44
|
+
}, {
|
|
45
|
+
id: "hexmesh",
|
|
46
|
+
label: "Hex Mesh",
|
|
47
|
+
blurb: "Diamond lattice with a slow breath",
|
|
48
|
+
nodes: 1,
|
|
49
|
+
views: 160,
|
|
50
|
+
Component: _lattice.HexMesh
|
|
51
|
+
}, {
|
|
52
|
+
id: "isogrid",
|
|
53
|
+
label: "Iso Grid",
|
|
54
|
+
blurb: "Three-axis isometric ruling",
|
|
55
|
+
nodes: 1,
|
|
56
|
+
views: 66,
|
|
57
|
+
Component: _lattice.IsoGrid
|
|
58
|
+
}, {
|
|
59
|
+
id: "crosshatch",
|
|
60
|
+
label: "Crosshatch",
|
|
61
|
+
blurb: "Fine 45° weave, drafting-paper quiet",
|
|
62
|
+
nodes: 1,
|
|
63
|
+
views: 64,
|
|
64
|
+
Component: _lattice.Crosshatch
|
|
65
|
+
}, {
|
|
66
|
+
id: "perfboard",
|
|
67
|
+
label: "Perf Board",
|
|
68
|
+
blurb: "Solder-pad matrix with datum pads every fourth",
|
|
69
|
+
nodes: 1,
|
|
70
|
+
views: 150,
|
|
71
|
+
Component: _lattice.PerfBoard
|
|
72
|
+
}, {
|
|
73
|
+
id: "halftone",
|
|
74
|
+
label: "Halftone",
|
|
75
|
+
blurb: "Dot grid swelling toward the light",
|
|
76
|
+
nodes: 1,
|
|
77
|
+
views: 176,
|
|
78
|
+
Component: _lattice.Halftone
|
|
79
|
+
}, {
|
|
80
|
+
id: "waffle",
|
|
81
|
+
label: "Waffle",
|
|
82
|
+
blurb: "Machined panel of rounded cells",
|
|
83
|
+
nodes: 1,
|
|
84
|
+
views: 88,
|
|
85
|
+
Component: _lattice.Waffle
|
|
86
|
+
}, {
|
|
87
|
+
id: "instrument",
|
|
88
|
+
label: "Instrument",
|
|
89
|
+
blurb: "Ruled scales with major graduations",
|
|
90
|
+
nodes: 1,
|
|
91
|
+
views: 110,
|
|
92
|
+
Component: _lattice.Instrument
|
|
93
|
+
}, {
|
|
94
|
+
id: "radar",
|
|
95
|
+
label: "Radar",
|
|
96
|
+
blurb: "Rings and spokes under a rotating sweep",
|
|
97
|
+
nodes: 2,
|
|
98
|
+
views: 40,
|
|
99
|
+
Component: _lattice.Radar
|
|
100
|
+
}];
|
|
101
|
+
const DEFAULT_BACKGROUND = exports.DEFAULT_BACKGROUND = "hexmesh";
|
|
102
|
+
function presetIndex(id) {
|
|
103
|
+
const i = BACKGROUND_PRESETS.findIndex(p => p.id === id);
|
|
104
|
+
return i < 0 ? 0 : i;
|
|
105
|
+
}
|
|
106
|
+
function presetAt(index) {
|
|
107
|
+
const n = BACKGROUND_PRESETS.length;
|
|
108
|
+
return BACKGROUND_PRESETS[(index % n + n) % n];
|
|
109
|
+
}
|
|
110
|
+
function getPreset(id) {
|
|
111
|
+
return BACKGROUND_PRESETS[presetIndex(id)];
|
|
112
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.flattenOver = flattenOver;
|
|
7
|
+
exports.mulberry32 = mulberry32;
|
|
8
|
+
exports.scatter = scatter;
|
|
9
|
+
exports.withAlpha = withAlpha;
|
|
10
|
+
/**
|
|
11
|
+
* Deterministic scatter tables for the tool backgrounds.
|
|
12
|
+
*
|
|
13
|
+
* Every preset needs a pile of "random" positions, sizes and phases. Those are
|
|
14
|
+
* generated ONCE at module load from a fixed seed and frozen, so:
|
|
15
|
+
* - the same seed always paints the same field (screenshots are stable, and
|
|
16
|
+
* two tools showing the same background look identical),
|
|
17
|
+
* - no allocation happens on mount or on any re-render — the presets only
|
|
18
|
+
* read these arrays.
|
|
19
|
+
*
|
|
20
|
+
* Ported from the seeded field in the Everlights starfield (mulberry32).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function mulberry32(seed) {
|
|
24
|
+
return () => {
|
|
25
|
+
seed = seed + 0x6d2b79f5 | 0;
|
|
26
|
+
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
|
27
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
28
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** `count` numbers in [0,1) from `seed`. */
|
|
33
|
+
function scatter(seed, count) {
|
|
34
|
+
const rnd = mulberry32(seed >>> 0);
|
|
35
|
+
const out = new Array(count);
|
|
36
|
+
for (let i = 0; i < count; i++) out[i] = rnd();
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** `#RRGGBB` (or `#RGB`) + alpha 0..1 → `rgba(...)`. */
|
|
41
|
+
function withAlpha(hex, alpha) {
|
|
42
|
+
let h = hex.replace("#", "");
|
|
43
|
+
if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
|
|
44
|
+
const n = parseInt(h, 16);
|
|
45
|
+
const r = n >> 16 & 255;
|
|
46
|
+
const g = n >> 8 & 255;
|
|
47
|
+
const b = n & 255;
|
|
48
|
+
const a = alpha < 0 ? 0 : alpha > 1 ? 1 : alpha;
|
|
49
|
+
return `rgba(${r},${g},${b},${a.toFixed(3)})`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* `hex` at `alpha` composited over an opaque `base`, returned as an OPAQUE
|
|
54
|
+
* colour.
|
|
55
|
+
*
|
|
56
|
+
* Over a known backdrop this is pixel-identical to drawing the translucent
|
|
57
|
+
* colour — the GPU just doesn't have to blend it. Only valid where nothing
|
|
58
|
+
* else sits between the layer and `base`.
|
|
59
|
+
*/
|
|
60
|
+
function flattenOver(hex, alpha, base) {
|
|
61
|
+
const parse = h => {
|
|
62
|
+
let v = h.replace("#", "");
|
|
63
|
+
if (v.length === 3) v = v[0] + v[0] + v[1] + v[1] + v[2] + v[2];
|
|
64
|
+
const n = parseInt(v, 16);
|
|
65
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
66
|
+
};
|
|
67
|
+
const [r, g, b] = parse(hex);
|
|
68
|
+
const [br, bg, bb] = parse(base);
|
|
69
|
+
const a = alpha < 0 ? 0 : alpha > 1 ? 1 : alpha;
|
|
70
|
+
const mix = (c, bc) => Math.round(c * a + bc * (1 - a));
|
|
71
|
+
return `rgb(${mix(r, br)},${mix(g, bg)},${mix(b, bb)})`;
|
|
72
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|