@motionscript/plot 0.0.0-stage → 0.1.0-alpha.3

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.
Files changed (102) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +201 -0
  3. package/dist/browser/chunks/chunk-37IWXGPH.js +2 -0
  4. package/dist/browser/chunks/chunk-37IWXGPH.js.map +7 -0
  5. package/dist/browser/index.js +84 -0
  6. package/dist/browser/index.js.map +7 -0
  7. package/dist/browser/kit.js +2 -0
  8. package/dist/browser/kit.js.map +7 -0
  9. package/dist/browser/manifest.json +12 -0
  10. package/dist/engine.d.ts +14 -0
  11. package/dist/engine.d.ts.map +1 -0
  12. package/dist/engine.js +14 -0
  13. package/dist/engine.js.map +1 -0
  14. package/dist/graph2d/curve-cache.d.ts +60 -0
  15. package/dist/graph2d/curve-cache.d.ts.map +1 -0
  16. package/dist/graph2d/curve-cache.js +79 -0
  17. package/dist/graph2d/curve-cache.js.map +1 -0
  18. package/dist/graph2d/curve-error.d.ts +12 -0
  19. package/dist/graph2d/curve-error.d.ts.map +1 -0
  20. package/dist/graph2d/curve-error.js +15 -0
  21. package/dist/graph2d/curve-error.js.map +1 -0
  22. package/dist/graph2d/curve.d.ts +104 -0
  23. package/dist/graph2d/curve.d.ts.map +1 -0
  24. package/dist/graph2d/curve.js +531 -0
  25. package/dist/graph2d/curve.js.map +1 -0
  26. package/dist/graph2d/graph2d.d.ts +164 -0
  27. package/dist/graph2d/graph2d.d.ts.map +1 -0
  28. package/dist/graph2d/graph2d.js +404 -0
  29. package/dist/graph2d/graph2d.js.map +1 -0
  30. package/dist/graph2d/index.d.ts +32 -0
  31. package/dist/graph2d/index.d.ts.map +1 -0
  32. package/dist/graph2d/index.js +32 -0
  33. package/dist/graph2d/index.js.map +1 -0
  34. package/dist/graph2d/plane-fill.d.ts +110 -0
  35. package/dist/graph2d/plane-fill.d.ts.map +1 -0
  36. package/dist/graph2d/plane-fill.js +248 -0
  37. package/dist/graph2d/plane-fill.js.map +1 -0
  38. package/dist/graph2d/plane.d.ts +179 -0
  39. package/dist/graph2d/plane.d.ts.map +1 -0
  40. package/dist/graph2d/plane.js +359 -0
  41. package/dist/graph2d/plane.js.map +1 -0
  42. package/dist/graph2d/shared.d.ts +40 -0
  43. package/dist/graph2d/shared.d.ts.map +1 -0
  44. package/dist/graph2d/shared.js +70 -0
  45. package/dist/graph2d/shared.js.map +1 -0
  46. package/dist/graph3d/expression.d.ts +30 -0
  47. package/dist/graph3d/expression.d.ts.map +1 -0
  48. package/dist/graph3d/expression.js +35 -0
  49. package/dist/graph3d/expression.js.map +1 -0
  50. package/dist/graph3d/graph3d.d.ts +186 -0
  51. package/dist/graph3d/graph3d.d.ts.map +1 -0
  52. package/dist/graph3d/graph3d.js +404 -0
  53. package/dist/graph3d/graph3d.js.map +1 -0
  54. package/dist/graph3d/index.d.ts +22 -0
  55. package/dist/graph3d/index.d.ts.map +1 -0
  56. package/dist/graph3d/index.js +22 -0
  57. package/dist/graph3d/index.js.map +1 -0
  58. package/dist/graph3d/shared.d.ts +61 -0
  59. package/dist/graph3d/shared.d.ts.map +1 -0
  60. package/dist/graph3d/shared.js +101 -0
  61. package/dist/graph3d/shared.js.map +1 -0
  62. package/dist/index.d.ts +4 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +4 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/kit/equations.d.ts +56 -0
  67. package/dist/kit/equations.d.ts.map +1 -0
  68. package/dist/kit/equations.js +63 -0
  69. package/dist/kit/equations.js.map +1 -0
  70. package/dist/kit/expression.d.ts +60 -0
  71. package/dist/kit/expression.d.ts.map +1 -0
  72. package/dist/kit/expression.js +268 -0
  73. package/dist/kit/expression.js.map +1 -0
  74. package/dist/kit/index.d.ts +15 -0
  75. package/dist/kit/index.d.ts.map +1 -0
  76. package/dist/kit/index.js +13 -0
  77. package/dist/kit/index.js.map +1 -0
  78. package/dist/nodes.d.ts +19 -0
  79. package/dist/nodes.d.ts.map +1 -0
  80. package/dist/nodes.js +19 -0
  81. package/dist/nodes.js.map +1 -0
  82. package/package.json +68 -3
  83. package/registry.json +34 -0
  84. package/src/engine.ts +13 -0
  85. package/src/graph2d/curve-cache.ts +103 -0
  86. package/src/graph2d/curve-error.ts +19 -0
  87. package/src/graph2d/curve.ts +657 -0
  88. package/src/graph2d/graph2d.ts +586 -0
  89. package/src/graph2d/index.ts +31 -0
  90. package/src/graph2d/plane-fill.ts +308 -0
  91. package/src/graph2d/plane.ts +457 -0
  92. package/src/graph2d/shared.ts +103 -0
  93. package/src/graph3d/expression.ts +51 -0
  94. package/src/graph3d/graph3d.ts +615 -0
  95. package/src/graph3d/index.ts +21 -0
  96. package/src/graph3d/shared.ts +143 -0
  97. package/src/index.ts +3 -0
  98. package/src/kit/equations.ts +102 -0
  99. package/src/kit/expression.ts +323 -0
  100. package/src/kit/index.ts +29 -0
  101. package/src/nodes.ts +19 -0
  102. package/README.md +0 -4
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The mappers and tweens the {@link Graph2D} node is built from — the same shape
3
+ * `graph3d/impl/shared.ts` has, and mostly the same short list, because a
4
+ * `@property` is only as good as the `mapper`/`tween` it is declared with.
5
+ *
6
+ * Almost everything here is a re-export. That is the point: the match-by-id
7
+ * equation tween lives in `nodes/graph-kit` because both graphs animate a list of
8
+ * equations the same way, and colour normalisation lives in `nodes/view3d-kit`
9
+ * because the 3D nodes needed it first. What is genuinely this node's own is one
10
+ * function: turning a two-argument compiled expression into the one-argument
11
+ * curve the sampler asks for, without losing the identity the tween compares.
12
+ */
13
+ import { CURVE_VARIABLES, compileExpressionCached, lerpGraphEquations, } from "../kit/index.js";
14
+ /**
15
+ * Colour normalisation and its tween, plus the two number tweens that fix what a
16
+ * plain lerp gets wrong.
17
+ *
18
+ * They live in `view3d-kit` because the 3D nodes needed them first, and there is
19
+ * nothing three-dimensional about any of them — a `NormalizedColor` is an RGBA
20
+ * tuple, which is both interpolatable and still a valid `Color` to hand back to
21
+ * `Graphics`. Renamed on the way through so the call sites don't read as though
22
+ * this node draws in perspective.
23
+ */
24
+ export { resolveColor3D as resolveColor, lerpColor3D as lerpColor, lerpCount, snapFlag, snapValue, } from "@motionscript/sdk/component";
25
+ /**
26
+ * Compiles `source` as `y = f(x)`, memoised, returning `null` for anything that
27
+ * doesn't parse.
28
+ *
29
+ * Two caches deep and both earn their place. The inner one memoises the *parse*,
30
+ * which is what keeps a node that re-draws sixty times a second from re-reading
31
+ * its own expressions; this one memoises the **adapter**, and without it every
32
+ * write would produce a fresh closure over the same parse — which the equation
33
+ * tween reads as "this expression changed" and would blend a function into
34
+ * itself, at double the sampling cost, for no visible difference.
35
+ *
36
+ * The adapter exists because arity is fixed in the parser for the sake of the
37
+ * hot path (see `CompiledExpression`) while the sampler quite reasonably wants
38
+ * to call `f(x)`. The unused second argument is 0 and unreachable: a curve is
39
+ * compiled with `x` as its only variable, so nothing in the tree reads it.
40
+ */
41
+ const curves = new Map();
42
+ export function compileCurveCached(source) {
43
+ const trimmed = source.trim();
44
+ if (trimmed === "")
45
+ return null;
46
+ const hit = curves.get(trimmed);
47
+ if (hit !== undefined)
48
+ return hit;
49
+ const compiled = compileExpressionCached(trimmed, CURVE_VARIABLES);
50
+ const curve = compiled === null ? null : (x) => compiled(x, 0);
51
+ curves.set(trimmed, curve);
52
+ return curve;
53
+ }
54
+ /**
55
+ * Tween for the curve list — the shared match-by-id walk, with the one thing a
56
+ * curve does differently: mid-morph its height is sampled from both functions
57
+ * and blended, so it deforms into the new one rather than cross-fading through
58
+ * a frame where both are drawn.
59
+ */
60
+ export function lerpCurves(from, to, t) {
61
+ return lerpGraphEquations(from, to, t, blendCurve);
62
+ }
63
+ /** How two curves blend mid-tween. */
64
+ function blendCurve(a, b, t) {
65
+ return (x) => {
66
+ const start = a(x);
67
+ return start + (b(x) - start) * t;
68
+ };
69
+ }
70
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/graph2d/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,GAEnB,MAAM,QAAQ,CAAA;AAGf;;;;;;;;;GASG;AACH,OAAO,EACL,cAAc,IAAI,YAAY,EAC9B,WAAW,IAAI,SAAS,EACxB,SAAS,EACT,QAAQ,EACR,SAAS,GACV,MAAM,6BAA6B,CAAA;AASpC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgC,CAAA;AAEtD,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;IAC7B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAE/B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC/B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAA;IAEjC,MAAM,QAAQ,GAAG,uBAAuB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;IAClE,MAAM,KAAK,GACT,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1D,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC1B,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,IAAqB,EACrB,EAAmB,EACnB,CAAS;IAET,OAAO,kBAAkB,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,UAAU,CAAC,CAAA;AACpD,CAAC;AAED,sCAAsC;AACtC,SAAS,UAAU,CACjB,CAAgB,EAChB,CAAgB,EAChB,CAAS;IAET,OAAO,CAAC,CAAC,EAAE,EAAE;QACX,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAClB,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IACnC,CAAC,CAAA;AACH,CAAC","sourcesContent":["/**\n * The mappers and tweens the {@link Graph2D} node is built from — the same shape\n * `graph3d/impl/shared.ts` has, and mostly the same short list, because a\n * `@property` is only as good as the `mapper`/`tween` it is declared with.\n *\n * Almost everything here is a re-export. That is the point: the match-by-id\n * equation tween lives in `nodes/graph-kit` because both graphs animate a list of\n * equations the same way, and colour normalisation lives in `nodes/view3d-kit`\n * because the 3D nodes needed it first. What is genuinely this node's own is one\n * function: turning a two-argument compiled expression into the one-argument\n * curve the sampler asks for, without losing the identity the tween compares.\n */\n\nimport {\n CURVE_VARIABLES,\n compileExpressionCached,\n lerpGraphEquations,\n type GraphEquationResolved,\n} from \"../kit\"\nimport type { CurveFunction } from \"./curve\"\n\n/**\n * Colour normalisation and its tween, plus the two number tweens that fix what a\n * plain lerp gets wrong.\n *\n * They live in `view3d-kit` because the 3D nodes needed them first, and there is\n * nothing three-dimensional about any of them — a `NormalizedColor` is an RGBA\n * tuple, which is both interpolatable and still a valid `Color` to hand back to\n * `Graphics`. Renamed on the way through so the call sites don't read as though\n * this node draws in perspective.\n */\nexport {\n resolveColor3D as resolveColor,\n lerpColor3D as lerpColor,\n lerpCount,\n snapFlag,\n snapValue,\n} from \"@motionscript/sdk/component\"\n\n/**\n * One curve after {@link Graph2D}'s mapper has run: compiled, resolved and fully\n * defaulted, so the per-frame draw never re-derives anything and the tween never\n * tests for an absent field.\n */\nexport type CurveResolved = GraphEquationResolved<CurveFunction>\n\n/**\n * Compiles `source` as `y = f(x)`, memoised, returning `null` for anything that\n * doesn't parse.\n *\n * Two caches deep and both earn their place. The inner one memoises the *parse*,\n * which is what keeps a node that re-draws sixty times a second from re-reading\n * its own expressions; this one memoises the **adapter**, and without it every\n * write would produce a fresh closure over the same parse — which the equation\n * tween reads as \"this expression changed\" and would blend a function into\n * itself, at double the sampling cost, for no visible difference.\n *\n * The adapter exists because arity is fixed in the parser for the sake of the\n * hot path (see `CompiledExpression`) while the sampler quite reasonably wants\n * to call `f(x)`. The unused second argument is 0 and unreachable: a curve is\n * compiled with `x` as its only variable, so nothing in the tree reads it.\n */\nconst curves = new Map<string, CurveFunction | null>()\n\nexport function compileCurveCached(source: string): CurveFunction | null {\n const trimmed = source.trim()\n if (trimmed === \"\") return null\n\n const hit = curves.get(trimmed)\n if (hit !== undefined) return hit\n\n const compiled = compileExpressionCached(trimmed, CURVE_VARIABLES)\n const curve: CurveFunction | null =\n compiled === null ? null : (x: number) => compiled(x, 0)\n curves.set(trimmed, curve)\n return curve\n}\n\n/**\n * Tween for the curve list — the shared match-by-id walk, with the one thing a\n * curve does differently: mid-morph its height is sampled from both functions\n * and blended, so it deforms into the new one rather than cross-fading through\n * a frame where both are drawn.\n */\nexport function lerpCurves(\n from: CurveResolved[],\n to: CurveResolved[],\n t: number\n): CurveResolved[] {\n return lerpGraphEquations(from, to, t, blendCurve)\n}\n\n/** How two curves blend mid-tween. */\nfunction blendCurve(\n a: CurveFunction,\n b: CurveFunction,\n t: number\n): CurveFunction {\n return (x) => {\n const start = a(x)\n return start + (b(x) - start) * t\n }\n}\n"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The `z = f(x, y)` expression language, as this node reaches for it.
3
+ *
4
+ * The parser itself now lives in `nodes/graph-kit/expression`, because the 2D
5
+ * graph writes its curves in the same language and neither node owns it — the
6
+ * same move `shared.ts` made when the Protein node needed the colour and camera
7
+ * helpers. What is left here is the *binding*: a surface's two free variables
8
+ * are `x` and `y`, which is the one thing about the grammar that differs between
9
+ * the two graphs, and every function below has it applied.
10
+ *
11
+ * Re-exported rather than re-implemented so this stays the one import a graph3d
12
+ * module reaches for, and so the vocabulary the inspector lists cannot drift
13
+ * from the names the parser will actually accept.
14
+ */
15
+ import { type CompiledExpression } from "../kit/expression.js";
16
+ export { EXPRESSION_VOCABULARY } from "../kit/expression.js";
17
+ export type { CompiledExpression, ExpressionVocabulary, } from "../kit/expression.js";
18
+ /** Compiles `source` as `z = f(x, y)`. Throws on a syntax error. */
19
+ export declare function compileExpression(source: string): CompiledExpression;
20
+ /** Why `source` won't compile as `z = f(x, y)`, or `null` when it does. */
21
+ export declare function expressionError(source: string): string | null;
22
+ /**
23
+ * Compiles with memoisation, returning `null` for anything that doesn't parse.
24
+ *
25
+ * The memoisation is what makes the equation tween cheap — equal source compiles
26
+ * to the identical closure, so "did this equation change" is an `===` — and what
27
+ * `surfaceRevision` reduces to a number. See the shared module for the rest.
28
+ */
29
+ export declare function compileExpressionCached(source: string): CompiledExpression | null;
30
+ //# sourceMappingURL=expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../src/graph3d/expression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAKL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,mBAAmB,CAAA;AAE1B,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAEpE;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7D;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,GACb,kBAAkB,GAAG,IAAI,CAE3B"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The `z = f(x, y)` expression language, as this node reaches for it.
3
+ *
4
+ * The parser itself now lives in `nodes/graph-kit/expression`, because the 2D
5
+ * graph writes its curves in the same language and neither node owns it — the
6
+ * same move `shared.ts` made when the Protein node needed the colour and camera
7
+ * helpers. What is left here is the *binding*: a surface's two free variables
8
+ * are `x` and `y`, which is the one thing about the grammar that differs between
9
+ * the two graphs, and every function below has it applied.
10
+ *
11
+ * Re-exported rather than re-implemented so this stays the one import a graph3d
12
+ * module reaches for, and so the vocabulary the inspector lists cannot drift
13
+ * from the names the parser will actually accept.
14
+ */
15
+ import { SURFACE_VARIABLES, compileExpression as compile, compileExpressionCached as compileCached, expressionError as errorOf, } from "../kit/expression.js";
16
+ export { EXPRESSION_VOCABULARY } from "../kit/expression.js";
17
+ /** Compiles `source` as `z = f(x, y)`. Throws on a syntax error. */
18
+ export function compileExpression(source) {
19
+ return compile(source, SURFACE_VARIABLES);
20
+ }
21
+ /** Why `source` won't compile as `z = f(x, y)`, or `null` when it does. */
22
+ export function expressionError(source) {
23
+ return errorOf(source, SURFACE_VARIABLES);
24
+ }
25
+ /**
26
+ * Compiles with memoisation, returning `null` for anything that doesn't parse.
27
+ *
28
+ * The memoisation is what makes the equation tween cheap — equal source compiles
29
+ * to the identical closure, so "did this equation change" is an `===` — and what
30
+ * `surfaceRevision` reduces to a number. See the shared module for the rest.
31
+ */
32
+ export function compileExpressionCached(source) {
33
+ return compileCached(source, SURFACE_VARIABLES);
34
+ }
35
+ //# sourceMappingURL=expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.js","sourceRoot":"","sources":["../../src/graph3d/expression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,IAAI,OAAO,EAC5B,uBAAuB,IAAI,aAAa,EACxC,eAAe,IAAI,OAAO,GAE3B,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAMzD,oEAAoE;AACpE,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAO,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;AAC3C,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,OAAO,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAc;IAEd,OAAO,aAAa,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;AACjD,CAAC","sourcesContent":["/**\n * The `z = f(x, y)` expression language, as this node reaches for it.\n *\n * The parser itself now lives in `nodes/graph-kit/expression`, because the 2D\n * graph writes its curves in the same language and neither node owns it — the\n * same move `shared.ts` made when the Protein node needed the colour and camera\n * helpers. What is left here is the *binding*: a surface's two free variables\n * are `x` and `y`, which is the one thing about the grammar that differs between\n * the two graphs, and every function below has it applied.\n *\n * Re-exported rather than re-implemented so this stays the one import a graph3d\n * module reaches for, and so the vocabulary the inspector lists cannot drift\n * from the names the parser will actually accept.\n */\n\nimport {\n SURFACE_VARIABLES,\n compileExpression as compile,\n compileExpressionCached as compileCached,\n expressionError as errorOf,\n type CompiledExpression,\n} from \"../kit/expression\"\n\nexport { EXPRESSION_VOCABULARY } from \"../kit/expression\"\nexport type {\n CompiledExpression,\n ExpressionVocabulary,\n} from \"../kit/expression\"\n\n/** Compiles `source` as `z = f(x, y)`. Throws on a syntax error. */\nexport function compileExpression(source: string): CompiledExpression {\n return compile(source, SURFACE_VARIABLES)\n}\n\n/** Why `source` won't compile as `z = f(x, y)`, or `null` when it does. */\nexport function expressionError(source: string): string | null {\n return errorOf(source, SURFACE_VARIABLES)\n}\n\n/**\n * Compiles with memoisation, returning `null` for anything that doesn't parse.\n *\n * The memoisation is what makes the equation tween cheap — equal source compiles\n * to the identical closure, so \"did this equation change\" is an `===` — and what\n * `surfaceRevision` reduces to a number. See the shared module for the rest.\n */\nexport function compileExpressionCached(\n source: string\n): CompiledExpression | null {\n return compileCached(source, SURFACE_VARIABLES)\n}\n"]}
@@ -0,0 +1,186 @@
1
+ import { type Command, type CommandArgs, Canvas3D, Scene3D, type Color, type NodeConfig, type Canvas3DProps } from "@motionscript/sdk";
2
+ import { type OrbitTarget } from "@motionscript/sdk/component";
3
+ /** One plotted surface, `z = f(x, y)`. */
4
+ export interface Graph3DEquation {
5
+ /** Identity across list changes — see {@link Graph3D.equations}. */
6
+ id: string | number;
7
+ /** The expression, evaluated as `z = f(x, y)` (e.g. `sin(x) + cos(y)`). */
8
+ expression: string;
9
+ /** The mesh's colour: any {@link Color} — a CSS string or an RGBA tuple. */
10
+ color: Color;
11
+ /** Whether the surface is drawn. Defaults to true. */
12
+ visible?: boolean;
13
+ /**
14
+ * How solid the mesh is, 0–1. Defaults to 1.
15
+ *
16
+ * Anything below 1 makes the surface blend rather than write depth, so
17
+ * overlapping surfaces layer instead of occluding each other. Left at 1 the
18
+ * surface is genuinely opaque and reads crisp — which is why that is the
19
+ * default, and why fading one in or out still looks right on the way through.
20
+ */
21
+ opacity?: number;
22
+ }
23
+ /**
24
+ * Where the camera may go.
25
+ *
26
+ * Deliberately *not* OrbitControls. Those drive a camera from live mouse input,
27
+ * and a rendered timeline has no pointer — worse, their damping is an
28
+ * accumulator, so a scrubbed frame would differ from a played one and export
29
+ * would stop being deterministic. What is honoured here is the framing
30
+ * ({@link initialPosition}) and the limits; to *move* the camera, animate
31
+ * {@link Graph3DProps.orbit} / {@link Graph3DProps.elevation} /
32
+ * {@link Graph3DProps.zoom} from the timeline, which stays seekable.
33
+ */
34
+ export interface Graph3DCamera {
35
+ /** Initial camera position, which seeds the three spherical props. */
36
+ initialPosition?: {
37
+ x: number;
38
+ y: number;
39
+ z: number;
40
+ };
41
+ /** Closest the camera may come to the origin. */
42
+ minZoom?: number;
43
+ /** Furthest it may pull back. */
44
+ maxZoom?: number;
45
+ }
46
+ /** The helper grid and the axes drawn under the surfaces. */
47
+ export interface Graph3DGrid {
48
+ /** Whether to draw the ground grid at all. Defaults to true. */
49
+ showGrid?: boolean;
50
+ /** Total width and depth of the grid. Defaults to 20. */
51
+ size?: number;
52
+ /** How many cells across. Defaults to 20. */
53
+ divisions?: number;
54
+ /** Colour of the two lines through the origin. */
55
+ colorCenterLine?: Color;
56
+ /** Colour of every other grid line. */
57
+ colorGrid?: Color;
58
+ /** Whether to draw the X/Y/Z axes. Defaults to true. */
59
+ showAxes?: boolean;
60
+ /** How far each axis reaches from the origin. Defaults to 10. */
61
+ axesSize?: number;
62
+ }
63
+ export interface Graph3DProps extends Canvas3DProps {
64
+ /** The surfaces to plot, each evaluated as `z = f(x, y)` over the domain. */
65
+ equations: Graph3DEquation[];
66
+ camera: Graph3DCamera;
67
+ grid: Graph3DGrid;
68
+ /** Half-width of the plotted domain: x and y run `-domain … +domain`. Default 10. */
69
+ domain: number;
70
+ /**
71
+ * Surface resolution per axis. Default 80, i.e. ~6.4k vertices per equation.
72
+ * Lower it when plotting several surfaces at once.
73
+ */
74
+ segments: number;
75
+ /**
76
+ * Clamp on `|z|`. Default 20. Without it a function with an asymptote (`1/x`,
77
+ * `tan`) produces near-infinite vertices that stretch the mesh across the
78
+ * whole scene and wreck the framing.
79
+ */
80
+ maxHeight: number;
81
+ /** Camera orbit about the vertical axis, in **degrees**. Animate this to spin. */
82
+ orbit: number;
83
+ /** Camera elevation above the ground plane, in **degrees**. */
84
+ elevation: number;
85
+ /** Camera distance from the origin, clamped by the camera's zoom limits. */
86
+ zoom: number;
87
+ /** The 3D scene's background. */
88
+ background: Color;
89
+ /** Skips the background entirely, letting the 2D scene behind show through. */
90
+ transparentBackground: boolean;
91
+ }
92
+ /**
93
+ * A 3D function grapher — any number of `z = f(x, y)` surfaces over a helper
94
+ * grid, with axes.
95
+ *
96
+ * Extends {@link Canvas3D} rather than `Node3D`: a grapher is a *viewport* on a
97
+ * scene it owns entirely, not a thing placed inside somebody else's. `Canvas3D`
98
+ * owns the bridge from the 2D scene graph into the 3D renderer, so subclassing
99
+ * it means this class only has to describe *what* to draw. It overrides
100
+ * `buildScene3D`, the single seam both the real render and the asset
101
+ * declaration pass go through.
102
+ *
103
+ * <Graph3D
104
+ * width="fill" height="fill"
105
+ * equations={[{ id: 1, expression: "sin(sqrt(x^2 + y^2))", color: "#3B82F6" }]}
106
+ * />
107
+ *
108
+ * Every prop is a `@property`, so a constant, a `() => signal()` binding, and
109
+ * `set()`/`to()` on a ref all work and agree. The non-scalar props each declare
110
+ * a `mapper` (loose authored shape → one canonical internal shape) and a `tween`
111
+ * (how that shape interpolates) — without the tween, `to({ grid: … })` would
112
+ * hold the old value and snap at the end, which is the standard trap for an
113
+ * object-valued attribute.
114
+ *
115
+ * **There is no OrbitControls and no pointer.** The camera is driven by the
116
+ * node's own `orbit`/`elevation`/`zoom` props, which is what keeps every frame
117
+ * reproducible under scrubbing and export — see {@link Graph3DCamera}.
118
+ */
119
+ export declare class Graph3D extends Canvas3D<Graph3DProps> {
120
+ /**
121
+ * The plotted surfaces.
122
+ *
123
+ * The mapper compiles each expression **once per write** (memoised by source),
124
+ * so the builder — which re-runs every frame — never re-parses; and it folds
125
+ * `visible`/`opacity` into a single number, so hiding is expressible as a
126
+ * fade. An expression that doesn't parse is dropped and the rest still draw,
127
+ * which is what lets the inspector commit on every keystroke.
128
+ *
129
+ * The tween matches the two lists by `id` — see `lerpEquations`.
130
+ */
131
+ equations: Graph3DEquation[];
132
+ /** The camera limits, and the framing that seeds the three spherical props. */
133
+ camera: Graph3DCamera;
134
+ /** The helper grid and axes. Flags snap at the end of a tween; the rest lerp. */
135
+ grid: Graph3DGrid;
136
+ domain: number;
137
+ /**
138
+ * Surface resolution. Tweenable, but *structural*: a geometry is immutable, so
139
+ * every intermediate value reallocates each surface's buffers. Set it once
140
+ * unless the resolution change is itself the point.
141
+ */
142
+ segments: number;
143
+ maxHeight: number;
144
+ background: Color;
145
+ transparentBackground: boolean;
146
+ orbit: number;
147
+ elevation: number;
148
+ zoom: number;
149
+ constructor(props?: NodeConfig<Graph3D, Graph3DProps>);
150
+ /**
151
+ * Frame the scene at a spherical camera placement. Every axis is optional,
152
+ * so "pull back" and "spin round" stay separate intentions — see
153
+ * {@link OrbitTarget}.
154
+ */
155
+ orbitTo(args: CommandArgs<{
156
+ target: OrbitTarget;
157
+ }> & {
158
+ duration: number;
159
+ }): Command<Graph3DProps>;
160
+ /**
161
+ * Seeds `orbit`/`elevation`/`zoom` from `camera.initialPosition`, so a caller
162
+ * who gives a raw position gets that framing and one who gives none gets
163
+ * {@link DEFAULT_POSITION} — without having to restate the other two axes.
164
+ *
165
+ * Bound reactively rather than copied, so the default *tracks* the camera and
166
+ * a camera signal keeps working. Writing any of the three (a `set`, or the
167
+ * first frame of a `to`) replaces the binding with the explicit value, which
168
+ * is exactly the handover wanted.
169
+ */
170
+ private applyCameraDefaults;
171
+ protected buildScene3D(): Scene3D;
172
+ /**
173
+ * One `z = f(x, y)` surface, keyed by equation id rather than by position in
174
+ * the op list — see {@link Graph3D.equations}.
175
+ */
176
+ private addSurface;
177
+ /**
178
+ * The ground grid, as two line ops — the centre cross and everything else —
179
+ * because a line op carries a single colour and the centre lines are drawn
180
+ * differently from the rest.
181
+ */
182
+ private addGrid;
183
+ /** X/Y/Z axes in red/green/blue, the conventional colouring. */
184
+ private addAxes;
185
+ }
186
+ //# sourceMappingURL=graph3d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph3d.d.ts","sourceRoot":"","sources":["../../src/graph3d/graph3d.ts"],"names":[],"mappings":"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"}