@glissade/scene 0.13.0-pre.3 → 0.14.0-pre.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/dist/index.js +21 -13
- package/dist/layout.js +4 -4
- package/dist/layoutEngine.d.ts +20 -2
- package/dist/layoutEngine.js +40 -29
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -48,8 +48,8 @@ var Highlight = class extends Node {
|
|
|
48
48
|
this.progress = init$2(signal(1), props.progress);
|
|
49
49
|
this.padding = props.padding ?? [4, 2];
|
|
50
50
|
this.cornerRadius = props.cornerRadius ?? 4;
|
|
51
|
-
this.registerTarget("progress", this.progress);
|
|
52
|
-
this.registerTarget("color", this.color);
|
|
51
|
+
this.registerTarget("progress", this.progress, "number");
|
|
52
|
+
this.registerTarget("color", this.color, "color");
|
|
53
53
|
}
|
|
54
54
|
draw(out, ctx) {
|
|
55
55
|
const progress = Math.min(1, Math.max(0, this.progress()));
|
|
@@ -132,7 +132,7 @@ var TextCursor = class extends Node {
|
|
|
132
132
|
this.solidWhileTyping = props.solidWhileTyping ?? true;
|
|
133
133
|
this.caretWidth = props.width ?? 2;
|
|
134
134
|
this.fill = init$1(signal(""), props.fill);
|
|
135
|
-
this.registerTarget("fill", this.fill);
|
|
135
|
+
this.registerTarget("fill", this.fill, "color");
|
|
136
136
|
}
|
|
137
137
|
draw(out, ctx) {
|
|
138
138
|
const head = this.target.revealHead(ctx.measurer);
|
|
@@ -288,6 +288,14 @@ function mix(seed, i) {
|
|
|
288
288
|
h = Math.imul(h ^ h >>> 15, 1935289751);
|
|
289
289
|
return (h ^ h >>> 15) >>> 0;
|
|
290
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Salt folded into the motion-jitter seed so the per-index jitter rng
|
|
293
|
+
* decorrelates from `ctx.rng` (the factory rng). Both axes derive from
|
|
294
|
+
* `mix(baseSeed, i)`; without a distinct salt they would be the SAME stream,
|
|
295
|
+
* so a factory that draws from `ctx.rng` and a `jitter` callback would see
|
|
296
|
+
* correlated "independent" randomness. An arbitrary fixed odd constant.
|
|
297
|
+
*/
|
|
298
|
+
const JITTER_SALT = 1779033703;
|
|
291
299
|
/** Resolve a built-in layout (or call the escape-hatch fn) to a fraction. */
|
|
292
300
|
function placeAt(layout, i, n) {
|
|
293
301
|
if (typeof layout === "function") return layout(i, n);
|
|
@@ -394,7 +402,7 @@ function each(n, factory, opts) {
|
|
|
394
402
|
const start = m.startSec ?? 0;
|
|
395
403
|
const at = staggerFn(m, n);
|
|
396
404
|
for (let i = 0; i < n; i++) {
|
|
397
|
-
const rngI = random(mix(baseSeed, i));
|
|
405
|
+
const rngI = random(mix(mix(baseSeed, i), JITTER_SALT));
|
|
398
406
|
const overrides = m.jitter?.(i, rngI, n);
|
|
399
407
|
const applyOpts = {
|
|
400
408
|
...overrides !== void 0 ? { overrides } : {},
|
|
@@ -815,7 +823,7 @@ var FollowPath = class extends Node {
|
|
|
815
823
|
this.progress = signal(1);
|
|
816
824
|
if (typeof props.progress === "function") this.progress.bindSource(props.progress);
|
|
817
825
|
else if (props.progress !== void 0) this.progress.set(props.progress);
|
|
818
|
-
this.registerTarget("progress", this.progress);
|
|
826
|
+
this.registerTarget("progress", this.progress, "number");
|
|
819
827
|
const sOpts = props.samplesPerSegment !== void 0 ? { samplesPerSegment: props.samplesPerSegment } : {};
|
|
820
828
|
const getPath = props.path instanceof Path ? () => props.path.data() : () => props.path;
|
|
821
829
|
let cachedPath = getPath();
|
|
@@ -919,13 +927,13 @@ var TokenHighlight = class extends Node {
|
|
|
919
927
|
run,
|
|
920
928
|
bound: runText(boxes, run)
|
|
921
929
|
};
|
|
922
|
-
this.registerTarget(`${id}/fill`, r.fill);
|
|
923
|
-
this.registerTarget(`${id}/opacity`, r.opacity);
|
|
924
|
-
this.registerTarget(`${id}/progress`, r.progress);
|
|
925
|
-
this.registerTarget(`${id}/scale`, r.scale);
|
|
926
|
-
this.registerTarget(`${id}/offset`, r.offset);
|
|
927
|
-
this.registerTarget(`${id}/offset.x`, r.offset.x);
|
|
928
|
-
this.registerTarget(`${id}/offset.y`, r.offset.y);
|
|
930
|
+
this.registerTarget(`${id}/fill`, r.fill, "color");
|
|
931
|
+
this.registerTarget(`${id}/opacity`, r.opacity, "number");
|
|
932
|
+
this.registerTarget(`${id}/progress`, r.progress, "number");
|
|
933
|
+
this.registerTarget(`${id}/scale`, r.scale, "number");
|
|
934
|
+
this.registerTarget(`${id}/offset`, r.offset, "vec2");
|
|
935
|
+
this.registerTarget(`${id}/offset.x`, r.offset.x, "number");
|
|
936
|
+
this.registerTarget(`${id}/offset.y`, r.offset.y, "number");
|
|
929
937
|
return r;
|
|
930
938
|
});
|
|
931
939
|
}
|
|
@@ -1121,7 +1129,7 @@ var ShaderEffect = class extends Group {
|
|
|
1121
1129
|
for (const [name, value] of Object.entries(props.uniforms ?? {})) {
|
|
1122
1130
|
const sig = signal(value);
|
|
1123
1131
|
map.set(name, sig);
|
|
1124
|
-
this.registerTarget(`u.${name}`, sig);
|
|
1132
|
+
this.registerTarget(`u.${name}`, sig, "number");
|
|
1125
1133
|
}
|
|
1126
1134
|
this.uniformSignals = map;
|
|
1127
1135
|
}
|
package/dist/layout.js
CHANGED
|
@@ -53,10 +53,10 @@ var Layout = class extends Group {
|
|
|
53
53
|
this.direction = props.direction ?? "row";
|
|
54
54
|
this.justify = props.justify ?? "start";
|
|
55
55
|
this.align = props.align ?? "center";
|
|
56
|
-
this.registerTarget("width", this.width);
|
|
57
|
-
this.registerTarget("height", this.height);
|
|
58
|
-
this.registerTarget("gap", this.gap);
|
|
59
|
-
this.registerTarget("padding", this.padding);
|
|
56
|
+
this.registerTarget("width", this.width, "number");
|
|
57
|
+
this.registerTarget("height", this.height, "number");
|
|
58
|
+
this.registerTarget("gap", this.gap, "number");
|
|
59
|
+
this.registerTarget("padding", this.padding, "number");
|
|
60
60
|
}
|
|
61
61
|
intrinsicSize(measurer) {
|
|
62
62
|
if (!this.autoWidth && !this.autoHeight) return {
|
package/dist/layoutEngine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BindableSignal, MeshInterpolation, MeshPaint as MeshPaint$1, MeshPoint, Paint, PathValue, ReadonlySignal, Rng, Track, Vec2, Vec2Signal } from "@glissade/core";
|
|
1
|
+
import { BindableSignal, MeshInterpolation, MeshPaint as MeshPaint$1, MeshPoint, Paint, PathValue, ReadonlySignal, Rng, Track, ValueTypeId, Vec2, Vec2Signal } from "@glissade/core";
|
|
2
2
|
|
|
3
3
|
//#region src/matrix.d.ts
|
|
4
4
|
|
|
@@ -297,6 +297,11 @@ interface NodeProps {
|
|
|
297
297
|
interface BindablePropTarget {
|
|
298
298
|
bindSource(fn: () => unknown): void;
|
|
299
299
|
unbindSource(): void;
|
|
300
|
+
/**
|
|
301
|
+
* The value type(s) this prop accepts — bindTimeline hard-throws a mismatched
|
|
302
|
+
* track (§2.2). An array for a polymorphic prop (a Shape `fill` is color|paint).
|
|
303
|
+
*/
|
|
304
|
+
readonly expects: ValueTypeId | readonly ValueTypeId[];
|
|
300
305
|
}
|
|
301
306
|
/** Node-local hit-shape override (v2 §C.3) — fat targets for thin strokes. */
|
|
302
307
|
type HitArea = {
|
|
@@ -345,7 +350,16 @@ declare abstract class Node {
|
|
|
345
350
|
/** Track-target paths → bindable signals; subclasses register their own props. */
|
|
346
351
|
protected readonly targets: Map<string, BindablePropTarget>;
|
|
347
352
|
constructor(props?: NodeProps);
|
|
348
|
-
|
|
353
|
+
/**
|
|
354
|
+
* Register a track-target path → bindable signal, stamping the value type the
|
|
355
|
+
* signal accepts (§2.2). The stamp is what bindTimeline's bind-time guard
|
|
356
|
+
* reads to reject a mismatched track (a scalar on a vec2, a number on a paint
|
|
357
|
+
* prop, …) instead of silently sampling to NaN/undefined.
|
|
358
|
+
*/
|
|
359
|
+
protected registerTarget(path: string, sig: {
|
|
360
|
+
bindSource(fn: () => unknown): void;
|
|
361
|
+
unbindSource(): void;
|
|
362
|
+
}, expects: ValueTypeId | readonly ValueTypeId[]): void;
|
|
349
363
|
resolveTarget(path: string): BindablePropTarget | undefined;
|
|
350
364
|
/** Subclass drawing: emit own commands (and children for containers). */
|
|
351
365
|
protected abstract draw(out: DisplayListBuilder, ctx: EvalContext): void;
|
|
@@ -609,6 +623,8 @@ interface ImageProps extends NodeProps {
|
|
|
609
623
|
height?: PropInit<number>;
|
|
610
624
|
}
|
|
611
625
|
declare class ImageNode extends Node {
|
|
626
|
+
/** Marks this node as referencing a kind 'image' timeline asset (§2.3). */
|
|
627
|
+
static readonly assetKind: "image";
|
|
612
628
|
readonly assetId: string;
|
|
613
629
|
readonly width: BindableSignal<number>;
|
|
614
630
|
readonly height: BindableSignal<number>;
|
|
@@ -644,6 +660,8 @@ interface VideoProps extends NodeProps {
|
|
|
644
660
|
* and references the exact source-grid frame; backends resolve it.
|
|
645
661
|
*/
|
|
646
662
|
declare class Video extends Node {
|
|
663
|
+
/** Marks this node as referencing a kind 'video' timeline asset (§3.8). */
|
|
664
|
+
static readonly assetKind: "video";
|
|
647
665
|
readonly assetId: string;
|
|
648
666
|
readonly at: number;
|
|
649
667
|
readonly trimStart: number;
|
package/dist/layoutEngine.js
CHANGED
|
@@ -560,17 +560,24 @@ var Node = class {
|
|
|
560
560
|
]);
|
|
561
561
|
}, { equals: matEquals });
|
|
562
562
|
this.worldMatrix = computed(() => this.parent ? multiply(this.parent.worldMatrix(), this.localMatrix()) : this.localMatrix(), { equals: matEquals });
|
|
563
|
-
this.registerTarget("position", this.position);
|
|
564
|
-
this.registerTarget("position.x", this.position.x);
|
|
565
|
-
this.registerTarget("position.y", this.position.y);
|
|
566
|
-
this.registerTarget("rotation", this.rotation);
|
|
567
|
-
this.registerTarget("scale", this.scale);
|
|
568
|
-
this.registerTarget("scale.x", this.scale.x);
|
|
569
|
-
this.registerTarget("scale.y", this.scale.y);
|
|
570
|
-
this.registerTarget("opacity", this.opacity);
|
|
571
|
-
this.registerTarget("zIndex", this.zIndex);
|
|
572
|
-
}
|
|
573
|
-
|
|
563
|
+
this.registerTarget("position", this.position, "vec2");
|
|
564
|
+
this.registerTarget("position.x", this.position.x, "number");
|
|
565
|
+
this.registerTarget("position.y", this.position.y, "number");
|
|
566
|
+
this.registerTarget("rotation", this.rotation, "number");
|
|
567
|
+
this.registerTarget("scale", this.scale, "vec2");
|
|
568
|
+
this.registerTarget("scale.x", this.scale.x, "number");
|
|
569
|
+
this.registerTarget("scale.y", this.scale.y, "number");
|
|
570
|
+
this.registerTarget("opacity", this.opacity, "number");
|
|
571
|
+
this.registerTarget("zIndex", this.zIndex, "number");
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Register a track-target path → bindable signal, stamping the value type the
|
|
575
|
+
* signal accepts (§2.2). The stamp is what bindTimeline's bind-time guard
|
|
576
|
+
* reads to reject a mismatched track (a scalar on a vec2, a number on a paint
|
|
577
|
+
* prop, …) instead of silently sampling to NaN/undefined.
|
|
578
|
+
*/
|
|
579
|
+
registerTarget(path, sig, expects) {
|
|
580
|
+
sig.expects = expects;
|
|
574
581
|
this.targets.set(path, sig);
|
|
575
582
|
if (this.id !== void 0) sig[TARGET_PATH] = `${this.id}/${path}`;
|
|
576
583
|
}
|
|
@@ -1141,10 +1148,10 @@ var Shape = class extends Node {
|
|
|
1141
1148
|
this.stroke = initProp(signal(""), props.stroke);
|
|
1142
1149
|
this.strokeWidth = initProp(signal(0), props.strokeWidth);
|
|
1143
1150
|
this.reveal = initProp(signal(1), props.reveal);
|
|
1144
|
-
this.registerTarget("fill", this.fill);
|
|
1145
|
-
this.registerTarget("stroke", this.stroke);
|
|
1146
|
-
this.registerTarget("strokeWidth", this.strokeWidth);
|
|
1147
|
-
this.registerTarget("reveal", this.reveal);
|
|
1151
|
+
this.registerTarget("fill", this.fill, ["color", "paint"]);
|
|
1152
|
+
this.registerTarget("stroke", this.stroke, "color");
|
|
1153
|
+
this.registerTarget("strokeWidth", this.strokeWidth, "number");
|
|
1154
|
+
this.registerTarget("reveal", this.reveal, "number");
|
|
1148
1155
|
if (props.sketch) validateSketch(props.sketch);
|
|
1149
1156
|
if (props.sketchFill) validateHachure(props.sketchFill);
|
|
1150
1157
|
if (props.sketchFill && !props.sketch) emitDevWarning(`${this.id !== void 0 ? `'${this.id}': ` : ""}sketchFill is ignored without sketch — hachure fill is drawn only by the sketch renderer. Set a sketch style (e.g. { kind: 'pencil' }) to see it.`);
|
|
@@ -1396,9 +1403,9 @@ var Rect = class extends Shape {
|
|
|
1396
1403
|
this.width = initProp(signal(0), props.width);
|
|
1397
1404
|
this.height = initProp(signal(0), props.height);
|
|
1398
1405
|
this.cornerRadius = initProp(signal(0), props.cornerRadius);
|
|
1399
|
-
this.registerTarget("width", this.width);
|
|
1400
|
-
this.registerTarget("height", this.height);
|
|
1401
|
-
this.registerTarget("cornerRadius", this.cornerRadius);
|
|
1406
|
+
this.registerTarget("width", this.width, "number");
|
|
1407
|
+
this.registerTarget("height", this.height, "number");
|
|
1408
|
+
this.registerTarget("cornerRadius", this.cornerRadius, "number");
|
|
1402
1409
|
}
|
|
1403
1410
|
intrinsicSize() {
|
|
1404
1411
|
return {
|
|
@@ -1418,7 +1425,7 @@ var Circle = class extends Shape {
|
|
|
1418
1425
|
constructor(props = {}) {
|
|
1419
1426
|
super(props);
|
|
1420
1427
|
this.radius = initProp(signal(0), props.radius);
|
|
1421
|
-
this.registerTarget("radius", this.radius);
|
|
1428
|
+
this.registerTarget("radius", this.radius, "number");
|
|
1422
1429
|
}
|
|
1423
1430
|
intrinsicSize() {
|
|
1424
1431
|
const d = this.radius() * 2;
|
|
@@ -1451,7 +1458,7 @@ var Path = class extends Shape {
|
|
|
1451
1458
|
constructor(props = {}) {
|
|
1452
1459
|
super(props);
|
|
1453
1460
|
this.data = initProp(signal([]), props.data);
|
|
1454
|
-
this.registerTarget("d", this.data);
|
|
1461
|
+
this.registerTarget("d", this.data, "path");
|
|
1455
1462
|
}
|
|
1456
1463
|
/** Control-point bounding box (conservative: contains the true curve). */
|
|
1457
1464
|
bounds() {
|
|
@@ -1538,6 +1545,8 @@ var Path = class extends Shape {
|
|
|
1538
1545
|
}
|
|
1539
1546
|
};
|
|
1540
1547
|
var ImageNode = class extends Node {
|
|
1548
|
+
/** Marks this node as referencing a kind 'image' timeline asset (§2.3). */
|
|
1549
|
+
static assetKind = "image";
|
|
1541
1550
|
assetId;
|
|
1542
1551
|
width;
|
|
1543
1552
|
height;
|
|
@@ -1546,8 +1555,8 @@ var ImageNode = class extends Node {
|
|
|
1546
1555
|
this.assetId = props.assetId;
|
|
1547
1556
|
this.width = initProp(signal(0), props.width);
|
|
1548
1557
|
this.height = initProp(signal(0), props.height);
|
|
1549
|
-
this.registerTarget("width", this.width);
|
|
1550
|
-
this.registerTarget("height", this.height);
|
|
1558
|
+
this.registerTarget("width", this.width, "number");
|
|
1559
|
+
this.registerTarget("height", this.height, "number");
|
|
1551
1560
|
}
|
|
1552
1561
|
intrinsicSize() {
|
|
1553
1562
|
return {
|
|
@@ -1581,6 +1590,8 @@ var ImageNode = class extends Node {
|
|
|
1581
1590
|
* and references the exact source-grid frame; backends resolve it.
|
|
1582
1591
|
*/
|
|
1583
1592
|
var Video = class extends Node {
|
|
1593
|
+
/** Marks this node as referencing a kind 'video' timeline asset (§3.8). */
|
|
1594
|
+
static assetKind = "video";
|
|
1584
1595
|
assetId;
|
|
1585
1596
|
at;
|
|
1586
1597
|
trimStart;
|
|
@@ -1599,8 +1610,8 @@ var Video = class extends Node {
|
|
|
1599
1610
|
this.sourceFps = props.sourceFps;
|
|
1600
1611
|
this.width = initProp(signal(0), props.width);
|
|
1601
1612
|
this.height = initProp(signal(0), props.height);
|
|
1602
|
-
this.registerTarget("width", this.width);
|
|
1603
|
-
this.registerTarget("height", this.height);
|
|
1613
|
+
this.registerTarget("width", this.width, "number");
|
|
1614
|
+
this.registerTarget("height", this.height, "number");
|
|
1604
1615
|
}
|
|
1605
1616
|
/** Frame-indexed media time for timeline time t; null when outside the clip. */
|
|
1606
1617
|
mediaTime(t) {
|
|
@@ -1657,11 +1668,11 @@ var Text = class extends Node {
|
|
|
1657
1668
|
this.width = initProp(signal(0), props.width);
|
|
1658
1669
|
this.lineHeight = props.lineHeight ?? 1.25;
|
|
1659
1670
|
this.reveal = initProp(signal(Number.POSITIVE_INFINITY), props.reveal);
|
|
1660
|
-
this.registerTarget("width", this.width);
|
|
1661
|
-
this.registerTarget("text", this.text);
|
|
1662
|
-
this.registerTarget("fill", this.fill);
|
|
1663
|
-
this.registerTarget("fontSize", this.fontSize);
|
|
1664
|
-
this.registerTarget("reveal", this.reveal);
|
|
1671
|
+
this.registerTarget("width", this.width, "number");
|
|
1672
|
+
this.registerTarget("text", this.text, "string");
|
|
1673
|
+
this.registerTarget("fill", this.fill, "color");
|
|
1674
|
+
this.registerTarget("fontSize", this.fontSize, "number");
|
|
1675
|
+
this.registerTarget("reveal", this.reveal, "number");
|
|
1665
1676
|
}
|
|
1666
1677
|
intrinsicSize(measurer) {
|
|
1667
1678
|
const text = this.text();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/scene",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0-pre.0",
|
|
4
4
|
"description": "glissade scene graph: nodes, transforms, DisplayList emission. Renderer-agnostic; zero DOM/Node dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"yoga-layout": "^3.2.1",
|
|
26
|
-
"@glissade/core": "0.
|
|
26
|
+
"@glissade/core": "0.14.0-pre.0"
|
|
27
27
|
},
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|