@glissade/scene 0.23.0-pre.0 → 0.23.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/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.23.0-pre.0";
25
+ const RAW_VERSION = "0.23.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) {
package/dist/nodes.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { C as Mat2x3, a as FilterSpec, d as Paint, f as PathSeg, g as ShaderRef, r as DisplayListBuilder, s as FontSpec, t as BlendMode } from "./displayList.js";
2
- import { BindableSignal, PathValue, ReadonlySignal, Rng, Track, ValueTypeId, Vec2, Vec2Signal } from "@glissade/core";
2
+ import { BindableSignal, FontAxes, PathValue, ReadonlySignal, Rng, Track, ValueTypeId, Vec2, Vec2Signal } from "@glissade/core";
3
3
 
4
4
  //#region src/text.d.ts
5
5
 
@@ -682,14 +682,23 @@ interface TextProps extends NodeProps {
682
682
  * `ctx.fontVariationSettings`) renders the axes; the browser DOM 2D context
683
683
  * has no such property, so axes are best-effort there (a guarded no-op, never
684
684
  * a throw). OMITTED when unset, so default Text emits a byte-identical
685
- * FontSpec. Axes are STATIC only in 0.20 **animatable** axes (a `wght`
686
- * track, `opsz` driven by size, …) are deferred to 1.0 (an opaque CSS string
687
- * isn't lerp-able); a track targeting `<id>/fontVariationSettings` hard-throws
688
- * `UnboundTargetError` today (no property signal resolves to it). For a
689
- * dynamic weight, use the discrete `fontWeight` named instances your font
690
- * ships.
685
+ * FontSpec. This is the STATIC form (an opaque CSS string isn't lerp-able);
686
+ * to ANIMATE an axis (`wght`, `opsz`, …), use {@link fontAxes} instead a
687
+ * structured, per-axis-interpolated map (0.23). When both are given, `fontAxes`
688
+ * (if non-empty) wins.
691
689
  */
692
690
  fontVariationSettings?: string;
691
+ /**
692
+ * Variable-font axes as a STRUCTURED, ANIMATABLE map — `{ wght: 700, opsz: 14 }`
693
+ * (0.23). Unlike the opaque {@link fontVariationSettings} string, this is a
694
+ * lerp-able value type (`fontAxes`): a track on `<id>/fontAxes` interpolates
695
+ * each axis per-frame, formatted to the CSS `font-variation-settings` string at
696
+ * draw (so backends are unchanged). Both keyframes of a track must declare the
697
+ * SAME axis tags (a mismatched set snaps + warns, like path/paint topology).
698
+ * Empty/unset ⇒ omitted, so default Text stays byte-identical. Track target
699
+ * `<id>/fontAxes`, value type `fontAxes`.
700
+ */
701
+ fontAxes?: PropInit<FontAxes>;
693
702
  /** Horizontal alignment about the node position; default 'left'. */
694
703
  align?: 'left' | 'center' | 'right';
695
704
  /** Wrap width in px; unset = no wrapping (explicit \n still breaks). */
@@ -736,6 +745,9 @@ declare class Text extends Node {
736
745
  readonly fontStyle: 'normal' | 'italic';
737
746
  /** Static variable-font axes (CSS `font-variation-settings`); undefined = none. */
738
747
  readonly fontVariationSettings: string | undefined;
748
+ /** Animatable variable-font axes (track target `<id>/fontAxes`); empty = none.
749
+ * When non-empty, overrides {@link fontVariationSettings} in the FontSpec. */
750
+ readonly fontAxes: BindableSignal<FontAxes>;
739
751
  readonly align: 'left' | 'center' | 'right';
740
752
  readonly width: BindableSignal<number>;
741
753
  readonly lineHeight: number;
package/dist/nodes.js CHANGED
@@ -1844,6 +1844,12 @@ var Video = class Video extends Node {
1844
1844
  });
1845
1845
  }
1846
1846
  };
1847
+ /** Format a variable-font axis map → the CSS `font-variation-settings` string,
1848
+ * `'"wght" 700, "opsz" 14'`. Axis tags are SORTED so the same axes always emit
1849
+ * the same string regardless of insertion order — a deterministic FontSpec. */
1850
+ function formatFontAxes(axes) {
1851
+ return Object.keys(axes).sort().map((tag) => `"${tag}" ${axes[tag]}`).join(", ");
1852
+ }
1847
1853
  var Text = class Text extends Node {
1848
1854
  /** Taxonomy name pinned literally (survives IIFE minification — see {@link Group}). */
1849
1855
  get describeType() {
@@ -1857,6 +1863,9 @@ var Text = class Text extends Node {
1857
1863
  fontStyle;
1858
1864
  /** Static variable-font axes (CSS `font-variation-settings`); undefined = none. */
1859
1865
  fontVariationSettings;
1866
+ /** Animatable variable-font axes (track target `<id>/fontAxes`); empty = none.
1867
+ * When non-empty, overrides {@link fontVariationSettings} in the FontSpec. */
1868
+ fontAxes;
1860
1869
  align;
1861
1870
  width;
1862
1871
  lineHeight;
@@ -1878,6 +1887,7 @@ var Text = class Text extends Node {
1878
1887
  this.fontWeight = props.fontWeight ?? 400;
1879
1888
  this.fontStyle = props.fontStyle ?? "normal";
1880
1889
  this.fontVariationSettings = props.fontVariationSettings;
1890
+ this.fontAxes = initProp(signal({}), props.fontAxes);
1881
1891
  this.align = props.align ?? "left";
1882
1892
  this.width = initProp(signal(0), props.width);
1883
1893
  this.lineHeight = props.lineHeight ?? 1.25;
@@ -1890,6 +1900,7 @@ var Text = class Text extends Node {
1890
1900
  this.registerTarget("fontSize", this.fontSize, "number");
1891
1901
  this.registerTarget("reveal", this.reveal, "number");
1892
1902
  this.registerTarget("revealFraction", this.revealFraction, "number");
1903
+ this.registerTarget("fontAxes", this.fontAxes, "fontAxes");
1893
1904
  if (new.target === Text) this.checkProps(props);
1894
1905
  }
1895
1906
  /**
@@ -1900,12 +1911,14 @@ var Text = class Text extends Node {
1900
1911
  * golden corpus depends on it).
1901
1912
  */
1902
1913
  fontSpec() {
1914
+ const axes = this.fontAxes();
1915
+ const fvs = Object.keys(axes).length > 0 ? formatFontAxes(axes) : this.fontVariationSettings;
1903
1916
  return {
1904
1917
  family: this.fontFamily,
1905
1918
  size: this.fontSize(),
1906
1919
  weight: this.fontWeight,
1907
1920
  ...this.fontStyle === "italic" ? { style: "italic" } : {},
1908
- ...this.fontVariationSettings !== void 0 ? { fontVariationSettings: this.fontVariationSettings } : {},
1921
+ ...fvs !== void 0 ? { fontVariationSettings: fvs } : {},
1909
1922
  ...this.letterSpacing !== void 0 ? { letterSpacing: this.letterSpacing } : {}
1910
1923
  };
1911
1924
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glissade/scene",
3
- "version": "0.23.0-pre.0",
3
+ "version": "0.23.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": {
@@ -59,7 +59,7 @@
59
59
  ],
60
60
  "dependencies": {
61
61
  "yoga-layout": "^3.2.1",
62
- "@glissade/core": "0.23.0-pre.0"
62
+ "@glissade/core": "0.23.0-pre.1"
63
63
  },
64
64
  "repository": {
65
65
  "type": "git",