@nxgt/material-core 0.12.0 → 0.13.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/CHANGELOG.md +30 -0
- package/README.md +268 -24
- package/dist/backgrounds/activity.d.ts +11 -0
- package/dist/backgrounds/activity.d.ts.map +1 -0
- package/dist/backgrounds/build.d.ts +9 -0
- package/dist/backgrounds/build.d.ts.map +1 -0
- package/dist/backgrounds/id-prefix.d.ts +8 -0
- package/dist/backgrounds/id-prefix.d.ts.map +1 -0
- package/dist/backgrounds/index.d.ts +20 -0
- package/dist/backgrounds/index.d.ts.map +1 -0
- package/dist/backgrounds/index.js +467 -0
- package/dist/backgrounds/index.js.map +20 -0
- package/dist/backgrounds/noise.d.ts +7 -0
- package/dist/backgrounds/noise.d.ts.map +1 -0
- package/dist/backgrounds/presets/grain.d.ts +9 -0
- package/dist/backgrounds/presets/grain.d.ts.map +1 -0
- package/dist/backgrounds/presets.d.ts +16 -0
- package/dist/backgrounds/presets.d.ts.map +1 -0
- package/dist/backgrounds/primitives.d.ts +22 -0
- package/dist/backgrounds/primitives.d.ts.map +1 -0
- package/dist/backgrounds/rng.d.ts +12 -0
- package/dist/backgrounds/rng.d.ts.map +1 -0
- package/dist/backgrounds/scatter.d.ts +25 -0
- package/dist/backgrounds/scatter.d.ts.map +1 -0
- package/dist/backgrounds/scene.d.ts +21 -0
- package/dist/backgrounds/scene.d.ts.map +1 -0
- package/dist/backgrounds/tones.d.ts +4 -0
- package/dist/backgrounds/tones.d.ts.map +1 -0
- package/dist/backgrounds/types.d.ts +53 -0
- package/dist/backgrounds/types.d.ts.map +1 -0
- package/dist/chunks/index-mw5fa8qa.js +119 -0
- package/dist/chunks/index-mw5fa8qa.js.map +12 -0
- package/dist/csp/index.d.ts +10 -0
- package/dist/csp/index.d.ts.map +1 -0
- package/dist/csp/index.js +21 -0
- package/dist/csp/index.js.map +9 -0
- package/dist/csp/nonce.d.ts +35 -0
- package/dist/csp/nonce.d.ts.map +1 -0
- package/dist/csp/policy.d.ts +33 -0
- package/dist/csp/policy.d.ts.map +1 -0
- package/dist/csp/zod-jitless.d.ts +4 -0
- package/dist/csp/zod-jitless.d.ts.map +1 -0
- package/dist/lib/drawer-room.d.ts +8 -0
- package/dist/lib/drawer-room.d.ts.map +1 -0
- package/dist/lib/drawer-room.js +17 -0
- package/dist/lib/drawer-room.js.map +10 -0
- package/dist/lib/escape-forward.d.ts +14 -0
- package/dist/lib/escape-forward.d.ts.map +1 -1
- package/dist/lib/escape-forward.js +22 -2
- package/dist/lib/escape-forward.js.map +3 -3
- package/dist/pdf-viewer/index.d.ts +1 -0
- package/dist/pdf-viewer/index.d.ts.map +1 -1
- package/dist/pdf-viewer/index.js +68 -38
- package/dist/pdf-viewer/index.js.map +6 -5
- package/dist/pdf-viewer/pdf-reveal-hit.d.ts +7 -0
- package/dist/pdf-viewer/pdf-reveal-hit.d.ts.map +1 -0
- package/dist/pdf-viewer/pdf-scroll-spy.d.ts +24 -8
- package/dist/pdf-viewer/pdf-scroll-spy.d.ts.map +1 -1
- package/dist/states/copy.d.ts +46 -0
- package/dist/states/copy.d.ts.map +1 -0
- package/dist/states/describe-error.d.ts +18 -0
- package/dist/states/describe-error.d.ts.map +1 -0
- package/dist/states/illustrations.d.ts +24 -0
- package/dist/states/illustrations.d.ts.map +1 -0
- package/dist/states/index.d.ts +11 -0
- package/dist/states/index.d.ts.map +1 -0
- package/dist/states/index.js +253 -0
- package/dist/states/index.js.map +13 -0
- package/dist/states/kinds.d.ts +28 -0
- package/dist/states/kinds.d.ts.map +1 -0
- package/dist/vite/csp-dev-header.d.ts +11 -0
- package/dist/vite/csp-dev-header.d.ts.map +1 -0
- package/dist/vite/csp-hashes.d.ts +23 -0
- package/dist/vite/csp-hashes.d.ts.map +1 -0
- package/dist/vite/csp-header.d.ts +10 -0
- package/dist/vite/csp-header.d.ts.map +1 -0
- package/dist/vite/csp-plugin.d.ts +12 -0
- package/dist/vite/csp-plugin.d.ts.map +1 -0
- package/dist/vite/css-chain.d.ts +13 -0
- package/dist/vite/css-chain.d.ts.map +1 -0
- package/dist/vite/dependency-closure.d.ts +8 -0
- package/dist/vite/dependency-closure.d.ts.map +1 -0
- package/dist/vite/fonts-inter.d.ts +15 -0
- package/dist/vite/fonts-inter.d.ts.map +1 -0
- package/dist/vite/fonts-plugin.d.ts +12 -0
- package/dist/vite/fonts-plugin.d.ts.map +1 -0
- package/dist/vite/index.d.ts +17 -81
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +478 -2
- package/dist/vite/index.js.map +18 -4
- package/dist/vite/libraries.d.ts +13 -0
- package/dist/vite/libraries.d.ts.map +1 -0
- package/dist/vite/nxgt-material.d.ts +12 -0
- package/dist/vite/nxgt-material.d.ts.map +1 -0
- package/dist/vite/options.d.ts +56 -0
- package/dist/vite/options.d.ts.map +1 -0
- package/dist/vite/pdf-plugin.d.ts +19 -0
- package/dist/vite/pdf-plugin.d.ts.map +1 -0
- package/dist/vite/pdfkit-standard-fonts.d.ts +74 -0
- package/dist/vite/pdfkit-standard-fonts.d.ts.map +1 -0
- package/dist/vite/styles-plugin.d.ts +27 -0
- package/dist/vite/styles-plugin.d.ts.map +1 -0
- package/dist/vite/styles-scan.d.ts +14 -0
- package/dist/vite/styles-scan.d.ts.map +1 -0
- package/docs/README.md +4 -0
- package/docs/backgrounds.md +95 -0
- package/docs/roadmap.md +34 -23
- package/docs/states.md +85 -0
- package/docs/troubleshooting.md +174 -3
- package/package.json +34 -4
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
// src/backgrounds/activity.ts
|
|
2
|
+
function observeBackgroundActivity(el, onChange) {
|
|
3
|
+
const doc = el.ownerDocument;
|
|
4
|
+
const win = doc.defaultView;
|
|
5
|
+
const motion = win?.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
6
|
+
let visible = true;
|
|
7
|
+
let last;
|
|
8
|
+
const update = () => {
|
|
9
|
+
const paused = doc.hidden || !visible || motion?.matches === true;
|
|
10
|
+
if (paused === last)
|
|
11
|
+
return;
|
|
12
|
+
last = paused;
|
|
13
|
+
onChange(paused);
|
|
14
|
+
};
|
|
15
|
+
const Observer = win?.IntersectionObserver;
|
|
16
|
+
const observer = Observer ? new Observer((entries) => {
|
|
17
|
+
const latest = entries[entries.length - 1];
|
|
18
|
+
if (!latest)
|
|
19
|
+
return;
|
|
20
|
+
visible = latest.isIntersecting;
|
|
21
|
+
update();
|
|
22
|
+
}) : undefined;
|
|
23
|
+
observer?.observe(el);
|
|
24
|
+
doc.addEventListener("visibilitychange", update);
|
|
25
|
+
motion?.addEventListener?.("change", update);
|
|
26
|
+
update();
|
|
27
|
+
return () => {
|
|
28
|
+
observer?.disconnect();
|
|
29
|
+
doc.removeEventListener("visibilitychange", update);
|
|
30
|
+
motion?.removeEventListener?.("change", update);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// src/backgrounds/scene.ts
|
|
34
|
+
var SCENE_TAGS = [
|
|
35
|
+
"svg",
|
|
36
|
+
"g",
|
|
37
|
+
"path",
|
|
38
|
+
"circle",
|
|
39
|
+
"rect",
|
|
40
|
+
"ellipse",
|
|
41
|
+
"line",
|
|
42
|
+
"polygon",
|
|
43
|
+
"defs",
|
|
44
|
+
"pattern",
|
|
45
|
+
"linearGradient",
|
|
46
|
+
"radialGradient",
|
|
47
|
+
"stop",
|
|
48
|
+
"filter",
|
|
49
|
+
"feTurbulence",
|
|
50
|
+
"feColorMatrix",
|
|
51
|
+
"feGaussianBlur",
|
|
52
|
+
"mask"
|
|
53
|
+
];
|
|
54
|
+
var SCENE_ATTRIBUTES = Object.freeze([
|
|
55
|
+
"id",
|
|
56
|
+
"class",
|
|
57
|
+
"aria-hidden",
|
|
58
|
+
"focusable",
|
|
59
|
+
"viewBox",
|
|
60
|
+
"preserveAspectRatio",
|
|
61
|
+
"x",
|
|
62
|
+
"y",
|
|
63
|
+
"width",
|
|
64
|
+
"height",
|
|
65
|
+
"cx",
|
|
66
|
+
"cy",
|
|
67
|
+
"r",
|
|
68
|
+
"rx",
|
|
69
|
+
"ry",
|
|
70
|
+
"x1",
|
|
71
|
+
"y1",
|
|
72
|
+
"x2",
|
|
73
|
+
"y2",
|
|
74
|
+
"d",
|
|
75
|
+
"points",
|
|
76
|
+
"transform",
|
|
77
|
+
"fill",
|
|
78
|
+
"stroke",
|
|
79
|
+
"stroke-width",
|
|
80
|
+
"stroke-linecap",
|
|
81
|
+
"stroke-linejoin",
|
|
82
|
+
"stroke-dasharray",
|
|
83
|
+
"stroke-dashoffset",
|
|
84
|
+
"fill-rule",
|
|
85
|
+
"clip-rule",
|
|
86
|
+
"opacity",
|
|
87
|
+
"fill-opacity",
|
|
88
|
+
"stroke-opacity",
|
|
89
|
+
"filter",
|
|
90
|
+
"mask",
|
|
91
|
+
"offset",
|
|
92
|
+
"gradientUnits",
|
|
93
|
+
"gradientTransform",
|
|
94
|
+
"patternUnits",
|
|
95
|
+
"patternContentUnits",
|
|
96
|
+
"patternTransform",
|
|
97
|
+
"maskUnits",
|
|
98
|
+
"maskContentUnits",
|
|
99
|
+
"fx",
|
|
100
|
+
"fy",
|
|
101
|
+
"spreadMethod",
|
|
102
|
+
"filterUnits",
|
|
103
|
+
"primitiveUnits",
|
|
104
|
+
"in",
|
|
105
|
+
"in2",
|
|
106
|
+
"result",
|
|
107
|
+
"type",
|
|
108
|
+
"values",
|
|
109
|
+
"baseFrequency",
|
|
110
|
+
"numOctaves",
|
|
111
|
+
"seed",
|
|
112
|
+
"stitchTiles",
|
|
113
|
+
"stdDeviation"
|
|
114
|
+
]);
|
|
115
|
+
var ALLOWED_ATTRIBUTES = new Set(SCENE_ATTRIBUTES);
|
|
116
|
+
var SAFE_ID = /^[A-Za-z][A-Za-z0-9_-]*$/;
|
|
117
|
+
var SAFE_CLASS = /^[A-Za-z0-9_ -]+$/;
|
|
118
|
+
var hasUnsafeChar = (value) => /[<>\\@;]/.test(value) || [...value].some((c) => c.charCodeAt(0) < 32);
|
|
119
|
+
var URL_REF = /url\(\s*([^)]*?)\s*\)/gi;
|
|
120
|
+
var SCHEME = /(?:javascript|data|https?|file):/i;
|
|
121
|
+
function check(node, path, prefix, ids, refs) {
|
|
122
|
+
const where = `${path}${path ? ">" : ""}${node.tag}`;
|
|
123
|
+
const fail = (why) => {
|
|
124
|
+
throw new Error(`Unsafe background scene at ${where}: ${why}`);
|
|
125
|
+
};
|
|
126
|
+
if (!SCENE_TAGS.includes(node.tag))
|
|
127
|
+
fail(`tag "${node.tag}" is not allowed`);
|
|
128
|
+
for (const [name, value] of Object.entries(node.attrs)) {
|
|
129
|
+
if (!ALLOWED_ATTRIBUTES.has(name))
|
|
130
|
+
fail(`attribute "${name}" is not allowed`);
|
|
131
|
+
if (typeof value === "number") {
|
|
132
|
+
if (!Number.isFinite(value))
|
|
133
|
+
fail(`attribute "${name}" is not finite`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (hasUnsafeChar(value))
|
|
137
|
+
fail(`attribute "${name}" has a markup, escape or control character`);
|
|
138
|
+
if (name === "id") {
|
|
139
|
+
if (!SAFE_ID.test(value))
|
|
140
|
+
fail(`id "${value}" has unsafe characters`);
|
|
141
|
+
if (prefix && !value.startsWith(`${prefix}-`))
|
|
142
|
+
fail(`id "${value}" lacks the prefix "${prefix}-"`);
|
|
143
|
+
if (ids.has(value))
|
|
144
|
+
fail(`id "${value}" is used twice`);
|
|
145
|
+
ids.add(value);
|
|
146
|
+
} else if (name === "class") {
|
|
147
|
+
if (!SAFE_CLASS.test(value))
|
|
148
|
+
fail(`class "${value}" has unsafe characters`);
|
|
149
|
+
}
|
|
150
|
+
const outside = value.replace(URL_REF, "");
|
|
151
|
+
if (SCHEME.test(outside) || /url\s*\(/i.test(outside)) {
|
|
152
|
+
fail(`attribute "${name}" holds a URL`);
|
|
153
|
+
}
|
|
154
|
+
for (const m of value.matchAll(URL_REF)) {
|
|
155
|
+
const target = m[1] ?? "";
|
|
156
|
+
if (!target.startsWith("#") || !SAFE_ID.test(target.slice(1))) {
|
|
157
|
+
fail(`attribute "${name}" has a url() that is not a local id`);
|
|
158
|
+
}
|
|
159
|
+
refs.push({ path: where, id: target.slice(1) });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
for (const child of node.children ?? [])
|
|
163
|
+
check(child, where, prefix, ids, refs);
|
|
164
|
+
}
|
|
165
|
+
function assertSafeScene(root, idPrefix) {
|
|
166
|
+
const ids = new Set;
|
|
167
|
+
const refs = [];
|
|
168
|
+
check(root, "", idPrefix, ids, refs);
|
|
169
|
+
for (const ref of refs) {
|
|
170
|
+
if (!ids.has(ref.id)) {
|
|
171
|
+
throw new Error(`Unsafe background scene at ${ref.path}: url(#${ref.id}) points to no element of the scene`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function el(tag, attrs = {}, children) {
|
|
176
|
+
return children ? { tag, attrs, children } : { tag, attrs };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/backgrounds/presets/grain.ts
|
|
180
|
+
function buildGrain({ idPrefix, seed = 0 }) {
|
|
181
|
+
const filter = `${idPrefix}-noise`;
|
|
182
|
+
return el("svg", {
|
|
183
|
+
viewBox: "0 0 1600 1000",
|
|
184
|
+
preserveAspectRatio: "xMidYMid slice",
|
|
185
|
+
"aria-hidden": "true",
|
|
186
|
+
focusable: "false"
|
|
187
|
+
}, [
|
|
188
|
+
el("defs", {}, [
|
|
189
|
+
el("filter", { id: filter, x: 0, y: 0, width: "100%", height: "100%" }, [
|
|
190
|
+
el("feTurbulence", {
|
|
191
|
+
type: "fractalNoise",
|
|
192
|
+
baseFrequency: 0.8,
|
|
193
|
+
numOctaves: 3,
|
|
194
|
+
seed: Math.trunc(Number.isFinite(seed) ? seed : 0),
|
|
195
|
+
stitchTiles: "stitch"
|
|
196
|
+
}),
|
|
197
|
+
el("feColorMatrix", { type: "saturate", values: 0 })
|
|
198
|
+
])
|
|
199
|
+
]),
|
|
200
|
+
el("rect", {
|
|
201
|
+
width: 1600,
|
|
202
|
+
height: 1000,
|
|
203
|
+
filter: `url(#${filter})`
|
|
204
|
+
})
|
|
205
|
+
]);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/backgrounds/build.ts
|
|
209
|
+
var BUILDERS = {
|
|
210
|
+
grain: buildGrain
|
|
211
|
+
};
|
|
212
|
+
function buildBackgroundScene(preset, opts) {
|
|
213
|
+
const scene = BUILDERS[preset]?.({ ...opts, seed: opts.seed ?? 0 }) ?? null;
|
|
214
|
+
if (scene)
|
|
215
|
+
assertSafeScene(scene, opts.idPrefix);
|
|
216
|
+
return scene;
|
|
217
|
+
}
|
|
218
|
+
// src/backgrounds/id-prefix.ts
|
|
219
|
+
function svgIdPrefix(raw) {
|
|
220
|
+
const cleaned = raw.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
221
|
+
return cleaned ? `bg-${cleaned}` : "bg";
|
|
222
|
+
}
|
|
223
|
+
// src/backgrounds/noise.ts
|
|
224
|
+
function valueNoise2(rand, lx, ly, width, height) {
|
|
225
|
+
const lattice = Array.from({ length: (lx + 1) * (ly + 1) }, rand);
|
|
226
|
+
const at = (i, j) => lattice[j * (lx + 1) + i];
|
|
227
|
+
const lerp = (a, b, t) => a + (b - a) * t;
|
|
228
|
+
const smooth = (t) => t * t * (3 - 2 * t);
|
|
229
|
+
return (x, y) => {
|
|
230
|
+
const gx = Math.min(lx - 0.000001, Math.max(0, x / width * lx));
|
|
231
|
+
const gy = Math.min(ly - 0.000001, Math.max(0, y / height * ly));
|
|
232
|
+
const ix = Math.floor(gx);
|
|
233
|
+
const iy = Math.floor(gy);
|
|
234
|
+
const fx = smooth(gx - ix);
|
|
235
|
+
const fy = smooth(gy - iy);
|
|
236
|
+
return lerp(lerp(at(ix, iy), at(ix + 1, iy), fx), lerp(at(ix, iy + 1), at(ix + 1, iy + 1), fx), fy);
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
// src/backgrounds/presets.ts
|
|
240
|
+
var ALL_MOTIF = [
|
|
241
|
+
"shapes",
|
|
242
|
+
"density",
|
|
243
|
+
"size",
|
|
244
|
+
"opacitySpread",
|
|
245
|
+
"rotate",
|
|
246
|
+
"shapeFill"
|
|
247
|
+
];
|
|
248
|
+
var light = (id, kind, seeded = false) => ({ id, family: "light", kind, seeded, motifControls: [] });
|
|
249
|
+
var geometry = (id, kind, seeded = false) => ({ id, family: "geometry", kind, seeded, motifControls: [] });
|
|
250
|
+
var motif = (id, motifControls) => ({
|
|
251
|
+
id,
|
|
252
|
+
family: "motif",
|
|
253
|
+
kind: "svg",
|
|
254
|
+
seeded: true,
|
|
255
|
+
motifControls
|
|
256
|
+
});
|
|
257
|
+
var BACKGROUND_PRESETS = [
|
|
258
|
+
light("gradient", "css"),
|
|
259
|
+
light("mesh", "css"),
|
|
260
|
+
light("aurora", "css+svg"),
|
|
261
|
+
light("spotlight", "css+svg"),
|
|
262
|
+
light("bokeh", "css+svg", true),
|
|
263
|
+
light("grain", "css+svg"),
|
|
264
|
+
geometry("isometric", "css+svg"),
|
|
265
|
+
geometry("blueprint", "css+svg"),
|
|
266
|
+
geometry("dots", "css"),
|
|
267
|
+
geometry("stripes", "css"),
|
|
268
|
+
geometry("low-poly", "css+svg", true),
|
|
269
|
+
geometry("topography", "css+svg", true),
|
|
270
|
+
geometry("waves", "css+svg"),
|
|
271
|
+
motif("shapes", ALL_MOTIF),
|
|
272
|
+
motif("confetti-grid", ALL_MOTIF),
|
|
273
|
+
motif("constellation", ["density", "size", "opacitySpread"]),
|
|
274
|
+
motif("halftone", ["shapes", "density", "size", "shapeFill"]),
|
|
275
|
+
motif("truchet", ["shapes", "density", "size", "opacitySpread"]),
|
|
276
|
+
motif("floating", [
|
|
277
|
+
"shapes",
|
|
278
|
+
"density",
|
|
279
|
+
"size",
|
|
280
|
+
"opacitySpread",
|
|
281
|
+
"shapeFill"
|
|
282
|
+
]),
|
|
283
|
+
motif("scatter-icons", ["density", "size", "opacitySpread", "rotate"])
|
|
284
|
+
];
|
|
285
|
+
var SHIPPED_BACKGROUND_PRESETS = [
|
|
286
|
+
"gradient",
|
|
287
|
+
"grain"
|
|
288
|
+
];
|
|
289
|
+
var warned = new Set;
|
|
290
|
+
function resolveShippedPreset(preset) {
|
|
291
|
+
if (SHIPPED_BACKGROUND_PRESETS.includes(preset)) {
|
|
292
|
+
return preset;
|
|
293
|
+
}
|
|
294
|
+
const production = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
295
|
+
if (!production && !warned.has(preset)) {
|
|
296
|
+
warned.add(preset);
|
|
297
|
+
console.warn(`Background: preset "${preset}" is not available yet; drawing "gradient".`);
|
|
298
|
+
}
|
|
299
|
+
return "gradient";
|
|
300
|
+
}
|
|
301
|
+
// src/backgrounds/rng.ts
|
|
302
|
+
function mulberry32(seed) {
|
|
303
|
+
let a = Math.trunc(seed) * 2654435761 >>> 0 || 1;
|
|
304
|
+
return () => {
|
|
305
|
+
a = a + 1831565813 | 0;
|
|
306
|
+
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
307
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
308
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function pick(rand, items) {
|
|
312
|
+
return items[Math.floor(rand() * items.length)];
|
|
313
|
+
}
|
|
314
|
+
function round1(n) {
|
|
315
|
+
return Math.round(n * 10) / 10;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/backgrounds/primitives.ts
|
|
319
|
+
var MOTIF_SHAPES = [
|
|
320
|
+
"circle",
|
|
321
|
+
"ring",
|
|
322
|
+
"square",
|
|
323
|
+
"triangle",
|
|
324
|
+
"plus",
|
|
325
|
+
"line",
|
|
326
|
+
"arc"
|
|
327
|
+
];
|
|
328
|
+
var MOTIF_DEFAULTS = {
|
|
329
|
+
shapes: MOTIF_SHAPES,
|
|
330
|
+
density: "default",
|
|
331
|
+
size: "mixed",
|
|
332
|
+
rotate: true,
|
|
333
|
+
shapeFill: "mixed",
|
|
334
|
+
opacitySpread: "varied"
|
|
335
|
+
};
|
|
336
|
+
function motifShape(shape, s, filled) {
|
|
337
|
+
const sw = round1(Math.max(1.6, s * 0.1));
|
|
338
|
+
const fillAttrs = filled ? { fill: "currentColor" } : {
|
|
339
|
+
fill: "none",
|
|
340
|
+
stroke: "currentColor",
|
|
341
|
+
"stroke-width": sw,
|
|
342
|
+
"stroke-linejoin": "round"
|
|
343
|
+
};
|
|
344
|
+
const stroke = (w) => ({
|
|
345
|
+
fill: "none",
|
|
346
|
+
stroke: "currentColor",
|
|
347
|
+
"stroke-width": round1(w),
|
|
348
|
+
"stroke-linecap": "round"
|
|
349
|
+
});
|
|
350
|
+
const k = (n) => round1(s * n);
|
|
351
|
+
switch (shape) {
|
|
352
|
+
case "circle":
|
|
353
|
+
return el("circle", { r: round1(s), ...fillAttrs });
|
|
354
|
+
case "ring":
|
|
355
|
+
return el("circle", {
|
|
356
|
+
r: k(0.8),
|
|
357
|
+
...stroke(filled ? Math.max(2.4, s * 0.3) : sw)
|
|
358
|
+
});
|
|
359
|
+
case "square":
|
|
360
|
+
return el("rect", {
|
|
361
|
+
x: k(-0.84),
|
|
362
|
+
y: k(-0.84),
|
|
363
|
+
width: k(1.68),
|
|
364
|
+
height: k(1.68),
|
|
365
|
+
rx: k(0.3),
|
|
366
|
+
...fillAttrs
|
|
367
|
+
});
|
|
368
|
+
case "triangle":
|
|
369
|
+
return el("path", {
|
|
370
|
+
d: `M0 ${k(-1)}L${k(0.92)} ${k(0.62)}L${k(-0.92)} ${k(0.62)}Z`,
|
|
371
|
+
...fillAttrs
|
|
372
|
+
});
|
|
373
|
+
case "plus":
|
|
374
|
+
return el("path", {
|
|
375
|
+
d: `M${k(-0.78)} 0H${k(0.78)}M0 ${k(-0.78)}V${k(0.78)}`,
|
|
376
|
+
...stroke(filled ? Math.max(2.4, s * 0.32) : sw)
|
|
377
|
+
});
|
|
378
|
+
case "line":
|
|
379
|
+
return el("rect", {
|
|
380
|
+
x: k(-1),
|
|
381
|
+
y: k(-0.17),
|
|
382
|
+
width: k(2),
|
|
383
|
+
height: k(0.34),
|
|
384
|
+
rx: k(0.17),
|
|
385
|
+
...fillAttrs
|
|
386
|
+
});
|
|
387
|
+
default: {
|
|
388
|
+
const arc = `M${k(-1)} ${k(0.4)}A${k(1)} ${k(1)} 0 0 1 ${k(1)} ${k(0.4)}`;
|
|
389
|
+
return filled ? el("path", { d: `${arc}Z`, ...fillAttrs }) : el("path", { d: arc, ...stroke(Math.max(1.8, s * 0.16)) });
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function place(opts, inner) {
|
|
394
|
+
const turn = opts.rotation ? ` rotate(${round1(opts.rotation)})` : "";
|
|
395
|
+
return el("g", {
|
|
396
|
+
transform: `translate(${round1(opts.x)} ${round1(opts.y)})${turn}`,
|
|
397
|
+
class: opts.className,
|
|
398
|
+
opacity: Math.round(opts.opacity * 100) / 100
|
|
399
|
+
}, [inner]);
|
|
400
|
+
}
|
|
401
|
+
// src/backgrounds/scatter.ts
|
|
402
|
+
function scatter(rand, sizes, {
|
|
403
|
+
width = 1600,
|
|
404
|
+
height = 1000,
|
|
405
|
+
gap = 1.12,
|
|
406
|
+
pad = 10,
|
|
407
|
+
margin = 40,
|
|
408
|
+
attempts = 40
|
|
409
|
+
} = {}) {
|
|
410
|
+
const out = [];
|
|
411
|
+
for (const s of [...sizes].sort((a, b) => b - a)) {
|
|
412
|
+
for (let t = 0;t < attempts; t++) {
|
|
413
|
+
const x = -margin + rand() * (width + 2 * margin);
|
|
414
|
+
const y = -margin + rand() * (height + 2 * margin);
|
|
415
|
+
if (out.every((p) => Math.hypot(p.x - x, p.y - y) >= (p.s + s) * gap + pad)) {
|
|
416
|
+
out.push({ x, y, s });
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return out;
|
|
422
|
+
}
|
|
423
|
+
// src/backgrounds/tones.ts
|
|
424
|
+
var BACKGROUND_TONES = [
|
|
425
|
+
"primary",
|
|
426
|
+
"secondary",
|
|
427
|
+
"tertiary",
|
|
428
|
+
"neutral",
|
|
429
|
+
"success",
|
|
430
|
+
"warning",
|
|
431
|
+
"error",
|
|
432
|
+
"info",
|
|
433
|
+
"mixed",
|
|
434
|
+
"custom"
|
|
435
|
+
];
|
|
436
|
+
var BACKGROUND_INTENSITIES = [
|
|
437
|
+
"subtle",
|
|
438
|
+
"default",
|
|
439
|
+
"vivid"
|
|
440
|
+
];
|
|
441
|
+
export {
|
|
442
|
+
BACKGROUND_INTENSITIES,
|
|
443
|
+
BACKGROUND_PRESETS,
|
|
444
|
+
BACKGROUND_TONES,
|
|
445
|
+
MOTIF_DEFAULTS,
|
|
446
|
+
MOTIF_SHAPES,
|
|
447
|
+
SCENE_ATTRIBUTES,
|
|
448
|
+
SCENE_TAGS,
|
|
449
|
+
SHIPPED_BACKGROUND_PRESETS,
|
|
450
|
+
assertSafeScene,
|
|
451
|
+
buildBackgroundScene,
|
|
452
|
+
buildGrain,
|
|
453
|
+
el,
|
|
454
|
+
motifShape,
|
|
455
|
+
mulberry32,
|
|
456
|
+
observeBackgroundActivity,
|
|
457
|
+
pick,
|
|
458
|
+
place,
|
|
459
|
+
resolveShippedPreset,
|
|
460
|
+
round1,
|
|
461
|
+
scatter,
|
|
462
|
+
svgIdPrefix,
|
|
463
|
+
valueNoise2
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
//# debugId=9BBF7513D8A7900264756E2164756E21
|
|
467
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/backgrounds/activity.ts", "../src/backgrounds/scene.ts", "../src/backgrounds/presets/grain.ts", "../src/backgrounds/build.ts", "../src/backgrounds/id-prefix.ts", "../src/backgrounds/noise.ts", "../src/backgrounds/presets.ts", "../src/backgrounds/rng.ts", "../src/backgrounds/primitives.ts", "../src/backgrounds/scatter.ts", "../src/backgrounds/tones.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Tells `onChange` whether an animated background should be paused: the page\n * is hidden, the element is off screen, or the user prefers reduced motion.\n * Calls `onChange` once with the current state, then on each change only.\n * Returns the function that removes every listener and observer.\n *\n * Reads the DOM when called, never at import: call it from an effect or\n * `onMounted`, and only when the background is `animated`.\n */\nexport function observeBackgroundActivity(\n\tel: Element,\n\tonChange: (paused: boolean) => void,\n): () => void {\n\tconst doc = el.ownerDocument;\n\tconst win = doc.defaultView;\n\tconst motion = win?.matchMedia?.('(prefers-reduced-motion: reduce)');\n\tlet visible = true;\n\tlet last: boolean | undefined;\n\n\tconst update = () => {\n\t\tconst paused = doc.hidden || !visible || motion?.matches === true;\n\t\tif (paused === last) return;\n\t\tlast = paused;\n\t\tonChange(paused);\n\t};\n\n\tconst Observer = win?.IntersectionObserver;\n\tconst observer = Observer\n\t\t? new Observer((entries) => {\n\t\t\t\tconst latest = entries[entries.length - 1];\n\t\t\t\tif (!latest) return;\n\t\t\t\tvisible = latest.isIntersecting;\n\t\t\t\tupdate();\n\t\t\t})\n\t\t: undefined;\n\tobserver?.observe(el);\n\tdoc.addEventListener('visibilitychange', update);\n\tmotion?.addEventListener?.('change', update);\n\tupdate();\n\n\treturn () => {\n\t\tobserver?.disconnect();\n\t\tdoc.removeEventListener('visibilitychange', update);\n\t\tmotion?.removeEventListener?.('change', update);\n\t};\n}\n",
|
|
6
|
+
"import type { SceneNode, SceneTag } from './types';\n\nexport const SCENE_TAGS: readonly SceneTag[] = [\n\t'svg',\n\t'g',\n\t'path',\n\t'circle',\n\t'rect',\n\t'ellipse',\n\t'line',\n\t'polygon',\n\t'defs',\n\t'pattern',\n\t'linearGradient',\n\t'radialGradient',\n\t'stop',\n\t'filter',\n\t'feTurbulence',\n\t'feColorMatrix',\n\t'feGaussianBlur',\n\t'mask',\n];\n\n/**\n * The attributes a scene may carry: geometry and presentation ones. Never\n * `style` (it would reach the markup as a `style=` attribute, which a strict\n * Content Security Policy blocks), an `on*` handler or an `href`. Colours come\n * from classes, so none of the colour attributes is needed.\n */\nexport const SCENE_ATTRIBUTES: readonly string[] = Object.freeze([\n\t// structure\n\t'id',\n\t'class',\n\t'aria-hidden',\n\t'focusable',\n\t'viewBox',\n\t'preserveAspectRatio',\n\t// geometry\n\t'x',\n\t'y',\n\t'width',\n\t'height',\n\t'cx',\n\t'cy',\n\t'r',\n\t'rx',\n\t'ry',\n\t'x1',\n\t'y1',\n\t'x2',\n\t'y2',\n\t'd',\n\t'points',\n\t'transform',\n\t// presentation\n\t'fill',\n\t'stroke',\n\t'stroke-width',\n\t'stroke-linecap',\n\t'stroke-linejoin',\n\t'stroke-dasharray',\n\t'stroke-dashoffset',\n\t'fill-rule',\n\t'clip-rule',\n\t'opacity',\n\t'fill-opacity',\n\t'stroke-opacity',\n\t'filter',\n\t'mask',\n\t// gradients, patterns, masks\n\t'offset',\n\t'gradientUnits',\n\t'gradientTransform',\n\t'patternUnits',\n\t'patternContentUnits',\n\t'patternTransform',\n\t'maskUnits',\n\t'maskContentUnits',\n\t'fx',\n\t'fy',\n\t'spreadMethod',\n\t// filters\n\t'filterUnits',\n\t'primitiveUnits',\n\t'in',\n\t'in2',\n\t'result',\n\t'type',\n\t'values',\n\t'baseFrequency',\n\t'numOctaves',\n\t'seed',\n\t'stitchTiles',\n\t'stdDeviation',\n]);\n\nconst ALLOWED_ATTRIBUTES: ReadonlySet<string> = new Set(SCENE_ATTRIBUTES);\n\nconst SAFE_ID = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst SAFE_CLASS = /^[A-Za-z0-9_ -]+$/;\n/** Markup, a backslash (CSS escape), `@`, `;`, or a control character (below space). */\nconst hasUnsafeChar = (value: string) =>\n\t/[<>\\\\@;]/.test(value) || [...value].some((c) => c.charCodeAt(0) < 32);\nconst URL_REF = /url\\(\\s*([^)]*?)\\s*\\)/gi;\nconst SCHEME = /(?:javascript|data|https?|file):/i;\n\n/** Checks one node and its children, collecting the ids and the `url(#…)` references. */\nfunction check(\n\tnode: SceneNode,\n\tpath: string,\n\tprefix: string | undefined,\n\tids: Set<string>,\n\trefs: { path: string; id: string }[],\n): void {\n\tconst where = `${path}${path ? '>' : ''}${node.tag}`;\n\tconst fail = (why: string): never => {\n\t\tthrow new Error(`Unsafe background scene at ${where}: ${why}`);\n\t};\n\tif (!SCENE_TAGS.includes(node.tag)) fail(`tag \"${node.tag}\" is not allowed`);\n\tfor (const [name, value] of Object.entries(node.attrs)) {\n\t\tif (!ALLOWED_ATTRIBUTES.has(name))\n\t\t\tfail(`attribute \"${name}\" is not allowed`);\n\t\tif (typeof value === 'number') {\n\t\t\tif (!Number.isFinite(value)) fail(`attribute \"${name}\" is not finite`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (hasUnsafeChar(value))\n\t\t\tfail(`attribute \"${name}\" has a markup, escape or control character`);\n\t\tif (name === 'id') {\n\t\t\tif (!SAFE_ID.test(value)) fail(`id \"${value}\" has unsafe characters`);\n\t\t\tif (prefix && !value.startsWith(`${prefix}-`))\n\t\t\t\tfail(`id \"${value}\" lacks the prefix \"${prefix}-\"`);\n\t\t\tif (ids.has(value)) fail(`id \"${value}\" is used twice`);\n\t\t\tids.add(value);\n\t\t} else if (name === 'class') {\n\t\t\tif (!SAFE_CLASS.test(value))\n\t\t\t\tfail(`class \"${value}\" has unsafe characters`);\n\t\t}\n\t\tconst outside = value.replace(URL_REF, '');\n\t\tif (SCHEME.test(outside) || /url\\s*\\(/i.test(outside)) {\n\t\t\tfail(`attribute \"${name}\" holds a URL`);\n\t\t}\n\t\tfor (const m of value.matchAll(URL_REF)) {\n\t\t\tconst target = m[1] ?? '';\n\t\t\tif (!target.startsWith('#') || !SAFE_ID.test(target.slice(1))) {\n\t\t\t\tfail(`attribute \"${name}\" has a url() that is not a local id`);\n\t\t\t}\n\t\t\trefs.push({ path: where, id: target.slice(1) });\n\t\t}\n\t}\n\tfor (const child of node.children ?? [])\n\t\tcheck(child, where, prefix, ids, refs);\n}\n\n/**\n * Throws when a scene holds anything but the allowed tags and attributes: a\n * `style`, an `on*` handler, an `href`, a URL in a value, a `url(…)` that is\n * not the local id of an element of the same scene, an id or class with\n * unusual characters, a number that is not finite. With `idPrefix`, every id\n * must start with `<idPrefix>-`. Builders are tested against it, and the\n * libraries may call it in development.\n */\nexport function assertSafeScene(root: SceneNode, idPrefix?: string): void {\n\tconst ids = new Set<string>();\n\tconst refs: { path: string; id: string }[] = [];\n\tcheck(root, '', idPrefix, ids, refs);\n\tfor (const ref of refs) {\n\t\tif (!ids.has(ref.id)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Unsafe background scene at ${ref.path}: url(#${ref.id}) points to no element of the scene`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** A scene element. */\nexport function el(\n\ttag: SceneTag,\n\tattrs: SceneNode['attrs'] = {},\n\tchildren?: readonly SceneNode[],\n): SceneNode {\n\treturn children ? { tag, attrs, children } : { tag, attrs };\n}\n",
|
|
7
|
+
"import { el } from '../scene';\nimport type { SceneNode, SceneOptions } from '../types';\n\n/**\n * The grain: film noise from an `feTurbulence` filter, turned grey and drawn on\n * one rect. It is an overlay (the library draws it above the preset's layers,\n * with `mix-blend-mode` and an opacity set by the CSS), so it paints no colour\n * of its own. The `seed` moves the noise; the look may still change.\n */\nexport function buildGrain({ idPrefix, seed = 0 }: SceneOptions): SceneNode {\n\tconst filter = `${idPrefix}-noise`;\n\treturn el(\n\t\t'svg',\n\t\t{\n\t\t\tviewBox: '0 0 1600 1000',\n\t\t\tpreserveAspectRatio: 'xMidYMid slice',\n\t\t\t'aria-hidden': 'true',\n\t\t\tfocusable: 'false',\n\t\t},\n\t\t[\n\t\t\tel('defs', {}, [\n\t\t\t\tel(\n\t\t\t\t\t'filter',\n\t\t\t\t\t{ id: filter, x: 0, y: 0, width: '100%', height: '100%' },\n\t\t\t\t\t[\n\t\t\t\t\t\tel('feTurbulence', {\n\t\t\t\t\t\t\ttype: 'fractalNoise',\n\t\t\t\t\t\t\tbaseFrequency: 0.8,\n\t\t\t\t\t\t\tnumOctaves: 3,\n\t\t\t\t\t\t\tseed: Math.trunc(Number.isFinite(seed) ? seed : 0),\n\t\t\t\t\t\t\tstitchTiles: 'stitch',\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tel('feColorMatrix', { type: 'saturate', values: 0 }),\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t\t]),\n\t\t\tel('rect', {\n\t\t\t\twidth: 1600,\n\t\t\t\theight: 1000,\n\t\t\t\tfilter: `url(#${filter})`,\n\t\t\t}),\n\t\t],\n\t);\n}\n",
|
|
8
|
+
"import { buildGrain } from './presets/grain';\nimport { assertSafeScene } from './scene';\nimport type {\n\tBackgroundPreset,\n\tSceneBuilder,\n\tSceneNode,\n\tSceneOptions,\n} from './types';\n\n/**\n * The scene builders by preset: each builder is its own module under\n * `presets/`, registered here as it is built. `grain` is the film-noise\n * overlay, which the libraries also draw over any other preset (`grain`).\n */\nconst BUILDERS: Partial<Record<BackgroundPreset, SceneBuilder>> = {\n\tgrain: buildGrain,\n};\n\n/**\n * The SVG scene of a preset, or `null` when it has none (the CSS-only\n * presets, and a preset whose builder is not there yet). The same `seed`\n * always gives the same scene. The scene is checked with `assertSafeScene`\n * before it is returned.\n */\nexport function buildBackgroundScene(\n\tpreset: BackgroundPreset,\n\topts: SceneOptions,\n): SceneNode | null {\n\tconst scene = BUILDERS[preset]?.({ ...opts, seed: opts.seed ?? 0 }) ?? null;\n\tif (scene) assertSafeScene(scene, opts.idPrefix);\n\treturn scene;\n}\n",
|
|
9
|
+
"/**\n * Turns a framework's generated id (React's `useId` gives `:r1:` or `«r1»`,\n * Vue's `v-0`) into a prefix that is safe inside `url(#…)` and as an `id`:\n * only `A-Z a-z 0-9 _ -`, and a letter first. Ids in a scene are\n * `<prefix>-<name>`.\n */\nexport function svgIdPrefix(raw: string): string {\n\tconst cleaned = raw.replace(/[^A-Za-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '');\n\treturn cleaned ? `bg-${cleaned}` : 'bg';\n}\n",
|
|
10
|
+
"/**\n * Smooth value noise over a `width` × `height` box, from a lattice of\n * `lx` × `ly` cells filled with `rand`: returns a function from a point to a\n * value in [0, 1]. Points outside the box clamp to its edge.\n */\nexport function valueNoise2(\n\trand: () => number,\n\tlx: number,\n\tly: number,\n\twidth: number,\n\theight: number,\n): (x: number, y: number) => number {\n\tconst lattice = Array.from({ length: (lx + 1) * (ly + 1) }, rand);\n\tconst at = (i: number, j: number) => lattice[j * (lx + 1) + i] as number; // in range: i <= lx, j <= ly\n\tconst lerp = (a: number, b: number, t: number) => a + (b - a) * t;\n\tconst smooth = (t: number) => t * t * (3 - 2 * t);\n\treturn (x, y) => {\n\t\tconst gx = Math.min(lx - 1e-6, Math.max(0, (x / width) * lx));\n\t\tconst gy = Math.min(ly - 1e-6, Math.max(0, (y / height) * ly));\n\t\tconst ix = Math.floor(gx);\n\t\tconst iy = Math.floor(gy);\n\t\tconst fx = smooth(gx - ix);\n\t\tconst fy = smooth(gy - iy);\n\t\treturn lerp(\n\t\t\tlerp(at(ix, iy), at(ix + 1, iy), fx),\n\t\t\tlerp(at(ix, iy + 1), at(ix + 1, iy + 1), fx),\n\t\t\tfy,\n\t\t);\n\t};\n}\n",
|
|
11
|
+
"import type {\n\tBackgroundPreset,\n\tMotifOptions,\n\tPresetInfo,\n\tShippedBackgroundPreset,\n} from './types';\n\nconst ALL_MOTIF: readonly (keyof MotifOptions)[] = [\n\t'shapes',\n\t'density',\n\t'size',\n\t'opacitySpread',\n\t'rotate',\n\t'shapeFill',\n];\n\nconst light = (\n\tid: BackgroundPreset,\n\tkind: PresetInfo['kind'],\n\tseeded = false,\n): PresetInfo => ({ id, family: 'light', kind, seeded, motifControls: [] });\n\nconst geometry = (\n\tid: BackgroundPreset,\n\tkind: PresetInfo['kind'],\n\tseeded = false,\n): PresetInfo => ({ id, family: 'geometry', kind, seeded, motifControls: [] });\n\nconst motif = (\n\tid: BackgroundPreset,\n\tmotifControls: readonly (keyof MotifOptions)[],\n): PresetInfo => ({\n\tid,\n\tfamily: 'motif',\n\tkind: 'svg',\n\tseeded: true,\n\tmotifControls,\n});\n\n/**\n * Every preset: the ids are final, the rest of each entry (`kind`, `seeded`,\n * `motifControls`) follows how the preset ends up drawn and may be refined\n * while the presets are built.\n */\nexport const BACKGROUND_PRESETS: readonly PresetInfo[] = [\n\tlight('gradient', 'css'),\n\tlight('mesh', 'css'),\n\tlight('aurora', 'css+svg'),\n\tlight('spotlight', 'css+svg'),\n\tlight('bokeh', 'css+svg', true),\n\tlight('grain', 'css+svg'),\n\tgeometry('isometric', 'css+svg'),\n\tgeometry('blueprint', 'css+svg'),\n\tgeometry('dots', 'css'),\n\tgeometry('stripes', 'css'),\n\tgeometry('low-poly', 'css+svg', true),\n\tgeometry('topography', 'css+svg', true),\n\tgeometry('waves', 'css+svg'),\n\tmotif('shapes', ALL_MOTIF),\n\tmotif('confetti-grid', ALL_MOTIF),\n\tmotif('constellation', ['density', 'size', 'opacitySpread']),\n\tmotif('halftone', ['shapes', 'density', 'size', 'shapeFill']),\n\tmotif('truchet', ['shapes', 'density', 'size', 'opacitySpread']),\n\tmotif('floating', [\n\t\t'shapes',\n\t\t'density',\n\t\t'size',\n\t\t'opacitySpread',\n\t\t'shapeFill',\n\t]),\n\tmotif('scatter-icons', ['density', 'size', 'opacitySpread', 'rotate']),\n];\n\n/** The presets that are drawn today (a subset of `BACKGROUND_PRESETS`). */\nexport const SHIPPED_BACKGROUND_PRESETS: readonly ShippedBackgroundPreset[] = [\n\t'gradient',\n\t'grain',\n];\n\nconst warned = new Set<string>();\n\n/**\n * The preset to draw: `preset` when it ships, else `'gradient'`, with a\n * one-time `console.warn` outside production (a planned id, or a typo from a\n * JavaScript caller).\n */\nexport function resolveShippedPreset(preset: string): ShippedBackgroundPreset {\n\tif ((SHIPPED_BACKGROUND_PRESETS as readonly string[]).includes(preset)) {\n\t\treturn preset as ShippedBackgroundPreset;\n\t}\n\tconst production =\n\t\ttypeof process !== 'undefined' && process.env?.NODE_ENV === 'production';\n\tif (!production && !warned.has(preset)) {\n\t\twarned.add(preset);\n\t\tconsole.warn(\n\t\t\t`Background: preset \"${preset}\" is not available yet; drawing \"gradient\".`,\n\t\t);\n\t}\n\treturn 'gradient';\n}\n",
|
|
12
|
+
"/**\n * A seeded random generator (mulberry32): the same seed always gives the same\n * sequence of numbers in [0, 1), on the server and in the browser, so a\n * background renders the same markup on both. There is no `Math.random` in\n * this folder.\n */\nexport function mulberry32(seed: number): () => number {\n\tlet a = (Math.trunc(seed) * 2654435761) >>> 0 || 1;\n\treturn () => {\n\t\ta = (a + 0x6d2b79f5) | 0;\n\t\tlet t = Math.imul(a ^ (a >>> 15), 1 | a);\n\t\tt = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n\t\treturn ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\n/** One of `items`, drawn with `rand`. `items` must not be empty. */\nexport function pick<T>(rand: () => number, items: readonly T[]): T {\n\treturn items[Math.floor(rand() * items.length)] as T; // non-empty by contract\n}\n\n/** Rounds to one decimal, which keeps the markup short and stable. */\nexport function round1(n: number): number {\n\treturn Math.round(n * 10) / 10;\n}\n",
|
|
13
|
+
"import { round1 } from './rng';\nimport { el } from './scene';\nimport type { MotifOptions, MotifShape, SceneNode } from './types';\n\nexport const MOTIF_SHAPES: readonly MotifShape[] = [\n\t'circle',\n\t'ring',\n\t'square',\n\t'triangle',\n\t'plus',\n\t'line',\n\t'arc',\n];\n\nexport const MOTIF_DEFAULTS: Required<MotifOptions> = {\n\tshapes: MOTIF_SHAPES,\n\tdensity: 'default',\n\tsize: 'mixed',\n\trotate: true,\n\tshapeFill: 'mixed',\n\topacitySpread: 'varied',\n};\n\n/**\n * One motif primitive centred on 0,0 with half-size `s`, drawn in\n * `currentColor` (the group around it sets the colour through a class). The\n * stroke shapes (`ring`, `plus`) keep their stroke when `filled`, only\n * thicker.\n */\nexport function motifShape(\n\tshape: MotifShape,\n\ts: number,\n\tfilled: boolean,\n): SceneNode {\n\tconst sw = round1(Math.max(1.6, s * 0.1));\n\tconst fillAttrs: Record<string, string | number> = filled\n\t\t? { fill: 'currentColor' }\n\t\t: {\n\t\t\t\tfill: 'none',\n\t\t\t\tstroke: 'currentColor',\n\t\t\t\t'stroke-width': sw,\n\t\t\t\t'stroke-linejoin': 'round',\n\t\t\t};\n\tconst stroke = (w: number) => ({\n\t\tfill: 'none',\n\t\tstroke: 'currentColor',\n\t\t'stroke-width': round1(w),\n\t\t'stroke-linecap': 'round',\n\t});\n\tconst k = (n: number) => round1(s * n);\n\tswitch (shape) {\n\t\tcase 'circle':\n\t\t\treturn el('circle', { r: round1(s), ...fillAttrs });\n\t\tcase 'ring':\n\t\t\treturn el('circle', {\n\t\t\t\tr: k(0.8),\n\t\t\t\t...stroke(filled ? Math.max(2.4, s * 0.3) : sw),\n\t\t\t});\n\t\tcase 'square':\n\t\t\treturn el('rect', {\n\t\t\t\tx: k(-0.84),\n\t\t\t\ty: k(-0.84),\n\t\t\t\twidth: k(1.68),\n\t\t\t\theight: k(1.68),\n\t\t\t\trx: k(0.3),\n\t\t\t\t...fillAttrs,\n\t\t\t});\n\t\tcase 'triangle':\n\t\t\treturn el('path', {\n\t\t\t\td: `M0 ${k(-1)}L${k(0.92)} ${k(0.62)}L${k(-0.92)} ${k(0.62)}Z`,\n\t\t\t\t...fillAttrs,\n\t\t\t});\n\t\tcase 'plus':\n\t\t\treturn el('path', {\n\t\t\t\td: `M${k(-0.78)} 0H${k(0.78)}M0 ${k(-0.78)}V${k(0.78)}`,\n\t\t\t\t...stroke(filled ? Math.max(2.4, s * 0.32) : sw),\n\t\t\t});\n\t\tcase 'line':\n\t\t\treturn el('rect', {\n\t\t\t\tx: k(-1),\n\t\t\t\ty: k(-0.17),\n\t\t\t\twidth: k(2),\n\t\t\t\theight: k(0.34),\n\t\t\t\trx: k(0.17),\n\t\t\t\t...fillAttrs,\n\t\t\t});\n\t\tdefault: {\n\t\t\tconst arc = `M${k(-1)} ${k(0.4)}A${k(1)} ${k(1)} 0 0 1 ${k(1)} ${k(0.4)}`;\n\t\t\treturn filled\n\t\t\t\t? el('path', { d: `${arc}Z`, ...fillAttrs })\n\t\t\t\t: el('path', { d: arc, ...stroke(Math.max(1.8, s * 0.16)) });\n\t\t}\n\t}\n}\n\nexport interface PlaceOptions {\n\tx: number;\n\ty: number;\n\t/** Degrees. */\n\trotation?: number;\n\t/** Class that sets the colour, such as `k1`. */\n\tclassName: string;\n\topacity: number;\n}\n\n/** A group that places `inner` at a point, turned and tinted by class. */\nexport function place(opts: PlaceOptions, inner: SceneNode): SceneNode {\n\tconst turn = opts.rotation ? ` rotate(${round1(opts.rotation)})` : '';\n\treturn el(\n\t\t'g',\n\t\t{\n\t\t\ttransform: `translate(${round1(opts.x)} ${round1(opts.y)})${turn}`,\n\t\t\tclass: opts.className,\n\t\t\topacity: Math.round(opts.opacity * 100) / 100,\n\t\t},\n\t\t[inner],\n\t);\n}\n",
|
|
14
|
+
"export interface ScatterPoint {\n\tx: number;\n\ty: number;\n\t/** Half-size: the radius of the disc the point keeps to itself. */\n\ts: number;\n}\n\nexport interface ScatterOptions {\n\twidth?: number;\n\theight?: number;\n\t/** Distance between two discs, as a multiple of their radii. */\n\tgap?: number;\n\t/** Distance added on top, in the box's units. */\n\tpad?: number;\n\t/** How far outside the box a centre may fall. */\n\tmargin?: number;\n\t/** Draws tried for each size before it is dropped. */\n\tattempts?: number;\n}\n\n/**\n * Dart throwing, largest first: a Poisson-disc set with variable radii. Each\n * size in `sizes` gets a random centre that keeps clear of the discs already\n * placed, or is dropped after `attempts` tries. `sizes` is not modified.\n */\nexport function scatter(\n\trand: () => number,\n\tsizes: readonly number[],\n\t{\n\t\twidth = 1600,\n\t\theight = 1000,\n\t\tgap = 1.12,\n\t\tpad = 10,\n\t\tmargin = 40,\n\t\tattempts = 40,\n\t}: ScatterOptions = {},\n): ScatterPoint[] {\n\tconst out: ScatterPoint[] = [];\n\tfor (const s of [...sizes].sort((a, b) => b - a)) {\n\t\tfor (let t = 0; t < attempts; t++) {\n\t\t\tconst x = -margin + rand() * (width + 2 * margin);\n\t\t\tconst y = -margin + rand() * (height + 2 * margin);\n\t\t\tif (\n\t\t\t\tout.every((p) => Math.hypot(p.x - x, p.y - y) >= (p.s + s) * gap + pad)\n\t\t\t) {\n\t\t\t\tout.push({ x, y, s });\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn out;\n}\n",
|
|
15
|
+
"import type { BackgroundIntensity, BackgroundTone } from './types';\n\nexport const BACKGROUND_TONES: readonly BackgroundTone[] = [\n\t'primary',\n\t'secondary',\n\t'tertiary',\n\t'neutral',\n\t'success',\n\t'warning',\n\t'error',\n\t'info',\n\t'mixed',\n\t'custom',\n];\n\nexport const BACKGROUND_INTENSITIES: readonly BackgroundIntensity[] = [\n\t'subtle',\n\t'default',\n\t'vivid',\n];\n"
|
|
16
|
+
],
|
|
17
|
+
"mappings": "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",
|
|
18
|
+
"debugId": "9BBF7513D8A7900264756E2164756E21",
|
|
19
|
+
"names": []
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smooth value noise over a `width` × `height` box, from a lattice of
|
|
3
|
+
* `lx` × `ly` cells filled with `rand`: returns a function from a point to a
|
|
4
|
+
* value in [0, 1]. Points outside the box clamp to its edge.
|
|
5
|
+
*/
|
|
6
|
+
export declare function valueNoise2(rand: () => number, lx: number, ly: number, width: number, height: number): (x: number, y: number) => number;
|
|
7
|
+
//# sourceMappingURL=noise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../../src/backgrounds/noise.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,WAAW,CAC1B,IAAI,EAAE,MAAM,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACZ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAkBlC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SceneNode, SceneOptions } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* The grain: film noise from an `feTurbulence` filter, turned grey and drawn on
|
|
4
|
+
* one rect. It is an overlay (the library draws it above the preset's layers,
|
|
5
|
+
* with `mix-blend-mode` and an opacity set by the CSS), so it paints no colour
|
|
6
|
+
* of its own. The `seed` moves the noise; the look may still change.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildGrain({ idPrefix, seed }: SceneOptions): SceneNode;
|
|
9
|
+
//# sourceMappingURL=grain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grain.d.ts","sourceRoot":"","sources":["../../../src/backgrounds/presets/grain.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAQ,EAAE,EAAE,YAAY,GAAG,SAAS,CAkC1E"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PresetInfo, ShippedBackgroundPreset } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Every preset: the ids are final, the rest of each entry (`kind`, `seeded`,
|
|
4
|
+
* `motifControls`) follows how the preset ends up drawn and may be refined
|
|
5
|
+
* while the presets are built.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BACKGROUND_PRESETS: readonly PresetInfo[];
|
|
8
|
+
/** The presets that are drawn today (a subset of `BACKGROUND_PRESETS`). */
|
|
9
|
+
export declare const SHIPPED_BACKGROUND_PRESETS: readonly ShippedBackgroundPreset[];
|
|
10
|
+
/**
|
|
11
|
+
* The preset to draw: `preset` when it ships, else `'gradient'`, with a
|
|
12
|
+
* one-time `console.warn` outside production (a planned id, or a typo from a
|
|
13
|
+
* JavaScript caller).
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveShippedPreset(preset: string): ShippedBackgroundPreset;
|
|
16
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/backgrounds/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGX,UAAU,EACV,uBAAuB,EACvB,MAAM,SAAS,CAAC;AAkCjB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,UAAU,EA2BnD,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,0BAA0B,EAAE,SAAS,uBAAuB,EAGxE,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CAa5E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MotifOptions, MotifShape, SceneNode } from './types';
|
|
2
|
+
export declare const MOTIF_SHAPES: readonly MotifShape[];
|
|
3
|
+
export declare const MOTIF_DEFAULTS: Required<MotifOptions>;
|
|
4
|
+
/**
|
|
5
|
+
* One motif primitive centred on 0,0 with half-size `s`, drawn in
|
|
6
|
+
* `currentColor` (the group around it sets the colour through a class). The
|
|
7
|
+
* stroke shapes (`ring`, `plus`) keep their stroke when `filled`, only
|
|
8
|
+
* thicker.
|
|
9
|
+
*/
|
|
10
|
+
export declare function motifShape(shape: MotifShape, s: number, filled: boolean): SceneNode;
|
|
11
|
+
export interface PlaceOptions {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
/** Degrees. */
|
|
15
|
+
rotation?: number;
|
|
16
|
+
/** Class that sets the colour, such as `k1`. */
|
|
17
|
+
className: string;
|
|
18
|
+
opacity: number;
|
|
19
|
+
}
|
|
20
|
+
/** A group that places `inner` at a point, turned and tinted by class. */
|
|
21
|
+
export declare function place(opts: PlaceOptions, inner: SceneNode): SceneNode;
|
|
22
|
+
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/backgrounds/primitives.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEnE,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAQ7C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,YAAY,CAOjD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,UAAU,CACzB,KAAK,EAAE,UAAU,EACjB,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,OAAO,GACb,SAAS,CA4DX;AAED,MAAM,WAAW,YAAY;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,CAWrE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A seeded random generator (mulberry32): the same seed always gives the same
|
|
3
|
+
* sequence of numbers in [0, 1), on the server and in the browser, so a
|
|
4
|
+
* background renders the same markup on both. There is no `Math.random` in
|
|
5
|
+
* this folder.
|
|
6
|
+
*/
|
|
7
|
+
export declare function mulberry32(seed: number): () => number;
|
|
8
|
+
/** One of `items`, drawn with `rand`. `items` must not be empty. */
|
|
9
|
+
export declare function pick<T>(rand: () => number, items: readonly T[]): T;
|
|
10
|
+
/** Rounds to one decimal, which keeps the markup short and stable. */
|
|
11
|
+
export declare function round1(n: number): number;
|
|
12
|
+
//# sourceMappingURL=rng.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rng.d.ts","sourceRoot":"","sources":["../../src/backgrounds/rng.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,MAAM,CAQrD;AAED,oEAAoE;AACpE,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,CAElE;AAED,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAExC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ScatterPoint {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
/** Half-size: the radius of the disc the point keeps to itself. */
|
|
5
|
+
s: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ScatterOptions {
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
/** Distance between two discs, as a multiple of their radii. */
|
|
11
|
+
gap?: number;
|
|
12
|
+
/** Distance added on top, in the box's units. */
|
|
13
|
+
pad?: number;
|
|
14
|
+
/** How far outside the box a centre may fall. */
|
|
15
|
+
margin?: number;
|
|
16
|
+
/** Draws tried for each size before it is dropped. */
|
|
17
|
+
attempts?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Dart throwing, largest first: a Poisson-disc set with variable radii. Each
|
|
21
|
+
* size in `sizes` gets a random centre that keeps clear of the discs already
|
|
22
|
+
* placed, or is dropped after `attempts` tries. `sizes` is not modified.
|
|
23
|
+
*/
|
|
24
|
+
export declare function scatter(rand: () => number, sizes: readonly number[], { width, height, gap, pad, margin, attempts, }?: ScatterOptions): ScatterPoint[];
|
|
25
|
+
//# sourceMappingURL=scatter.d.ts.map
|