@idle-screens/schema 1.0.0 → 2.0.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/FORMAT.md +135 -0
- package/dist/index.d.ts +56 -1
- package/dist/index.js +354 -191
- package/dist/index.js.map +1 -1
- package/package.json +9 -5
- package/saver-spec.schema.json +224 -0
package/dist/index.js
CHANGED
|
@@ -292,6 +292,99 @@ function positionAt(e, t, w, h) {
|
|
|
292
292
|
import {
|
|
293
293
|
createRng
|
|
294
294
|
} from "@idle-screens/core";
|
|
295
|
+
|
|
296
|
+
// src/steer.ts
|
|
297
|
+
var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
298
|
+
function resolveSpecPath(spec, path) {
|
|
299
|
+
if (!spec || typeof spec !== "object" || !path) return null;
|
|
300
|
+
const parts = path.split(".");
|
|
301
|
+
if (parts.some((p) => UNSAFE_KEYS.has(p))) return null;
|
|
302
|
+
const s = spec;
|
|
303
|
+
if (parts[0] !== "layers" && parts[0] !== "background" && Array.isArray(s.layers)) {
|
|
304
|
+
const idx = s.layers.findIndex((l) => l && l.key === parts[0]);
|
|
305
|
+
if (idx === -1) return null;
|
|
306
|
+
parts.splice(0, 1, "layers", String(idx));
|
|
307
|
+
}
|
|
308
|
+
let node = spec;
|
|
309
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
310
|
+
if (node === null || typeof node !== "object") return null;
|
|
311
|
+
node = node[parts[i]];
|
|
312
|
+
}
|
|
313
|
+
if (node === null || typeof node !== "object") return null;
|
|
314
|
+
const last = parts[parts.length - 1];
|
|
315
|
+
const key = Array.isArray(node) ? Number(last) : last;
|
|
316
|
+
const exists = Array.isArray(node) ? Number.isInteger(key) && key >= 0 && key < node.length : last in node;
|
|
317
|
+
return exists ? { parent: node, key } : null;
|
|
318
|
+
}
|
|
319
|
+
function applyDeltasToSpec(spec, deltas) {
|
|
320
|
+
const copy = JSON.parse(JSON.stringify(spec));
|
|
321
|
+
for (const d of deltas) {
|
|
322
|
+
const loc = resolveSpecPath(copy, d.path);
|
|
323
|
+
if (loc) loc.parent[loc.key] = d.value;
|
|
324
|
+
}
|
|
325
|
+
return copy;
|
|
326
|
+
}
|
|
327
|
+
var HEX2 = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
328
|
+
function hexToRgb(hex) {
|
|
329
|
+
const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
|
|
330
|
+
const n = parseInt(h.slice(1), 16);
|
|
331
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
332
|
+
}
|
|
333
|
+
function lerpHex(a, b, k) {
|
|
334
|
+
const ca = hexToRgb(a);
|
|
335
|
+
const cb = hexToRgb(b);
|
|
336
|
+
const mix = ca.map((v, i) => Math.round(v + (cb[i] - v) * k));
|
|
337
|
+
return `#${mix.map((v) => v.toString(16).padStart(2, "0")).join("")}`;
|
|
338
|
+
}
|
|
339
|
+
function lerpSpec(from, to, k) {
|
|
340
|
+
const kk = Math.max(0, Math.min(1, k));
|
|
341
|
+
const walk = (a, b, key) => {
|
|
342
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
343
|
+
const v = a + (b - a) * kk;
|
|
344
|
+
return key === "count" ? Math.max(1, Math.round(v)) : v;
|
|
345
|
+
}
|
|
346
|
+
if (typeof a === "string" && typeof b === "string" && HEX2.test(a) && HEX2.test(b)) {
|
|
347
|
+
return lerpHex(a, b, kk);
|
|
348
|
+
}
|
|
349
|
+
if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
|
|
350
|
+
return b.map((bv, i) => walk(a[i], bv, i));
|
|
351
|
+
}
|
|
352
|
+
if (a && b && typeof a === "object" && typeof b === "object" && !Array.isArray(a) && !Array.isArray(b)) {
|
|
353
|
+
const out = {};
|
|
354
|
+
for (const kName of Object.keys(b)) {
|
|
355
|
+
out[kName] = walk(a[kName], b[kName], kName);
|
|
356
|
+
}
|
|
357
|
+
return out;
|
|
358
|
+
}
|
|
359
|
+
return kk > 0 ? b : a;
|
|
360
|
+
};
|
|
361
|
+
return walk(from, to);
|
|
362
|
+
}
|
|
363
|
+
function easeSmooth(k) {
|
|
364
|
+
const c = Math.max(0, Math.min(1, k));
|
|
365
|
+
return c * c * (3 - 2 * c);
|
|
366
|
+
}
|
|
367
|
+
function structuralSignature(spec) {
|
|
368
|
+
return JSON.stringify(
|
|
369
|
+
spec.layers.map((l) => [
|
|
370
|
+
l.count,
|
|
371
|
+
l.size,
|
|
372
|
+
l.region,
|
|
373
|
+
l.position,
|
|
374
|
+
l.motion,
|
|
375
|
+
l.wrap,
|
|
376
|
+
l.flip,
|
|
377
|
+
l.alpha,
|
|
378
|
+
l.pulse,
|
|
379
|
+
l.sprite.kind,
|
|
380
|
+
l.sprite.kind === "circle" ? l.sprite.radius : void 0,
|
|
381
|
+
l.sprite.kind === "emoji" ? l.sprite.glyphs.length : l.sprite.kind === "text" ? l.sprite.strings.length : void 0
|
|
382
|
+
])
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// src/compile.ts
|
|
387
|
+
var DEFAULT_STEER_DUR = 1e3;
|
|
295
388
|
function hexToRgba(hex, alpha) {
|
|
296
389
|
const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
|
|
297
390
|
const n = parseInt(h.slice(1), 16);
|
|
@@ -310,12 +403,14 @@ function manifestFor(spec) {
|
|
|
310
403
|
reducedMotionFallback: "static",
|
|
311
404
|
// Flash-safe by construction: static background + bounded sprites, no strobe
|
|
312
405
|
// primitive. Proven by sampling a compiled spec through @idle-screens/validator.
|
|
313
|
-
a11y: { flashSafe: true }
|
|
406
|
+
a11y: { flashSafe: true },
|
|
407
|
+
workerReady: true
|
|
314
408
|
};
|
|
315
409
|
}
|
|
316
410
|
var SpecInstance = class {
|
|
317
411
|
constructor(spec, ctx) {
|
|
318
412
|
this.spec = spec;
|
|
413
|
+
this.effSpec = spec;
|
|
319
414
|
this.saverCtx = ctx;
|
|
320
415
|
this.seed = (spec.seed ?? ctx.seed) >>> 0 || 1;
|
|
321
416
|
let canvas;
|
|
@@ -354,6 +449,11 @@ var SpecInstance = class {
|
|
|
354
449
|
baseT = 0;
|
|
355
450
|
// elapsed logical time carried across pause/resume
|
|
356
451
|
lastT = 0;
|
|
452
|
+
/** The spec currently being rendered (base spec + any applied steering). */
|
|
453
|
+
effSpec;
|
|
454
|
+
/** Active glide between two resolved specs (live setParam/applyTrack). */
|
|
455
|
+
transition = null;
|
|
456
|
+
lastStructural = "";
|
|
357
457
|
sizeCanvas() {
|
|
358
458
|
const dpr = Math.min(this.saverCtx.dpr, 2);
|
|
359
459
|
this.canvas.width = Math.max(1, Math.round(this.w * dpr));
|
|
@@ -363,7 +463,8 @@ var SpecInstance = class {
|
|
|
363
463
|
/** (Re)seed and place all entities — deterministic for the seed + size. */
|
|
364
464
|
rebuild() {
|
|
365
465
|
const rng = createRng(this.seed);
|
|
366
|
-
this.layers = this.
|
|
466
|
+
this.layers = this.effSpec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, this.w, this.h) }));
|
|
467
|
+
this.lastStructural = structuralSignature(this.effSpec);
|
|
367
468
|
}
|
|
368
469
|
start() {
|
|
369
470
|
if (this.frameId !== null || typeof requestAnimationFrame === "undefined") return;
|
|
@@ -385,7 +486,7 @@ var SpecInstance = class {
|
|
|
385
486
|
}
|
|
386
487
|
drawBackground() {
|
|
387
488
|
const { ctx, w, h } = this;
|
|
388
|
-
const bg = this.
|
|
489
|
+
const bg = this.effSpec.background;
|
|
389
490
|
if (!bg || bg.type === "solid") {
|
|
390
491
|
ctx.fillStyle = bg?.color ?? "#05050a";
|
|
391
492
|
ctx.fillRect(0, 0, w, h);
|
|
@@ -440,8 +541,47 @@ var SpecInstance = class {
|
|
|
440
541
|
}
|
|
441
542
|
ctx.restore();
|
|
442
543
|
}
|
|
544
|
+
/** Advance any live steering glide; rebuild entities on structural change. */
|
|
545
|
+
stepTransition(t) {
|
|
546
|
+
const tr = this.transition;
|
|
547
|
+
if (!tr) return;
|
|
548
|
+
const k = tr.dur <= 0 ? 1 : (t - tr.startT) / tr.dur;
|
|
549
|
+
this.effSpec = k >= 1 ? tr.to : lerpSpec(tr.from, tr.to, easeSmooth(k));
|
|
550
|
+
if (k >= 1) this.transition = null;
|
|
551
|
+
const sig = structuralSignature(this.effSpec);
|
|
552
|
+
if (sig !== this.lastStructural) this.rebuild();
|
|
553
|
+
else this.layers.forEach((b, i) => {
|
|
554
|
+
b.layer = this.effSpec.layers[i] ?? b.layer;
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Live steering: glide from what's currently rendered to the track's target
|
|
559
|
+
* state (deltas applied last-wins). Duration = the longest delta `dur`.
|
|
560
|
+
*/
|
|
561
|
+
applyTrack(track) {
|
|
562
|
+
const deltas = track?.deltas ?? [];
|
|
563
|
+
const target = applyDeltasToSpec(this.effSpec, deltas);
|
|
564
|
+
if (!validateSpec(target).valid) return;
|
|
565
|
+
const dur = deltas.length ? deltas.reduce((m, d) => Math.max(m, d.dur ?? DEFAULT_STEER_DUR), 0) : DEFAULT_STEER_DUR;
|
|
566
|
+
this.transition = {
|
|
567
|
+
from: JSON.parse(JSON.stringify(this.effSpec)),
|
|
568
|
+
to: target,
|
|
569
|
+
startT: this.lastT,
|
|
570
|
+
dur
|
|
571
|
+
};
|
|
572
|
+
if (this.paused) {
|
|
573
|
+
this.transition = null;
|
|
574
|
+
this.effSpec = target;
|
|
575
|
+
if (structuralSignature(this.effSpec) !== this.lastStructural) this.rebuild();
|
|
576
|
+
else this.layers.forEach((b, i) => {
|
|
577
|
+
b.layer = this.effSpec.layers[i] ?? b.layer;
|
|
578
|
+
});
|
|
579
|
+
this.renderFrame(this.lastT, this.seed);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
443
582
|
/** Deterministic, frame-addressable render (shared by the rAF loop). */
|
|
444
583
|
renderFrame(t, _seed) {
|
|
584
|
+
this.stepTransition(t);
|
|
445
585
|
const { ctx } = this;
|
|
446
586
|
ctx.globalAlpha = 1;
|
|
447
587
|
ctx.globalCompositeOperation = "source-over";
|
|
@@ -483,7 +623,7 @@ function compileSaver(spec) {
|
|
|
483
623
|
};
|
|
484
624
|
}
|
|
485
625
|
|
|
486
|
-
// src/examples.ts
|
|
626
|
+
// src/examples/aquarium.ts
|
|
487
627
|
var AQUARIUM_SPEC = {
|
|
488
628
|
schemaVersion: 1,
|
|
489
629
|
id: "aquarium",
|
|
@@ -514,185 +654,8 @@ var AQUARIUM_SPEC = {
|
|
|
514
654
|
}
|
|
515
655
|
]
|
|
516
656
|
};
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
id: "rain",
|
|
520
|
-
label: "Rain",
|
|
521
|
-
seed: 7,
|
|
522
|
-
motionIntensity: "moderate",
|
|
523
|
-
background: { type: "solid", color: "#05070a" },
|
|
524
|
-
layers: [
|
|
525
|
-
{
|
|
526
|
-
count: 140,
|
|
527
|
-
sprite: { kind: "text", strings: ["\u2502"], color: "#9fd0ff" },
|
|
528
|
-
size: [12, 26],
|
|
529
|
-
motion: { type: "drift", angle: 90, speed: [520, 900] }
|
|
530
|
-
}
|
|
531
|
-
]
|
|
532
|
-
};
|
|
533
|
-
var SNOWFALL_SPEC = {
|
|
534
|
-
schemaVersion: 1,
|
|
535
|
-
id: "snowfall",
|
|
536
|
-
label: "Snowfall",
|
|
537
|
-
seed: 12,
|
|
538
|
-
motionIntensity: "calm",
|
|
539
|
-
background: {
|
|
540
|
-
type: "gradient",
|
|
541
|
-
stops: [
|
|
542
|
-
{ at: 0, color: "#0a1628" },
|
|
543
|
-
{ at: 0.7, color: "#0d1f3c" },
|
|
544
|
-
{ at: 1, color: "#121212" }
|
|
545
|
-
]
|
|
546
|
-
},
|
|
547
|
-
layers: [
|
|
548
|
-
{
|
|
549
|
-
count: 50,
|
|
550
|
-
sprite: { kind: "circle", radius: [1, 2.5], color: "#8899aa" },
|
|
551
|
-
motion: { type: "drift", angle: 90, speed: [15, 40], bob: 3 }
|
|
552
|
-
},
|
|
553
|
-
{
|
|
554
|
-
count: 35,
|
|
555
|
-
sprite: { kind: "circle", radius: [2, 4.5], color: "#c0cdd8" },
|
|
556
|
-
motion: { type: "drift", angle: 85, speed: [35, 80], bob: 6 }
|
|
557
|
-
},
|
|
558
|
-
{
|
|
559
|
-
count: 15,
|
|
560
|
-
sprite: { kind: "circle", radius: [3.5, 7], color: "#e8eff5" },
|
|
561
|
-
motion: { type: "drift", angle: 82, speed: [55, 120], bob: 10 }
|
|
562
|
-
}
|
|
563
|
-
]
|
|
564
|
-
};
|
|
565
|
-
var LANTERNS_SPEC = {
|
|
566
|
-
schemaVersion: 1,
|
|
567
|
-
id: "lanterns",
|
|
568
|
-
label: "Night Lanterns",
|
|
569
|
-
seed: 88,
|
|
570
|
-
motionIntensity: "calm",
|
|
571
|
-
background: {
|
|
572
|
-
type: "gradient",
|
|
573
|
-
stops: [
|
|
574
|
-
{ at: 0, color: "#04060f" },
|
|
575
|
-
{ at: 0.55, color: "#0b1026" },
|
|
576
|
-
{ at: 0.85, color: "#251731" },
|
|
577
|
-
{ at: 1, color: "#472518" }
|
|
578
|
-
]
|
|
579
|
-
},
|
|
580
|
-
layers: [
|
|
581
|
-
{
|
|
582
|
-
count: 60,
|
|
583
|
-
sprite: { kind: "circle", radius: [0.5, 1.4], color: "#8fa0c8" },
|
|
584
|
-
alpha: [0.35, 1],
|
|
585
|
-
region: { y: [0, 0.62] },
|
|
586
|
-
motion: { type: "drift", speed: [0.5, 2], bob: 1 }
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
count: 36,
|
|
590
|
-
sprite: {
|
|
591
|
-
kind: "circle",
|
|
592
|
-
radius: [1.5, 3],
|
|
593
|
-
color: "#b06a2a",
|
|
594
|
-
soft: true
|
|
595
|
-
},
|
|
596
|
-
alpha: [0.5, 0.9],
|
|
597
|
-
blend: "lighter",
|
|
598
|
-
pulse: { amp: 0.18, period: 2800 },
|
|
599
|
-
motion: { type: "rise", speed: [6, 14], sway: 4 }
|
|
600
|
-
},
|
|
601
|
-
{
|
|
602
|
-
count: 14,
|
|
603
|
-
sprite: {
|
|
604
|
-
kind: "circle",
|
|
605
|
-
radius: [3.5, 6.5],
|
|
606
|
-
color: "#e08a34",
|
|
607
|
-
soft: true
|
|
608
|
-
},
|
|
609
|
-
alpha: [0.6, 1],
|
|
610
|
-
blend: "lighter",
|
|
611
|
-
pulse: { amp: 0.22, period: 3400 },
|
|
612
|
-
motion: { type: "rise", speed: [16, 28], sway: 7 }
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
count: 8,
|
|
616
|
-
sprite: { kind: "emoji", glyphs: ["\u{1F3EE}"] },
|
|
617
|
-
size: [26, 44],
|
|
618
|
-
alpha: [0.85, 1],
|
|
619
|
-
motion: { type: "rise", speed: [30, 48], sway: 10 }
|
|
620
|
-
},
|
|
621
|
-
{
|
|
622
|
-
count: 4,
|
|
623
|
-
sprite: { kind: "emoji", glyphs: ["\u{1F3EE}"] },
|
|
624
|
-
size: [58, 84],
|
|
625
|
-
motion: { type: "rise", speed: [52, 74], sway: 14 }
|
|
626
|
-
},
|
|
627
|
-
{
|
|
628
|
-
count: 12,
|
|
629
|
-
sprite: { kind: "circle", radius: [2, 5], color: "#e08a34", soft: true },
|
|
630
|
-
alpha: [0.12, 0.35],
|
|
631
|
-
blend: "lighter",
|
|
632
|
-
region: { y: [0.93, 1] },
|
|
633
|
-
pulse: { amp: 0.1, period: 2200 },
|
|
634
|
-
motion: { type: "drift", speed: [2, 6], bob: 2 }
|
|
635
|
-
}
|
|
636
|
-
]
|
|
637
|
-
};
|
|
638
|
-
var SAKURA_SPEC = {
|
|
639
|
-
schemaVersion: 1,
|
|
640
|
-
id: "sakura",
|
|
641
|
-
label: "Sakura Drift",
|
|
642
|
-
seed: 314,
|
|
643
|
-
motionIntensity: "calm",
|
|
644
|
-
background: {
|
|
645
|
-
type: "gradient",
|
|
646
|
-
stops: [
|
|
647
|
-
{ at: 0, color: "#1b1d38" },
|
|
648
|
-
{ at: 0.45, color: "#3a2645" },
|
|
649
|
-
{ at: 0.8, color: "#7d3d4e" },
|
|
650
|
-
{ at: 1, color: "#0f140d" }
|
|
651
|
-
],
|
|
652
|
-
band: { color: "#0c140d", height: 44 }
|
|
653
|
-
},
|
|
654
|
-
layers: [
|
|
655
|
-
{
|
|
656
|
-
count: 60,
|
|
657
|
-
sprite: { kind: "circle", radius: [0.6, 1.6], color: "#ffe3ec", soft: true },
|
|
658
|
-
alpha: [0.3, 0.9],
|
|
659
|
-
blend: "lighter",
|
|
660
|
-
region: { y: [0, 0.72] },
|
|
661
|
-
pulse: { amp: 0.22, period: 3e3 },
|
|
662
|
-
motion: { type: "drift", speed: [0.3, 1.2], bob: 1 }
|
|
663
|
-
},
|
|
664
|
-
{
|
|
665
|
-
count: 28,
|
|
666
|
-
sprite: { kind: "emoji", glyphs: ["\u{1F338}"] },
|
|
667
|
-
size: [13, 20],
|
|
668
|
-
alpha: [0.5, 0.8],
|
|
669
|
-
motion: { type: "drift", speed: [12, 26], angle: 100, bob: 3 }
|
|
670
|
-
},
|
|
671
|
-
{
|
|
672
|
-
count: 18,
|
|
673
|
-
sprite: { kind: "emoji", glyphs: ["\u{1F338}"] },
|
|
674
|
-
size: [20, 32],
|
|
675
|
-
alpha: [0.7, 0.95],
|
|
676
|
-
motion: { type: "drift", speed: [24, 44], angle: 100, bob: 6 }
|
|
677
|
-
},
|
|
678
|
-
{
|
|
679
|
-
count: 10,
|
|
680
|
-
sprite: { kind: "emoji", glyphs: ["\u{1F338}"] },
|
|
681
|
-
size: [34, 54],
|
|
682
|
-
alpha: [0.85, 1],
|
|
683
|
-
motion: { type: "drift", speed: [42, 68], angle: 100, bob: 11 }
|
|
684
|
-
},
|
|
685
|
-
{
|
|
686
|
-
count: 16,
|
|
687
|
-
sprite: { kind: "circle", radius: [1.5, 4], color: "#ff9bb5", soft: true },
|
|
688
|
-
alpha: [0.1, 0.3],
|
|
689
|
-
blend: "lighter",
|
|
690
|
-
region: { y: [0.9, 1] },
|
|
691
|
-
pulse: { amp: 0.15, period: 2600 },
|
|
692
|
-
motion: { type: "drift", speed: [0.3, 1.5], angle: 180, bob: 1 }
|
|
693
|
-
}
|
|
694
|
-
]
|
|
695
|
-
};
|
|
657
|
+
|
|
658
|
+
// src/examples/dev-dashboard.ts
|
|
696
659
|
var DASHBOARD_SPEC = {
|
|
697
660
|
schemaVersion: 1,
|
|
698
661
|
id: "dev-dashboard",
|
|
@@ -1154,7 +1117,7 @@ var DASHBOARD_SPEC = {
|
|
|
1154
1117
|
position: { x: 0.06, y: 0.92 },
|
|
1155
1118
|
sprite: {
|
|
1156
1119
|
kind: "text",
|
|
1157
|
-
strings: ["14:03 Edit examples.ts +84 -1"],
|
|
1120
|
+
strings: ["14:03 Edit examples/dev-dashboard.ts +84 -1"],
|
|
1158
1121
|
color: "#445544",
|
|
1159
1122
|
font: "10px monospace",
|
|
1160
1123
|
align: "left",
|
|
@@ -1180,31 +1143,231 @@ var DASHBOARD_SPEC = {
|
|
|
1180
1143
|
}
|
|
1181
1144
|
]
|
|
1182
1145
|
};
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1146
|
+
|
|
1147
|
+
// src/examples/lanterns.ts
|
|
1148
|
+
var LANTERNS_SPEC = {
|
|
1149
|
+
schemaVersion: 1,
|
|
1150
|
+
id: "lanterns",
|
|
1151
|
+
label: "Night Lanterns",
|
|
1152
|
+
seed: 88,
|
|
1153
|
+
motionIntensity: "calm",
|
|
1154
|
+
background: {
|
|
1155
|
+
type: "gradient",
|
|
1156
|
+
stops: [
|
|
1157
|
+
{ at: 0, color: "#04060f" },
|
|
1158
|
+
{ at: 0.55, color: "#0b1026" },
|
|
1159
|
+
{ at: 0.85, color: "#251731" },
|
|
1160
|
+
{ at: 1, color: "#472518" }
|
|
1161
|
+
]
|
|
1162
|
+
},
|
|
1163
|
+
layers: [
|
|
1164
|
+
{
|
|
1165
|
+
count: 60,
|
|
1166
|
+
sprite: { kind: "circle", radius: [0.5, 1.4], color: "#8fa0c8" },
|
|
1167
|
+
alpha: [0.35, 1],
|
|
1168
|
+
region: { y: [0, 0.62] },
|
|
1169
|
+
motion: { type: "drift", speed: [0.5, 2], bob: 1 }
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
count: 36,
|
|
1173
|
+
sprite: {
|
|
1174
|
+
kind: "circle",
|
|
1175
|
+
radius: [1.5, 3],
|
|
1176
|
+
color: "#b06a2a",
|
|
1177
|
+
soft: true
|
|
1178
|
+
},
|
|
1179
|
+
alpha: [0.5, 0.9],
|
|
1180
|
+
blend: "lighter",
|
|
1181
|
+
pulse: { amp: 0.18, period: 2800 },
|
|
1182
|
+
motion: { type: "rise", speed: [6, 14], sway: 4 }
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
count: 14,
|
|
1186
|
+
sprite: {
|
|
1187
|
+
kind: "circle",
|
|
1188
|
+
radius: [3.5, 6.5],
|
|
1189
|
+
color: "#e08a34",
|
|
1190
|
+
soft: true
|
|
1191
|
+
},
|
|
1192
|
+
alpha: [0.6, 1],
|
|
1193
|
+
blend: "lighter",
|
|
1194
|
+
pulse: { amp: 0.22, period: 3400 },
|
|
1195
|
+
motion: { type: "rise", speed: [16, 28], sway: 7 }
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
count: 8,
|
|
1199
|
+
sprite: { kind: "emoji", glyphs: ["\u{1F3EE}"] },
|
|
1200
|
+
size: [26, 44],
|
|
1201
|
+
alpha: [0.85, 1],
|
|
1202
|
+
motion: { type: "rise", speed: [30, 48], sway: 10 }
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
count: 4,
|
|
1206
|
+
sprite: { kind: "emoji", glyphs: ["\u{1F3EE}"] },
|
|
1207
|
+
size: [58, 84],
|
|
1208
|
+
motion: { type: "rise", speed: [52, 74], sway: 14 }
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
count: 12,
|
|
1212
|
+
sprite: { kind: "circle", radius: [2, 5], color: "#e08a34", soft: true },
|
|
1213
|
+
alpha: [0.12, 0.35],
|
|
1214
|
+
blend: "lighter",
|
|
1215
|
+
region: { y: [0.93, 1] },
|
|
1216
|
+
pulse: { amp: 0.1, period: 2200 },
|
|
1217
|
+
motion: { type: "drift", speed: [2, 6], bob: 2 }
|
|
1218
|
+
}
|
|
1219
|
+
]
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
// src/examples/rain.ts
|
|
1223
|
+
var RAIN_SPEC = {
|
|
1224
|
+
schemaVersion: 1,
|
|
1225
|
+
id: "rain",
|
|
1226
|
+
label: "Rain",
|
|
1227
|
+
seed: 7,
|
|
1228
|
+
motionIntensity: "moderate",
|
|
1229
|
+
background: { type: "solid", color: "#05070a" },
|
|
1230
|
+
layers: [
|
|
1231
|
+
{
|
|
1232
|
+
count: 140,
|
|
1233
|
+
sprite: { kind: "text", strings: ["\u2502"], color: "#9fd0ff" },
|
|
1234
|
+
size: [12, 26],
|
|
1235
|
+
motion: { type: "drift", angle: 90, speed: [520, 900] }
|
|
1236
|
+
}
|
|
1237
|
+
]
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1240
|
+
// src/examples/sakura.ts
|
|
1241
|
+
var SAKURA_SPEC = {
|
|
1242
|
+
schemaVersion: 1,
|
|
1243
|
+
id: "sakura",
|
|
1244
|
+
label: "Sakura Drift",
|
|
1245
|
+
seed: 314,
|
|
1246
|
+
motionIntensity: "calm",
|
|
1247
|
+
background: {
|
|
1248
|
+
type: "gradient",
|
|
1249
|
+
stops: [
|
|
1250
|
+
{ at: 0, color: "#1b1d38" },
|
|
1251
|
+
{ at: 0.45, color: "#3a2645" },
|
|
1252
|
+
{ at: 0.8, color: "#7d3d4e" },
|
|
1253
|
+
{ at: 1, color: "#0f140d" }
|
|
1254
|
+
],
|
|
1255
|
+
band: { color: "#0c140d", height: 44 }
|
|
1256
|
+
},
|
|
1257
|
+
layers: [
|
|
1258
|
+
{
|
|
1259
|
+
count: 60,
|
|
1260
|
+
sprite: { kind: "circle", radius: [0.6, 1.6], color: "#ffe3ec", soft: true },
|
|
1261
|
+
alpha: [0.3, 0.9],
|
|
1262
|
+
blend: "lighter",
|
|
1263
|
+
region: { y: [0, 0.72] },
|
|
1264
|
+
pulse: { amp: 0.22, period: 3e3 },
|
|
1265
|
+
motion: { type: "drift", speed: [0.3, 1.2], bob: 1 }
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
count: 28,
|
|
1269
|
+
sprite: { kind: "emoji", glyphs: ["\u{1F338}"] },
|
|
1270
|
+
size: [13, 20],
|
|
1271
|
+
alpha: [0.5, 0.8],
|
|
1272
|
+
motion: { type: "drift", speed: [12, 26], angle: 100, bob: 3 }
|
|
1273
|
+
},
|
|
1274
|
+
{
|
|
1275
|
+
count: 18,
|
|
1276
|
+
sprite: { kind: "emoji", glyphs: ["\u{1F338}"] },
|
|
1277
|
+
size: [20, 32],
|
|
1278
|
+
alpha: [0.7, 0.95],
|
|
1279
|
+
motion: { type: "drift", speed: [24, 44], angle: 100, bob: 6 }
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
count: 10,
|
|
1283
|
+
sprite: { kind: "emoji", glyphs: ["\u{1F338}"] },
|
|
1284
|
+
size: [34, 54],
|
|
1285
|
+
alpha: [0.85, 1],
|
|
1286
|
+
motion: { type: "drift", speed: [42, 68], angle: 100, bob: 11 }
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
count: 16,
|
|
1290
|
+
sprite: { kind: "circle", radius: [1.5, 4], color: "#ff9bb5", soft: true },
|
|
1291
|
+
alpha: [0.1, 0.3],
|
|
1292
|
+
blend: "lighter",
|
|
1293
|
+
region: { y: [0.9, 1] },
|
|
1294
|
+
pulse: { amp: 0.15, period: 2600 },
|
|
1295
|
+
motion: { type: "drift", speed: [0.3, 1.5], angle: 180, bob: 1 }
|
|
1296
|
+
}
|
|
1297
|
+
]
|
|
1298
|
+
};
|
|
1299
|
+
|
|
1300
|
+
// src/examples/snowfall.ts
|
|
1301
|
+
var SNOWFALL_SPEC = {
|
|
1302
|
+
schemaVersion: 1,
|
|
1303
|
+
id: "snowfall",
|
|
1304
|
+
label: "Snowfall",
|
|
1305
|
+
seed: 12,
|
|
1306
|
+
motionIntensity: "calm",
|
|
1307
|
+
background: {
|
|
1308
|
+
type: "gradient",
|
|
1309
|
+
stops: [
|
|
1310
|
+
{ at: 0, color: "#0a1628" },
|
|
1311
|
+
{ at: 0.7, color: "#0d1f3c" },
|
|
1312
|
+
{ at: 1, color: "#121212" }
|
|
1313
|
+
]
|
|
1314
|
+
},
|
|
1315
|
+
layers: [
|
|
1316
|
+
{
|
|
1317
|
+
count: 50,
|
|
1318
|
+
sprite: { kind: "circle", radius: [1, 2.5], color: "#8899aa" },
|
|
1319
|
+
motion: { type: "drift", angle: 90, speed: [15, 40], bob: 3 }
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
count: 35,
|
|
1323
|
+
sprite: { kind: "circle", radius: [2, 4.5], color: "#c0cdd8" },
|
|
1324
|
+
motion: { type: "drift", angle: 85, speed: [35, 80], bob: 6 }
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
count: 15,
|
|
1328
|
+
sprite: { kind: "circle", radius: [3.5, 7], color: "#e8eff5" },
|
|
1329
|
+
motion: { type: "drift", angle: 82, speed: [55, 120], bob: 10 }
|
|
1330
|
+
}
|
|
1331
|
+
]
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
// src/examples/index.ts
|
|
1335
|
+
var SCHEMA_EXAMPLES = [
|
|
1336
|
+
{ id: "aquarium", label: "Aquarium", spec: AQUARIUM_SPEC },
|
|
1337
|
+
{ id: "rain", label: "Rain", spec: RAIN_SPEC },
|
|
1338
|
+
{ id: "snowfall", label: "Snowfall", spec: SNOWFALL_SPEC },
|
|
1339
|
+
{ id: "lanterns", label: "Night Lanterns", spec: LANTERNS_SPEC },
|
|
1340
|
+
{ id: "sakura", label: "Sakura Drift", spec: SAKURA_SPEC },
|
|
1341
|
+
{ id: "dev-dashboard", label: "Dev Dashboard", spec: DASHBOARD_SPEC }
|
|
1190
1342
|
];
|
|
1343
|
+
var EXAMPLE_SPECS = SCHEMA_EXAMPLES.map((e) => e.spec);
|
|
1344
|
+
var EXAMPLE_BY_ID = Object.fromEntries(
|
|
1345
|
+
SCHEMA_EXAMPLES.map((e) => [e.id, e.spec])
|
|
1346
|
+
);
|
|
1191
1347
|
export {
|
|
1192
1348
|
AQUARIUM_SPEC,
|
|
1193
1349
|
DASHBOARD_SPEC,
|
|
1350
|
+
EXAMPLE_BY_ID,
|
|
1194
1351
|
EXAMPLE_SPECS,
|
|
1195
1352
|
LANTERNS_SPEC,
|
|
1196
1353
|
LIMITS,
|
|
1197
1354
|
RAIN_SPEC,
|
|
1198
1355
|
SAKURA_SPEC,
|
|
1356
|
+
SCHEMA_EXAMPLES,
|
|
1199
1357
|
SCHEMA_VERSION,
|
|
1200
1358
|
SNOWFALL_SPEC,
|
|
1201
1359
|
alphaAt,
|
|
1360
|
+
applyDeltasToSpec,
|
|
1202
1361
|
assertValidSpec,
|
|
1203
1362
|
buildEntities,
|
|
1204
1363
|
compileSaver,
|
|
1364
|
+
easeSmooth,
|
|
1365
|
+
lerpSpec,
|
|
1205
1366
|
manifestFor,
|
|
1206
1367
|
positionAt,
|
|
1368
|
+
resolveSpecPath,
|
|
1207
1369
|
spriteVariants,
|
|
1370
|
+
structuralSignature,
|
|
1208
1371
|
validateSpec
|
|
1209
1372
|
};
|
|
1210
1373
|
//# sourceMappingURL=index.js.map
|