@glissade/scene 0.33.0 → 0.34.0-pre.1
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/chart.d.ts +1 -1
- package/dist/describe.js +12 -2
- package/dist/displayList.d.ts +11 -0
- package/dist/grid.d.ts +1 -1
- package/dist/index.d.ts +33 -2
- package/dist/index.js +70 -4
- package/dist/layoutCtors.d.ts +1 -1
- package/dist/motion.d.ts +1 -1
- package/dist/nodes.d.ts +24 -1
- package/dist/nodes.js +23 -1
- package/dist/scene.d.ts +1 -1
- package/dist/tokens.d.ts +1 -1
- package/dist/type.d.ts +1 -1
- package/package.json +2 -2
package/dist/chart.d.ts
CHANGED
package/dist/describe.js
CHANGED
|
@@ -22,7 +22,7 @@ import { easings, listValueTypes } from "@glissade/core";
|
|
|
22
22
|
* never pulled onto the base embed path — a scene that never calls `describe()`
|
|
23
23
|
* pays zero bytes for it.
|
|
24
24
|
*/
|
|
25
|
-
const RAW_VERSION = "0.
|
|
25
|
+
const RAW_VERSION = "0.34.0-pre.1";
|
|
26
26
|
const PACKAGE_VERSION = RAW_VERSION.includes("GLISSADE_".concat("VERSION")) ? "0.0.0-dev" : RAW_VERSION;
|
|
27
27
|
/** Arity of a value type's numeric repr: vec2/vec2-arc → 2, number → 1; others (color/paint/path/string/boolean) carry no scalar arity. */
|
|
28
28
|
function arityOf(type) {
|
|
@@ -52,7 +52,10 @@ function expectsToType(expects) {
|
|
|
52
52
|
* only each node's OWN construction surface.
|
|
53
53
|
*/
|
|
54
54
|
const CONSTRUCTION_PROP_META = {
|
|
55
|
-
Group: {
|
|
55
|
+
Group: {
|
|
56
|
+
children: { type: "Node[]" },
|
|
57
|
+
clip: { type: "{ w, h, r?, x?, y? } | PathSeg[]" }
|
|
58
|
+
},
|
|
56
59
|
Rect: {
|
|
57
60
|
sketch: { type: "SketchStyle" },
|
|
58
61
|
sketchFill: { type: "HachureSpec" },
|
|
@@ -190,6 +193,7 @@ const LAYOUT_CONSTRUCTION_META = {
|
|
|
190
193
|
function describeLayoutNode() {
|
|
191
194
|
const props = describeNode(new Group(), "Group").props;
|
|
192
195
|
delete props.children;
|
|
196
|
+
delete props["clip"];
|
|
193
197
|
for (const [prop, spec] of Object.entries(LAYOUT_ANIMATABLE)) {
|
|
194
198
|
const arity = arityOf(spec.type);
|
|
195
199
|
props[prop] = {
|
|
@@ -351,6 +355,12 @@ const HELPERS = [
|
|
|
351
355
|
import: "@glissade/scene",
|
|
352
356
|
usage: "motionBlur(child: Node, opts?: { id?, shutter?: number, samples?: number }): MotionBlur"
|
|
353
357
|
},
|
|
358
|
+
{
|
|
359
|
+
name: "trackMatte",
|
|
360
|
+
summary: "Track-matte: mask CONTENT by a MATTE layer's alpha (default) or luminance ('luma'). Content renders into an isolated layer, then the matte composites destination-in — pixels survive only where the matte is opaque. Both subtrees animate like ordinary nodes (a sliding shape wipes text in, a scaling blob irises a photo). Byte-exact on Skia; browser-vs-Skia pixel parity is perceptual at anti-aliased matte edges; backend-dom (preview tier) degrades with data-approx.",
|
|
361
|
+
import: "@glissade/scene",
|
|
362
|
+
usage: "trackMatte(content: Node, matte: Node, opts?: { id?, mode?: 'alpha' | 'luma' }): TrackMatte"
|
|
363
|
+
},
|
|
354
364
|
{
|
|
355
365
|
name: "clip",
|
|
356
366
|
summary: "A reusable, target-agnostic motion captured once as a relative-time key schedule, then applied to a node at a wall-clock start time. Build-time sugar: clip.apply() compiles to ordinary Track[].",
|
package/dist/displayList.d.ts
CHANGED
|
@@ -174,6 +174,17 @@ type DrawCommand = {
|
|
|
174
174
|
filters: FilterSpec[];
|
|
175
175
|
shader?: ShaderRef;
|
|
176
176
|
cacheKey?: string;
|
|
177
|
+
/**
|
|
178
|
+
* 0.34 track-matte: this layer is a MATTE for the layer it composites
|
|
179
|
+
* onto — 'alpha' keeps destination pixels where this layer is opaque
|
|
180
|
+
* (native destination-in, byte-exact); 'luma' first converts this
|
|
181
|
+
* layer's luminance to alpha via the shared straight-alpha CPU kernel
|
|
182
|
+
* (the mesh-kernel discipline), then applies destination-in. Emitted
|
|
183
|
+
* by trackMatte() inside its isolated outer group; an optional field
|
|
184
|
+
* on the shader?/cacheKey? extension precedent — BlendMode stays a
|
|
185
|
+
* closed union.
|
|
186
|
+
*/
|
|
187
|
+
matte?: 'alpha' | 'luma';
|
|
177
188
|
} | {
|
|
178
189
|
op: 'popGroup';
|
|
179
190
|
};
|
package/dist/grid.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { C as Mat2x3, D as matEquals, E as invert, O as multiply, S as IDENTITY, T as fromTRS, _ as StrokeStyle, a as FilterSpec, b as glow, c as MeshInterpolation, d as Paint, f as PathSeg, g as ShaderRef, h as ResourceId, i as DrawCommand, l as MeshPaint, m as Resource, n as DisplayList, o as FilterValidationError, p as Rect$1, r as DisplayListBuilder, s as FontSpec, t as BlendMode, u as MeshPoint, v as createDisplayListBuilder, w as applyToPoint, x as validateFilters, y as filtersToCanvasFilter } from "./displayList.js";
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as isEstimatingMeasurer, A as hachureLines, B as Node, C as HachureSpec, D as SketchValidationError, E as SketchStyle, F as validateSketch, G as MEASURE_QUANTUM_PX, H as NodeProps, I as AnchorSpec, J as WrappedTextMetrics, K as TextMeasurer, L as BindablePropTarget, M as roughen, N as sketchStrokes, O as arcLength, P as validateHachure, Q as estimatingMeasurer, R as EvalContext, S as roundedRectSegs, T as ResolvedSketch, U as PropInit, V as NodeConstructionError, W as resolveAnchor, X as assertFiniteFontSize, Y as __resetEstimateWarnings, Z as breakLines, _ as VideoProps, a as Group, b as pathFromSegs, c as LineBox, d as Rect, et as measureWrappedText, f as RevealMark, g as Video, h as TextProps, i as GraphemeBox, it as setDefaultMeasurer, j as resolveSketch, k as flatten, l as Path, m as Text, n as ClipRegion, nt as segmentGraphemes, o as ImageNode, p as ShapeProps, q as TextMetricsLite, r as Custom, rt as segmentWords, s as ImageProps, t as Circle, tt as quantize, u as PathProps, v as WordBox, w as Polyline, x as revealSchedule, y as coercePathData, z as HitArea } from "./nodes.js";
|
|
3
3
|
import { t as collapseReplacer } from "./collapseReplacer.js";
|
|
4
4
|
import { a as SceneModule, c as evaluate, i as SceneInit, n as ReservedNodeIdError, o as bindScene, r as Scene, s as createScene, t as DuplicateNodeIdError } from "./scene.js";
|
|
5
5
|
import { a as LayoutEngineMissingError, c as requireLayoutEngine, i as LayoutEngine, l as setLayoutEngine, n as LayoutChildSpec, r as LayoutContainerSpec, s as getLayoutEngine, t as LayoutBox } from "./layoutEngine.js";
|
|
@@ -464,6 +464,30 @@ declare class MotionBlur extends Group {
|
|
|
464
464
|
* sub-frame motion blur. Wrap the moving content; its background stays crisp. */
|
|
465
465
|
declare function motionBlur(child: Node, props?: Omit<MotionBlurProps, 'children'>): MotionBlur;
|
|
466
466
|
//#endregion
|
|
467
|
+
//#region src/matte.d.ts
|
|
468
|
+
interface TrackMatteProps extends NodeProps {
|
|
469
|
+
/** the visible content — masked by the matte. */
|
|
470
|
+
content: Node;
|
|
471
|
+
/** the mask — its alpha (or luma) decides which content pixels survive. */
|
|
472
|
+
matte: Node;
|
|
473
|
+
/** 'alpha' (default): matte opacity masks. 'luma': matte brightness masks
|
|
474
|
+
* (white = keep, black = erase), via the shared deterministic CPU kernel. */
|
|
475
|
+
mode?: 'alpha' | 'luma';
|
|
476
|
+
}
|
|
477
|
+
declare class TrackMatte extends Group {
|
|
478
|
+
get describeType(): string;
|
|
479
|
+
readonly content: Node;
|
|
480
|
+
readonly matte: Node;
|
|
481
|
+
readonly mode: 'alpha' | 'luma';
|
|
482
|
+
constructor(props: TrackMatteProps);
|
|
483
|
+
/** destination-in must not leak past this node — always isolate in a layer. */
|
|
484
|
+
protected requiresGroup(): boolean;
|
|
485
|
+
protected draw(out: DisplayListBuilder, ctx: EvalContext): void;
|
|
486
|
+
}
|
|
487
|
+
/** `trackMatte(photo, circleWipe)` — photo visible only inside the (animatable)
|
|
488
|
+
* circle. Pass `{ mode: 'luma' }` to mask by matte brightness instead of alpha. */
|
|
489
|
+
declare function trackMatte(content: Node, matte: Node, props?: Omit<TrackMatteProps, 'content' | 'matte'>): TrackMatte;
|
|
490
|
+
//#endregion
|
|
467
491
|
//#region src/raster2d.d.ts
|
|
468
492
|
/** A backend gradient handle (DOM CanvasGradient and @napi-rs CanvasGradient both satisfy it). */
|
|
469
493
|
interface CanvasGradientLike {
|
|
@@ -669,6 +693,13 @@ declare class Raster2D<TCanvas extends CanvasLike, TPath extends PathLike, TDraw
|
|
|
669
693
|
* the cache entry (hit); the composite params (opacity/blend/filters) always
|
|
670
694
|
* come from the LIVE pushGroup command, never the cache.
|
|
671
695
|
*/
|
|
696
|
+
/**
|
|
697
|
+
* 0.34 luma matte: convert a layer's LUMINANCE to its alpha, in place —
|
|
698
|
+
* `a' = round(luma(r,g,b) × a / 255)` with Rec.709 integer coefficients over
|
|
699
|
+
* STRAIGHT (non-premultiplied) RGBA, the same discipline as the mesh kernel,
|
|
700
|
+
* so both backends run one deterministic CPU pass and the result byte-compares.
|
|
701
|
+
*/
|
|
702
|
+
private lumaToAlpha;
|
|
672
703
|
private composite;
|
|
673
704
|
/** The command walk — order and operations identical to the pre-extraction twins. */
|
|
674
705
|
render(target: TCanvas, list: DisplayList): void;
|
|
@@ -710,4 +741,4 @@ declare function meshRasterSize(bw: number, bh: number): {
|
|
|
710
741
|
h: number;
|
|
711
742
|
};
|
|
712
743
|
//#endregion
|
|
713
|
-
export { ALL_FILTER_KINDS, type AnchorSpec, type BackendCaps, type BindablePropTarget, type BlendMode, type Bounds, type CanvasLike, Circle, ColdAssetError, type Ctx2DLike, Custom, DeterminismViolationError, type DisplayList, type DisplayListBuilder, type DrawCommand, type DrawOnEachOptions, type DrawOnOptions, DuplicateNodeIdError, type EachBox, type EachContext, type EachDistribute, EachError, type EachLayout, type EachMotion, type EachOpts, type EachResult, Echo, type EchoProps, type EditMark, type EvalContext, type FilterKind, type FilterSpec, FilterValidationError, type FontByteLoader, type FontSpec, type GraphemeBox, Group, type GuardMode, type HachureSpec, Highlight, type HighlightProps, type HitArea, IDENTITY, ImageNode as Image, ImageNode, type ImageDataLike, type ImageHandle, type ImageProps, type LayerCacheEntry, type LayerStore, type LayoutBox, type LayoutChildSpec, type LayoutContainerSpec, type LayoutEngine, LayoutEngineMissingError, type LineBox, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, type Mat2x3, type MeshInterpolation, type MeshPaint, type MeshPoint, MotionBlur, type MotionBlurProps, NODE_TAXONOMY, Node, NodeConstructionError, type NodeProps, type NodeTypeName, type Paint, Path, type PathLike, type PathProps, type PathSeg, type Place, type Polyline, type PropInit, Raster2D, type Raster2DHost, Rect, type Rect$1 as RectShape, type RenderBackend, ReservedNodeIdError, type ResolvedSketch, type Resource, type ResourceId, type RevealMark, type Scene, type SceneInit, type SceneModule, type ShaderCaps, ShaderEffect, type ShaderEffectProps, type ShaderRef, type ShapeProps, type SketchStyle, SketchValidationError, type StepMark, type StrokeStyle, Text, TextCursor, type TextCursorProps, type TextMeasurer, type TextMetricsLite, type TextProps, type TypeEdit, type TypewriterResult, type ValidateSceneFontsOptions, Video, type VideoFrameSource, type VideoProps, type WordBox, type WrappedTextMetrics, __resetEstimateWarnings, applyToPoint, arcLength, assertFiniteFontSize, bindScene, breakLines, coercePathData, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, drawOn, drawOnEach, each, echo, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, fontString, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, isEstimatingMeasurer, matEquals, measureWrappedText, meshRasterSize, motionBlur, multiply, pathFromSegs, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
|
|
744
|
+
export { ALL_FILTER_KINDS, type AnchorSpec, type BackendCaps, type BindablePropTarget, type BlendMode, type Bounds, type CanvasLike, Circle, type ClipRegion, ColdAssetError, type Ctx2DLike, Custom, DeterminismViolationError, type DisplayList, type DisplayListBuilder, type DrawCommand, type DrawOnEachOptions, type DrawOnOptions, DuplicateNodeIdError, type EachBox, type EachContext, type EachDistribute, EachError, type EachLayout, type EachMotion, type EachOpts, type EachResult, Echo, type EchoProps, type EditMark, type EvalContext, type FilterKind, type FilterSpec, FilterValidationError, type FontByteLoader, type FontSpec, type GraphemeBox, Group, type GuardMode, type HachureSpec, Highlight, type HighlightProps, type HitArea, IDENTITY, ImageNode as Image, ImageNode, type ImageDataLike, type ImageHandle, type ImageProps, type LayerCacheEntry, type LayerStore, type LayoutBox, type LayoutChildSpec, type LayoutContainerSpec, type LayoutEngine, LayoutEngineMissingError, type LineBox, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, type Mat2x3, type MeshInterpolation, type MeshPaint, type MeshPoint, MotionBlur, type MotionBlurProps, NODE_TAXONOMY, Node, NodeConstructionError, type NodeProps, type NodeTypeName, type Paint, Path, type PathLike, type PathProps, type PathSeg, type Place, type Polyline, type PropInit, Raster2D, type Raster2DHost, Rect, type Rect$1 as RectShape, type RenderBackend, ReservedNodeIdError, type ResolvedSketch, type Resource, type ResourceId, type RevealMark, type Scene, type SceneInit, type SceneModule, type ShaderCaps, ShaderEffect, type ShaderEffectProps, type ShaderRef, type ShapeProps, type SketchStyle, SketchValidationError, type StepMark, type StrokeStyle, Text, TextCursor, type TextCursorProps, type TextMeasurer, type TextMetricsLite, type TextProps, TrackMatte, type TrackMatteProps, type TypeEdit, type TypewriterResult, type ValidateSceneFontsOptions, Video, type VideoFrameSource, type VideoProps, type WordBox, type WrappedTextMetrics, __resetEstimateWarnings, applyToPoint, arcLength, assertFiniteFontSize, bindScene, breakLines, coercePathData, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, drawOn, drawOnEach, each, echo, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, fontString, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, isEstimatingMeasurer, matEquals, measureWrappedText, meshRasterSize, motionBlur, multiply, pathFromSegs, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, trackMatte, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
|
package/dist/index.js
CHANGED
|
@@ -671,6 +671,52 @@ var ShaderEffect = class extends Group {
|
|
|
671
671
|
};
|
|
672
672
|
}
|
|
673
673
|
};
|
|
674
|
+
//#endregion
|
|
675
|
+
//#region src/matte.ts
|
|
676
|
+
var TrackMatte = class extends Group {
|
|
677
|
+
get describeType() {
|
|
678
|
+
return "TrackMatte";
|
|
679
|
+
}
|
|
680
|
+
content;
|
|
681
|
+
matte;
|
|
682
|
+
mode;
|
|
683
|
+
constructor(props) {
|
|
684
|
+
const { content, matte, mode, ...rest } = props;
|
|
685
|
+
super({
|
|
686
|
+
...rest,
|
|
687
|
+
children: [content, matte]
|
|
688
|
+
});
|
|
689
|
+
if (mode !== void 0 && mode !== "alpha" && mode !== "luma") throw new Error(`trackMatte mode must be 'alpha' or 'luma', got ${JSON.stringify(mode)}`);
|
|
690
|
+
this.content = content;
|
|
691
|
+
this.matte = matte;
|
|
692
|
+
this.mode = mode ?? "alpha";
|
|
693
|
+
}
|
|
694
|
+
/** destination-in must not leak past this node — always isolate in a layer. */
|
|
695
|
+
requiresGroup() {
|
|
696
|
+
return true;
|
|
697
|
+
}
|
|
698
|
+
draw(out, ctx) {
|
|
699
|
+
this.content.emit(out, ctx);
|
|
700
|
+
out.push({
|
|
701
|
+
op: "pushGroup",
|
|
702
|
+
opacity: 1,
|
|
703
|
+
blend: "source-over",
|
|
704
|
+
filters: [],
|
|
705
|
+
matte: this.mode
|
|
706
|
+
});
|
|
707
|
+
this.matte.emit(out, ctx);
|
|
708
|
+
out.push({ op: "popGroup" });
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
/** `trackMatte(photo, circleWipe)` — photo visible only inside the (animatable)
|
|
712
|
+
* circle. Pass `{ mode: 'luma' }` to mask by matte brightness instead of alpha. */
|
|
713
|
+
function trackMatte(content, matte, props = {}) {
|
|
714
|
+
return new TrackMatte({
|
|
715
|
+
...props,
|
|
716
|
+
content,
|
|
717
|
+
matte
|
|
718
|
+
});
|
|
719
|
+
}
|
|
674
720
|
const smoothstep = (u) => u * u * (3 - 2 * u);
|
|
675
721
|
const GAUSS_K = 2.4;
|
|
676
722
|
const GAUSS_NORM = 1 - Math.exp(-5.76 / 2);
|
|
@@ -1143,6 +1189,24 @@ var Raster2D = class {
|
|
|
1143
1189
|
* the cache entry (hit); the composite params (opacity/blend/filters) always
|
|
1144
1190
|
* come from the LIVE pushGroup command, never the cache.
|
|
1145
1191
|
*/
|
|
1192
|
+
/**
|
|
1193
|
+
* 0.34 luma matte: convert a layer's LUMINANCE to its alpha, in place —
|
|
1194
|
+
* `a' = round(luma(r,g,b) × a / 255)` with Rec.709 integer coefficients over
|
|
1195
|
+
* STRAIGHT (non-premultiplied) RGBA, the same discipline as the mesh kernel,
|
|
1196
|
+
* so both backends run one deterministic CPU pass and the result byte-compares.
|
|
1197
|
+
*/
|
|
1198
|
+
lumaToAlpha(ctx, w, h) {
|
|
1199
|
+
const t = ctx.getTransform();
|
|
1200
|
+
ctx.resetTransform();
|
|
1201
|
+
const img = ctx.getImageData(0, 0, w, h);
|
|
1202
|
+
const d = img.data;
|
|
1203
|
+
for (let i = 0; i < d.length; i += 4) {
|
|
1204
|
+
const luma = (d[i] * 2126 + d[i + 1] * 7152 + d[i + 2] * 722) / 255e4;
|
|
1205
|
+
d[i + 3] = Math.round(luma * d[i + 3]);
|
|
1206
|
+
}
|
|
1207
|
+
ctx.putImageData(img, 0, 0);
|
|
1208
|
+
ctx.setTransform(t);
|
|
1209
|
+
}
|
|
1146
1210
|
composite(parent, parentLayer, drawable, bounds, unbounded, shaderReplaced, opacity, blend, filter, filters, w, h) {
|
|
1147
1211
|
const hasFilter = filter !== void 0 && filter !== "none";
|
|
1148
1212
|
const outset = hasFilter ? filterOutset(filters) : 0;
|
|
@@ -1295,7 +1359,7 @@ var Raster2D = class {
|
|
|
1295
1359
|
if (lruKey !== void 0) {
|
|
1296
1360
|
const hit = this.cacheTouch(lruKey);
|
|
1297
1361
|
if (hit) {
|
|
1298
|
-
this.composite(parent, top(), hit.canvas, hit.bounds, hit.unbounded, false, cmd.opacity, cmd.blend, filtersToCanvasFilter(cmd.filters), cmd.filters, w, h);
|
|
1362
|
+
this.composite(parent, top(), hit.canvas, hit.bounds, hit.unbounded, false, cmd.opacity, cmd.matte !== void 0 ? "destination-in" : cmd.blend, filtersToCanvasFilter(cmd.filters), cmd.filters, w, h);
|
|
1299
1363
|
let depth = 1;
|
|
1300
1364
|
while (depth > 0 && ++ci < commands.length) {
|
|
1301
1365
|
const c = commands[ci];
|
|
@@ -1317,7 +1381,7 @@ var Raster2D = class {
|
|
|
1317
1381
|
bounds: disk.bounds,
|
|
1318
1382
|
unbounded: disk.unbounded
|
|
1319
1383
|
});
|
|
1320
|
-
this.composite(parent, top(), canvas, disk.bounds, disk.unbounded, false, cmd.opacity, cmd.blend, filtersToCanvasFilter(cmd.filters), cmd.filters, w, h);
|
|
1384
|
+
this.composite(parent, top(), canvas, disk.bounds, disk.unbounded, false, cmd.opacity, cmd.matte !== void 0 ? "destination-in" : cmd.blend, filtersToCanvasFilter(cmd.filters), cmd.filters, w, h);
|
|
1321
1385
|
let depth = 1;
|
|
1322
1386
|
while (depth > 0 && ++ci < commands.length) {
|
|
1323
1387
|
const c = commands[ci];
|
|
@@ -1340,6 +1404,7 @@ var Raster2D = class {
|
|
|
1340
1404
|
filter: filtersToCanvasFilter(cmd.filters),
|
|
1341
1405
|
filters: cmd.filters,
|
|
1342
1406
|
...cmd.shader !== void 0 ? { shader: cmd.shader } : {},
|
|
1407
|
+
...cmd.matte !== void 0 ? { matte: cmd.matte } : {},
|
|
1343
1408
|
bounds: null,
|
|
1344
1409
|
unbounded: false,
|
|
1345
1410
|
...lruKey !== void 0 ? { cacheStoreKey: lruKey } : {}
|
|
@@ -1370,7 +1435,8 @@ var Raster2D = class {
|
|
|
1370
1435
|
emitDevWarning("ShaderEffect pass skipped: no shader runner here (headless or webgpu-less browser) — subtree composites unfiltered (§3.7 caps.shaders)");
|
|
1371
1436
|
}
|
|
1372
1437
|
}
|
|
1373
|
-
|
|
1438
|
+
if (layer.matte === "luma" && !shaderReplaced) this.lumaToAlpha(layer.ctx, w, h);
|
|
1439
|
+
this.composite(parent, top(), drawable, layer.bounds, layer.unbounded, shaderReplaced, layer.opacity, layer.matte !== void 0 ? "destination-in" : layer.blend, layer.filter, layer.filters, w, h);
|
|
1374
1440
|
if (layer.cacheStoreKey !== void 0 && !shaderReplaced) {
|
|
1375
1441
|
this.cacheStore(layer.cacheStoreKey, {
|
|
1376
1442
|
canvas: layer.canvas,
|
|
@@ -1396,4 +1462,4 @@ var Raster2D = class {
|
|
|
1396
1462
|
}
|
|
1397
1463
|
};
|
|
1398
1464
|
//#endregion
|
|
1399
|
-
export { ALL_FILTER_KINDS, Circle, ColdAssetError, Custom, DeterminismViolationError, DuplicateNodeIdError, EachError, Echo, FilterValidationError, Group, Highlight, IDENTITY, ImageNode as Image, ImageNode, LayoutEngineMissingError, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, MotionBlur, NODE_TAXONOMY, Node, NodeConstructionError, Path, Raster2D, Rect, ReservedNodeIdError, ShaderEffect, SketchValidationError, Text, TextCursor, Video, __resetEstimateWarnings, applyToPoint, arcLength, assertFiniteFontSize, bindScene, breakLines, coercePathData, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, drawOn, drawOnEach, each, echo, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, fontString, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, isEstimatingMeasurer, matEquals, measureWrappedText, meshRasterSize, motionBlur, multiply, pathFromSegs, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
|
|
1465
|
+
export { ALL_FILTER_KINDS, Circle, ColdAssetError, Custom, DeterminismViolationError, DuplicateNodeIdError, EachError, Echo, FilterValidationError, Group, Highlight, IDENTITY, ImageNode as Image, ImageNode, LayoutEngineMissingError, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, MotionBlur, NODE_TAXONOMY, Node, NodeConstructionError, Path, Raster2D, Rect, ReservedNodeIdError, ShaderEffect, SketchValidationError, Text, TextCursor, TrackMatte, Video, __resetEstimateWarnings, applyToPoint, arcLength, assertFiniteFontSize, bindScene, breakLines, coercePathData, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, drawOn, drawOnEach, each, echo, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, fontString, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, isEstimatingMeasurer, matEquals, measureWrappedText, meshRasterSize, motionBlur, multiply, pathFromSegs, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, trackMatte, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
|
package/dist/layoutCtors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as DisplayListBuilder } from "./displayList.js";
|
|
2
|
-
import {
|
|
2
|
+
import { B as Node, H as NodeProps, K as TextMeasurer, R as EvalContext, U as PropInit, a as Group } from "./nodes.js";
|
|
3
3
|
import { r as LayoutContainerSpec } from "./layoutEngine.js";
|
|
4
4
|
import { BindableSignal } from "@glissade/core";
|
|
5
5
|
|
package/dist/motion.d.ts
CHANGED
package/dist/nodes.d.ts
CHANGED
|
@@ -434,6 +434,22 @@ declare function sketchStrokes(segs: readonly PathSeg[], style: SketchStyle, see
|
|
|
434
434
|
declare abstract class Custom extends Node {}
|
|
435
435
|
/** Rounded-rect path segments — Rect's outline, shared with Highlight. */
|
|
436
436
|
declare function roundedRectSegs(x: number, y: number, w: number, h: number, r: number): PathSeg[];
|
|
437
|
+
/**
|
|
438
|
+
* A Group clip region (0.34), in the group's LOCAL coordinates: a (rounded)
|
|
439
|
+
* rect centered on `[x ?? 0, y ?? 0]` — matching the center-anchor convention —
|
|
440
|
+
* or an explicit `PathSeg[]` outline (`pathFromSvg(...)` output works directly).
|
|
441
|
+
* Children paint only inside the region; it clips the group's own layer, so a
|
|
442
|
+
* rounded corner anti-aliases in LOCAL space and the whole subtree byte-compares
|
|
443
|
+
* on Skia. Construction-only (not a track target); clipping is render-time only
|
|
444
|
+
* — hit-testing is unaffected in v1 (a clipped child still hits).
|
|
445
|
+
*/
|
|
446
|
+
type ClipRegion = {
|
|
447
|
+
w: number;
|
|
448
|
+
h: number;
|
|
449
|
+
r?: number;
|
|
450
|
+
x?: number;
|
|
451
|
+
y?: number;
|
|
452
|
+
} | PathSeg[];
|
|
437
453
|
declare class Group extends Node {
|
|
438
454
|
#private;
|
|
439
455
|
/**
|
|
@@ -448,8 +464,11 @@ declare class Group extends Node {
|
|
|
448
464
|
*/
|
|
449
465
|
get describeType(): string;
|
|
450
466
|
readonly children: Node[];
|
|
467
|
+
/** Clip region for this group's children (0.34) — see {@link ClipRegion}. */
|
|
468
|
+
readonly clip?: ClipRegion;
|
|
451
469
|
constructor(props?: NodeProps & {
|
|
452
470
|
children?: Node[];
|
|
471
|
+
clip?: ClipRegion;
|
|
453
472
|
});
|
|
454
473
|
/** Record the structural version as a dependency — call inside a computed
|
|
455
474
|
* that walks `children` so add()/remove() invalidate it. */
|
|
@@ -457,6 +476,10 @@ declare class Group extends Node {
|
|
|
457
476
|
add(child: Node): this;
|
|
458
477
|
/** Remove a child (the reactive counterpart to add()); no-op if absent. */
|
|
459
478
|
remove(child: Node): this;
|
|
479
|
+
/** A clip demands a group layer: children must rasterize into an isolated
|
|
480
|
+
* layer the region applies to (and the clip op lands INSIDE the cacheKey'd
|
|
481
|
+
* draw slice, so a changed region correctly misses the layer cache). */
|
|
482
|
+
protected requiresGroup(): boolean;
|
|
460
483
|
protected draw(out: DisplayListBuilder, ctx: EvalContext): void;
|
|
461
484
|
}
|
|
462
485
|
/** A color string is sugar for a solid `color` Paint; a Paint passes through. */
|
|
@@ -900,4 +923,4 @@ interface RevealMark {
|
|
|
900
923
|
*/
|
|
901
924
|
declare function revealSchedule(text: Text, reveal: Track<number>, measurer?: TextMeasurer): RevealMark[];
|
|
902
925
|
//#endregion
|
|
903
|
-
export {
|
|
926
|
+
export { isEstimatingMeasurer as $, hachureLines as A, Node as B, HachureSpec as C, SketchValidationError as D, SketchStyle as E, validateSketch as F, MEASURE_QUANTUM_PX as G, NodeProps as H, AnchorSpec as I, WrappedTextMetrics as J, TextMeasurer as K, BindablePropTarget as L, roughen as M, sketchStrokes as N, arcLength as O, validateHachure as P, estimatingMeasurer as Q, EvalContext as R, roundedRectSegs as S, ResolvedSketch as T, PropInit as U, NodeConstructionError as V, resolveAnchor as W, assertFiniteFontSize as X, __resetEstimateWarnings as Y, breakLines as Z, VideoProps as _, Group as a, pathFromSegs as b, LineBox as c, Rect as d, measureWrappedText as et, RevealMark as f, Video as g, TextProps as h, GraphemeBox as i, setDefaultMeasurer as it, resolveSketch as j, flatten as k, Path as l, Text as m, ClipRegion as n, segmentGraphemes as nt, ImageNode as o, ShapeProps as p, TextMetricsLite as q, Custom as r, segmentWords as rt, ImageProps as s, Circle as t, quantize as tt, PathProps as u, WordBox as v, Polyline as w, revealSchedule as x, coercePathData as y, HitArea as z };
|
package/dist/nodes.js
CHANGED
|
@@ -469,7 +469,7 @@ const LAYOUT = [
|
|
|
469
469
|
"children"
|
|
470
470
|
];
|
|
471
471
|
const NODE_CONSTRUCTION_PROP_NAMES = {
|
|
472
|
-
Group: ["children"],
|
|
472
|
+
Group: ["children", "clip"],
|
|
473
473
|
Rect: SKETCH,
|
|
474
474
|
Circle: SKETCH,
|
|
475
475
|
Path: SKETCH,
|
|
@@ -1251,6 +1251,8 @@ var Group = class Group extends Node {
|
|
|
1251
1251
|
return "Group";
|
|
1252
1252
|
}
|
|
1253
1253
|
children;
|
|
1254
|
+
/** Clip region for this group's children (0.34) — see {@link ClipRegion}. */
|
|
1255
|
+
clip;
|
|
1254
1256
|
/** Version bumped on structural child mutation, so a dependency-tracked memo
|
|
1255
1257
|
* (e.g. Layout's computed) re-runs when the child SET changes — not only when
|
|
1256
1258
|
* a participating prop signal does. */
|
|
@@ -1258,6 +1260,7 @@ var Group = class Group extends Node {
|
|
|
1258
1260
|
constructor(props = {}) {
|
|
1259
1261
|
super(props);
|
|
1260
1262
|
this.children = props.children ?? [];
|
|
1263
|
+
if (props.clip !== void 0) this.clip = props.clip;
|
|
1261
1264
|
for (const child of this.children) child.parent = this;
|
|
1262
1265
|
if (new.target === Group) this.checkProps(props);
|
|
1263
1266
|
}
|
|
@@ -1282,12 +1285,31 @@ var Group = class Group extends Node {
|
|
|
1282
1285
|
}
|
|
1283
1286
|
return this;
|
|
1284
1287
|
}
|
|
1288
|
+
/** A clip demands a group layer: children must rasterize into an isolated
|
|
1289
|
+
* layer the region applies to (and the clip op lands INSIDE the cacheKey'd
|
|
1290
|
+
* draw slice, so a changed region correctly misses the layer cache). */
|
|
1291
|
+
requiresGroup() {
|
|
1292
|
+
return this.clip !== void 0 || super.requiresGroup();
|
|
1293
|
+
}
|
|
1285
1294
|
draw(out, ctx) {
|
|
1295
|
+
if (this.clip !== void 0) {
|
|
1296
|
+
const segs = Array.isArray(this.clip) ? this.clip : roundedRectSegs((this.clip.x ?? 0) - this.clip.w / 2, (this.clip.y ?? 0) - this.clip.h / 2, this.clip.w, this.clip.h, this.clip.r ?? 0);
|
|
1297
|
+
out.push({ op: "save" });
|
|
1298
|
+
out.push({
|
|
1299
|
+
op: "clip",
|
|
1300
|
+
path: out.resource({
|
|
1301
|
+
kind: "path",
|
|
1302
|
+
segs
|
|
1303
|
+
}),
|
|
1304
|
+
rule: "nonzero"
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1286
1307
|
const sorted = this.children.map((node, i) => ({
|
|
1287
1308
|
node,
|
|
1288
1309
|
i
|
|
1289
1310
|
})).sort((a, b) => a.node.zIndex() - b.node.zIndex() || a.i - b.i).map((e) => e.node);
|
|
1290
1311
|
for (const child of sorted) child.emit(out, ctx);
|
|
1312
|
+
if (this.clip !== void 0) out.push({ op: "restore" });
|
|
1291
1313
|
}
|
|
1292
1314
|
};
|
|
1293
1315
|
/** A color string is sugar for a solid `color` Paint; a Paint passes through. */
|
package/dist/scene.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as DisplayList, s as FontSpec } from "./displayList.js";
|
|
2
|
-
import {
|
|
2
|
+
import { B as Node, J as WrappedTextMetrics, K as TextMeasurer, L as BindablePropTarget, a as Group } from "./nodes.js";
|
|
3
3
|
import { BoundTimeline, CompiledTimeline, Playhead, Timeline } from "@glissade/core";
|
|
4
4
|
|
|
5
5
|
//#region src/scene.d.ts
|
package/dist/tokens.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as DisplayListBuilder } from "./displayList.js";
|
|
2
|
-
import {
|
|
2
|
+
import { B as Node, H as NodeProps, R as EvalContext, U as PropInit, m as Text, v as WordBox } from "./nodes.js";
|
|
3
3
|
import { Vec2 } from "@glissade/core";
|
|
4
4
|
|
|
5
5
|
//#region src/tokenHighlight.d.ts
|
package/dist/type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as TextMeasurer, a as Group, c as LineBox, h as TextProps, i as GraphemeBox, m as Text, v as WordBox } from "./nodes.js";
|
|
2
2
|
|
|
3
3
|
//#region src/type.d.ts
|
|
4
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/scene",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0-pre.1",
|
|
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": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
],
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"yoga-layout": "^3.2.1",
|
|
72
|
-
"@glissade/core": "0.
|
|
72
|
+
"@glissade/core": "0.34.0-pre.1"
|
|
73
73
|
},
|
|
74
74
|
"repository": {
|
|
75
75
|
"type": "git",
|