@pixerate/editor 0.240.0 → 0.242.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.
Files changed (67) hide show
  1. package/dist/animation-editor/controller.d.cts +10 -0
  2. package/dist/animation-editor/controller.d.ts +10 -0
  3. package/dist/animation-editor/effects.d.cts +1 -1
  4. package/dist/animation-editor/effects.d.ts +1 -1
  5. package/dist/animation-editor/index.cjs +195 -146
  6. package/dist/animation-editor/index.js +63 -14
  7. package/dist/{brushstrokeRender-WB67GMUP.js → brushstrokeRender-MOYGEXOC.js} +2 -2
  8. package/dist/{brushstrokeRender-MPOM7BFW.cjs → brushstrokeRender-UKADOV5D.cjs} +5 -5
  9. package/dist/canvas/index.cjs +15 -15
  10. package/dist/canvas/index.js +2 -2
  11. package/dist/{chunk-NKTNLJUJ.cjs → chunk-5BR7LC24.cjs} +99 -11
  12. package/dist/{chunk-ZXNO3ZOX.cjs → chunk-7F4G74UQ.cjs} +35 -35
  13. package/dist/{chunk-A7PQNIBX.cjs → chunk-7V7QMFTI.cjs} +14 -14
  14. package/dist/{chunk-AD7GA3TL.cjs → chunk-AFLMXITL.cjs} +23 -23
  15. package/dist/{chunk-JAOSL334.cjs → chunk-GHCSC2WP.cjs} +38 -16
  16. package/dist/{chunk-PP6BXVRL.cjs → chunk-HGGJ36HR.cjs} +1 -1
  17. package/dist/{chunk-BBUE3UJL.cjs → chunk-HW72ABGR.cjs} +86 -86
  18. package/dist/{chunk-7YGBSFC6.js → chunk-ILM6GYAX.js} +1 -1
  19. package/dist/{chunk-JWCKJNDR.cjs → chunk-K5DS2JTA.cjs} +6 -6
  20. package/dist/{chunk-THXFU3JB.cjs → chunk-KCMV2534.cjs} +2 -2
  21. package/dist/{chunk-WDDUPWVG.js → chunk-L3JFOTBQ.js} +1 -1
  22. package/dist/{chunk-3E36VDMJ.js → chunk-NE6OOKWJ.js} +1 -1
  23. package/dist/{chunk-SIK3LT6M.js → chunk-OFH6Q67U.js} +28 -6
  24. package/dist/{chunk-RV5DKZHU.js → chunk-QP2B3MID.js} +1 -1
  25. package/dist/{chunk-G3RUKJ5C.js → chunk-RXZL4NG5.js} +1 -1
  26. package/dist/{chunk-UUBO6RB5.js → chunk-UDBDYZET.js} +1 -1
  27. package/dist/{chunk-TEFQISBY.js → chunk-X3ZINLIP.js} +1 -1
  28. package/dist/{chunk-PJYG6FCF.js → chunk-XBZK47LV.js} +98 -10
  29. package/dist/{chunk-ZQIWBJGH.cjs → chunk-XNZFVYC2.cjs} +7 -7
  30. package/dist/{chunk-XK4SST43.js → chunk-ZDPLZDTT.js} +1 -1
  31. package/dist/effects/fake.d.cts +4 -0
  32. package/dist/effects/fake.d.ts +4 -0
  33. package/dist/effects/helpers.d.cts +6 -0
  34. package/dist/effects/helpers.d.ts +6 -0
  35. package/dist/effects/index.cjs +222 -94
  36. package/dist/effects/index.js +131 -3
  37. package/dist/effects/types.d.cts +31 -0
  38. package/dist/effects/types.d.ts +31 -0
  39. package/dist/image-editor/index.cjs +788 -788
  40. package/dist/image-editor/index.js +5 -5
  41. package/dist/paint-editor/controller.d.cts +67 -0
  42. package/dist/paint-editor/controller.d.ts +67 -0
  43. package/dist/paint-editor/effect-paint.d.cts +60 -3
  44. package/dist/paint-editor/effect-paint.d.ts +60 -3
  45. package/dist/paint-editor/index.cjs +682 -436
  46. package/dist/paint-editor/index.js +284 -38
  47. package/dist/paint-editor/stickers.d.cts +6 -0
  48. package/dist/paint-editor/stickers.d.ts +6 -0
  49. package/dist/paint-editor/thick.d.cts +4 -0
  50. package/dist/paint-editor/thick.d.ts +4 -0
  51. package/dist/paint-editor/wet.d.cts +8 -0
  52. package/dist/paint-editor/wet.d.ts +8 -0
  53. package/dist/vector/index.cjs +968 -968
  54. package/dist/vector/index.js +5 -5
  55. package/dist/video-editor/controller.d.cts +49 -1
  56. package/dist/video-editor/controller.d.ts +49 -1
  57. package/dist/video-editor/effect-path.d.cts +66 -0
  58. package/dist/video-editor/effect-path.d.ts +66 -0
  59. package/dist/video-editor/index.cjs +616 -427
  60. package/dist/video-editor/index.d.cts +1 -0
  61. package/dist/video-editor/index.d.ts +1 -0
  62. package/dist/video-editor/index.js +193 -4
  63. package/package.json +1 -1
  64. package/skills/pixerate-animation-editor/SKILL.md +1 -1
  65. package/skills/pixerate-paint-editor/SKILL.md +17 -21
  66. package/skills/pixerate-paint-editor/references/effect-paint.md +25 -0
  67. package/skills/pixerate-video-editor/SKILL.md +9 -2
@@ -3,7 +3,7 @@ import {
3
3
  } from "../chunk-N4ZXW3WB.js";
4
4
  import {
5
5
  createEffectAuthoringSession
6
- } from "../chunk-TEFQISBY.js";
6
+ } from "../chunk-X3ZINLIP.js";
7
7
  import {
8
8
  EFFECT_LAYER_USES,
9
9
  EFFECT_SEQUENCE_NAME,
@@ -28,16 +28,18 @@ import {
28
28
  templateSlotTakes,
29
29
  templateValueProblem,
30
30
  templateValuesSchema
31
- } from "../chunk-G3RUKJ5C.js";
31
+ } from "../chunk-RXZL4NG5.js";
32
32
  import {
33
33
  EffectRendererPool
34
34
  } from "../chunk-EHLOCVWB.js";
35
35
  import {
36
36
  CAMERA_MOVE_MAX_MS,
37
37
  CAMERA_MOVE_ROLES,
38
+ EFFECT_ACCEPTS,
38
39
  EFFECT_ERROR_CODES,
39
40
  EFFECT_KINDS,
40
41
  EFFECT_LAYER_ROLES,
42
+ EFFECT_PATH_FORMAT,
41
43
  EFFECT_SUBJECT_KINDS,
42
44
  EFFECT_TEMPLATE_SLOT_TYPES,
43
45
  EFFECT_TRANSITION_MS,
@@ -69,13 +71,14 @@ import {
69
71
  isEffectPixels,
70
72
  linearToSrgb,
71
73
  normaliseEffectTag,
74
+ pathControlsOf,
72
75
  resolveCameraMoveSpec,
73
76
  resolveEffectValues,
74
77
  sampleCameraViews,
75
78
  sampleEffectCameraMove,
76
79
  searchEffectSummaries,
77
80
  srgbToLinear
78
- } from "../chunk-SIK3LT6M.js";
81
+ } from "../chunk-OFH6Q67U.js";
79
82
  import "../chunk-V2ZCJRDM.js";
80
83
  import "../chunk-RNSANXPT.js";
81
84
  import {
@@ -105,6 +108,7 @@ function checkSummary(e, issues) {
105
108
  if (typeof e.loop !== "boolean") at("loop is not a boolean");
106
109
  if (e.duration !== void 0 && !(e.duration > 0)) at("duration must be a positive number of ms when present");
107
110
  if (e.backgroundOpacity !== void 0 && (typeof e.backgroundOpacity !== "string" || !e.backgroundOpacity)) at("backgroundOpacity must name a control when present");
111
+ for (const a of e.accepts ?? []) if (!EFFECT_ACCEPTS.includes(a)) at(`accepts "${a}" is not one of ${EFFECT_ACCEPTS.join(", ")}`);
108
112
  if (e.kind === "camera") {
109
113
  if (e.uses?.length !== 1 || e.uses[0] !== "camera") at('a camera effect must have exactly the use "camera"');
110
114
  const m = e.camera;
@@ -136,6 +140,9 @@ function checkDescription(id, d, issues) {
136
140
  if (!control) at(`backgroundOpacity "${d.backgroundOpacity}" is not a control`);
137
141
  else if (control.type !== "number" || control.minimum !== 0 || control.maximum !== 1) at(`backgroundOpacity "${d.backgroundOpacity}" must be a number control from 0 to 1`);
138
142
  }
143
+ const paths = pathControlsOf(d);
144
+ if (paths.length && !d.accepts?.includes("path")) at(`controls ${paths.map((p) => `"${p}"`).join(", ")} take a path, but accepts does not list "path"`);
145
+ if (!paths.length && d.accepts?.includes("path")) at('accepts lists "path", but no control has format "svg-path"');
139
146
  for (const e of effectValueErrors(d, d.defaults)) at(`default ${e.path}: ${e.message}`);
140
147
  for (const p of d.presets ?? []) for (const e of effectValueErrors(d, p.values)) at(`preset "${p.name}" ${e.path}: ${e.message}`);
141
148
  for (const input2 of d.inputs ?? []) {
@@ -547,6 +554,13 @@ function fakeTemplateMethods() {
547
554
  var HEX = "^#[0-9a-fA-F]{6}$";
548
555
  var colour = (description) => ({ type: "string", pattern: HEX, description });
549
556
  var amount = (description) => ({ type: "number", minimum: 0, maximum: 1, description });
557
+ var pathControl = (what) => ({
558
+ description: `${what}: SVG path data (fitted into the frame, contain, 8% margin), or points [x0, y0, x1, y1, \u2026] in frame pixels from the top left (used as given), or "" for none.`,
559
+ anyOf: [
560
+ { type: "string", format: "svg-path", description: 'SVG path data, or "" for no path.' },
561
+ { type: "array", items: { type: "number", description: "x or y, frame pixels." }, description: "Points x0, y0, x1, y1, \u2026 in frame pixels." }
562
+ ]
563
+ });
550
564
  var DESCRIPTIONS = [
551
565
  {
552
566
  id: "fake.invert",
@@ -711,8 +725,77 @@ var DESCRIPTIONS = [
711
725
  defaults: { color: "#f43f5e", ms: 500 },
712
726
  presets: [],
713
727
  inputs: []
728
+ },
729
+ {
730
+ id: "fake.trail",
731
+ name: "Trail",
732
+ kind: "shader",
733
+ category: "path",
734
+ uses: ["overlay"],
735
+ description: "A line drawn along its path control over transparency; with no path, a line across the middle.",
736
+ tags: ["path", "line"],
737
+ transparent: true,
738
+ loop: false,
739
+ accepts: ["path"],
740
+ controls: {
741
+ type: "object",
742
+ additionalProperties: false,
743
+ properties: {
744
+ path: pathControl("Where the line runs"),
745
+ color: colour("Line colour as #rrggbb. Default #22d3ee."),
746
+ width: { type: "number", minimum: 1, maximum: 64, description: "Line width in pixels. Default 6." }
747
+ }
748
+ },
749
+ defaults: { path: "", color: "#22d3ee", width: 6 },
750
+ presets: [],
751
+ inputs: []
752
+ },
753
+ {
754
+ id: "fake.route",
755
+ name: "Route",
756
+ kind: "vector",
757
+ category: "path",
758
+ uses: ["title"],
759
+ description: "A vector line along its path control, its picture fitted to the path (viewBox = the path bounds); with no path, a short wave.",
760
+ tags: ["path", "route"],
761
+ transparent: true,
762
+ loop: false,
763
+ duration: 400,
764
+ accepts: ["path"],
765
+ controls: {
766
+ type: "object",
767
+ additionalProperties: false,
768
+ properties: {
769
+ path: pathControl("The route"),
770
+ color: colour("Line colour as #rrggbb. Default #f59e0b.")
771
+ }
772
+ },
773
+ defaults: { path: "", color: "#f59e0b" },
774
+ presets: [],
775
+ inputs: []
714
776
  }
715
777
  ];
778
+ function pathNumbers(d) {
779
+ return [...d.matchAll(/-?\d*\.?\d+(?:e[-+]?\d+)?/gi)].map((m) => Number(m[0]));
780
+ }
781
+ function framePoints(value, width, height, fallback) {
782
+ if (Array.isArray(value)) return value.length >= 4 ? value : fallback;
783
+ if (typeof value !== "string" || !value.trim()) return fallback;
784
+ const n = pathNumbers(value);
785
+ if (n.length < 4) return fallback;
786
+ let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
787
+ for (let i = 0; i + 1 < n.length; i += 2) {
788
+ x0 = Math.min(x0, n[i]);
789
+ x1 = Math.max(x1, n[i]);
790
+ y0 = Math.min(y0, n[i + 1]);
791
+ y1 = Math.max(y1, n[i + 1]);
792
+ }
793
+ const m = 0.08;
794
+ const k = Math.min(width * (1 - 2 * m) / Math.max(1e-9, x1 - x0), height * (1 - 2 * m) / Math.max(1e-9, y1 - y0));
795
+ const ox = (width - (x1 - x0) * k) / 2 - x0 * k;
796
+ const oy = (height - (y1 - y0) * k) / 2 - y0 * k;
797
+ return n.map((v, i) => i % 2 ? v * k + oy : v * k + ox);
798
+ }
716
799
  var CAMERA_DESCRIPTIONS = [
717
800
  {
718
801
  id: "fake.glide",
@@ -831,6 +914,29 @@ function renderPixels(d, v, request, width, height) {
831
914
  }
832
915
  break;
833
916
  }
917
+ case "fake.trail": {
918
+ const rgb = hexToRgb(v.color);
919
+ const pts = framePoints(v.path, width, height, [0, height / 2, width, height / 2]);
920
+ const r = v.width / 2;
921
+ for (let i = 0; i + 3 < pts.length; i += 2) {
922
+ const [ax, ay, bx, by] = [pts[i], pts[i + 1], pts[i + 2], pts[i + 3]];
923
+ const steps = Math.max(1, Math.ceil(Math.hypot(bx - ax, by - ay)));
924
+ for (let s = 0; s <= steps; s++) {
925
+ const cx = ax + (bx - ax) * s / steps;
926
+ const cy = ay + (by - ay) * s / steps;
927
+ for (let y = Math.max(0, Math.floor(cy - r)); y <= Math.min(height - 1, Math.ceil(cy + r)); y++)
928
+ for (let x = Math.max(0, Math.floor(cx - r)); x <= Math.min(width - 1, Math.ceil(cx + r)); x++) {
929
+ if ((x + 0.5 - cx) ** 2 + (y + 0.5 - cy) ** 2 > r * r) continue;
930
+ const i4 = (y * width + x) * 4;
931
+ o[i4] = rgb[0];
932
+ o[i4 + 1] = rgb[1];
933
+ o[i4 + 2] = rgb[2];
934
+ o[i4 + 3] = 255;
935
+ }
936
+ }
937
+ }
938
+ break;
939
+ }
834
940
  case "fake.bar": {
835
941
  const rgb = hexToRgb(v.color);
836
942
  const slide = v.slide;
@@ -983,10 +1089,29 @@ function createFakeEffectProvider(options = {}) {
983
1089
  }
984
1090
  };
985
1091
  },
1092
+ pathFromText(text, opts) {
1093
+ if (typeof text !== "string" || !text.trim()) throw new EffectUnsupportedError("There are no words to write; pass some text.");
1094
+ if (opts?.font !== void 0 && opts.font !== "zig") throw new EffectUnsupportedError(`The fake provider has no font "${opts.font}"; its only font is "zig".`);
1095
+ return [...text].map((_, i) => `M${i * 10} 10 L${i * 10 + 3} 0 L${i * 10 + 6} 10`).join(" ");
1096
+ },
986
1097
  applyVectorEffect(id, target, values) {
987
1098
  const d = get(id);
988
1099
  if (d.kind !== "motion" && d.kind !== "vector") throw new EffectUnsupportedError(`"${id}" is a ${d.kind} effect, not a vector one.`, id);
989
1100
  const v = resolveEffectValues(d, values);
1101
+ if (d.id === "fake.route") {
1102
+ const pts = Array.isArray(v.path) && v.path.length >= 4 ? v.path : typeof v.path === "string" && pathNumbers(v.path).length >= 4 ? pathNumbers(v.path) : [0, 20, 25, 0, 50, 20, 75, 40, 100, 20];
1103
+ const xs = pts.filter((_, i) => i % 2 === 0);
1104
+ const ys = pts.filter((_, i) => i % 2 === 1);
1105
+ const [x0, y0] = [Math.min(...xs), Math.min(...ys)];
1106
+ const [w, h] = [Math.max(1, Math.max(...xs) - x0), Math.max(1, Math.max(...ys) - y0)];
1107
+ const dpath = "M" + pts.map((p) => +p.toFixed(3)).join(" ").replace(/^(\S+ \S+) /, "$1 L");
1108
+ return {
1109
+ svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${x0} ${y0} ${w} ${h}" width="${w}" height="${h}"><path id="route" d="${dpath}" fill="none" stroke="${v.color}" stroke-width="2"/></svg>`,
1110
+ animate: [{ id: "route", ms: 400, attrs: { opacity: [0, 1] } }],
1111
+ duration: 400,
1112
+ loop: false
1113
+ };
1114
+ }
990
1115
  if (d.kind === "vector") {
991
1116
  return { svg: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100"><circle id="badge" cx="50" cy="50" r="40" fill="${v.color}"/></svg>`, animate: [{ id: "badge", ms: v.ms, attrs: { opacity: [0, 1] } }], duration: v.ms, loop: false };
992
1117
  }
@@ -1537,10 +1662,12 @@ function createEffectAuthoringToolProvider(host, options) {
1537
1662
  export {
1538
1663
  CAMERA_MOVE_MAX_MS,
1539
1664
  CAMERA_MOVE_ROLES,
1665
+ EFFECT_ACCEPTS,
1540
1666
  EFFECT_ERROR_CODES,
1541
1667
  EFFECT_KINDS,
1542
1668
  EFFECT_LAYER_ROLES,
1543
1669
  EFFECT_LAYER_USES,
1670
+ EFFECT_PATH_FORMAT,
1544
1671
  EFFECT_SEQUENCE_NAME,
1545
1672
  EFFECT_SUBJECT_KINDS,
1546
1673
  EFFECT_TEMPLATE_SLOT_TYPES,
@@ -1601,6 +1728,7 @@ export {
1601
1728
  isSubjectTemplateSlot,
1602
1729
  linearToSrgb,
1603
1730
  normaliseEffectTag,
1731
+ pathControlsOf,
1604
1732
  renderEffectThumbnail,
1605
1733
  resolveCameraMoveSpec,
1606
1734
  resolveEffectValues,
@@ -76,6 +76,29 @@ export interface EffectSummary {
76
76
  backgroundOpacity?: string;
77
77
  /** How a `camera` effect moves. Present exactly when `kind` is `camera`. */
78
78
  camera?: EffectCameraMove;
79
+ /**
80
+ * What it takes besides pictures, for search: `path` when a control draws along a path given at
81
+ * run time (`pathControlsOf` names them). Present exactly when it takes one.
82
+ */
83
+ accepts?: readonly EffectAccept[];
84
+ }
85
+ /** What an effect can take besides pictures: `path`, a control that draws along a path given at run time. */
86
+ export type EffectAccept = 'path';
87
+ export declare const EFFECT_ACCEPTS: readonly EffectAccept[];
88
+ /**
89
+ * The JSON Schema `format` of a path control: a string of SVG path data (fitted into the frame as
90
+ * the control's description says), a flat list of numbers `[x0, y0, x1, y1, …]` in frame pixels
91
+ * from the top left (used as given), or `""` for no path.
92
+ */
93
+ export declare const EFFECT_PATH_FORMAT = "svg-path";
94
+ /** A path control's value: SVG path data, points in frame pixels, or `""` for none. */
95
+ export type EffectPathValue = string | readonly number[];
96
+ /** How `pathFromText` writes words. */
97
+ export interface EffectTextPathOptions {
98
+ /** A font the provider offers for single-stroke writing (its own names, e.g. `script`, `sans`); default its first. */
99
+ font?: string;
100
+ /** Where the line sits in its box (default `start`). */
101
+ align?: 'start' | 'middle' | 'end';
79
102
  }
80
103
  export interface EffectSearchOptions {
81
104
  kind?: EffectKind;
@@ -85,6 +108,8 @@ export interface EffectSearchOptions {
85
108
  tags?: readonly string[];
86
109
  /** Most results to return. */
87
110
  limit?: number;
111
+ /** Only effects that take every one of these (e.g. `['path']`: effects that draw along a path). */
112
+ accepts?: readonly EffectAccept[];
88
113
  }
89
114
  /** One control value: a number, a `#rrggbb` colour or other string, a switch, or a vector of numbers. */
90
115
  export type EffectValue = number | string | boolean | readonly number[];
@@ -524,6 +549,12 @@ export interface EffectProvider {
524
549
  * effect cannot use with `EffectUnsupportedError`.
525
550
  */
526
551
  applyVectorEffect?(id: string, target: EffectVectorTarget, values?: EffectValues): MaybePromise<EffectVectorMotion>;
552
+ /**
553
+ * Words as single-stroke SVG path data, for a path control (an effect that writes a name along
554
+ * its path). Optional: editors refuse words when it is missing. Throws `EffectUnsupportedError`
555
+ * for a font it does not have.
556
+ */
557
+ pathFromText?(text: string, options?: EffectTextPathOptions): MaybePromise<string>;
527
558
  /**
528
559
  * Opens an effect for editing. Present when `capabilities.supportsAuthoring`. Unknown ids throw
529
560
  * `UnknownEffectError`; an effect the provider cannot edit throws `EffectUnsupportedError`.
@@ -76,6 +76,29 @@ export interface EffectSummary {
76
76
  backgroundOpacity?: string;
77
77
  /** How a `camera` effect moves. Present exactly when `kind` is `camera`. */
78
78
  camera?: EffectCameraMove;
79
+ /**
80
+ * What it takes besides pictures, for search: `path` when a control draws along a path given at
81
+ * run time (`pathControlsOf` names them). Present exactly when it takes one.
82
+ */
83
+ accepts?: readonly EffectAccept[];
84
+ }
85
+ /** What an effect can take besides pictures: `path`, a control that draws along a path given at run time. */
86
+ export type EffectAccept = 'path';
87
+ export declare const EFFECT_ACCEPTS: readonly EffectAccept[];
88
+ /**
89
+ * The JSON Schema `format` of a path control: a string of SVG path data (fitted into the frame as
90
+ * the control's description says), a flat list of numbers `[x0, y0, x1, y1, …]` in frame pixels
91
+ * from the top left (used as given), or `""` for no path.
92
+ */
93
+ export declare const EFFECT_PATH_FORMAT = "svg-path";
94
+ /** A path control's value: SVG path data, points in frame pixels, or `""` for none. */
95
+ export type EffectPathValue = string | readonly number[];
96
+ /** How `pathFromText` writes words. */
97
+ export interface EffectTextPathOptions {
98
+ /** A font the provider offers for single-stroke writing (its own names, e.g. `script`, `sans`); default its first. */
99
+ font?: string;
100
+ /** Where the line sits in its box (default `start`). */
101
+ align?: 'start' | 'middle' | 'end';
79
102
  }
80
103
  export interface EffectSearchOptions {
81
104
  kind?: EffectKind;
@@ -85,6 +108,8 @@ export interface EffectSearchOptions {
85
108
  tags?: readonly string[];
86
109
  /** Most results to return. */
87
110
  limit?: number;
111
+ /** Only effects that take every one of these (e.g. `['path']`: effects that draw along a path). */
112
+ accepts?: readonly EffectAccept[];
88
113
  }
89
114
  /** One control value: a number, a `#rrggbb` colour or other string, a switch, or a vector of numbers. */
90
115
  export type EffectValue = number | string | boolean | readonly number[];
@@ -524,6 +549,12 @@ export interface EffectProvider {
524
549
  * effect cannot use with `EffectUnsupportedError`.
525
550
  */
526
551
  applyVectorEffect?(id: string, target: EffectVectorTarget, values?: EffectValues): MaybePromise<EffectVectorMotion>;
552
+ /**
553
+ * Words as single-stroke SVG path data, for a path control (an effect that writes a name along
554
+ * its path). Optional: editors refuse words when it is missing. Throws `EffectUnsupportedError`
555
+ * for a font it does not have.
556
+ */
557
+ pathFromText?(text: string, options?: EffectTextPathOptions): MaybePromise<string>;
527
558
  /**
528
559
  * Opens an effect for editing. Present when `capabilities.supportsAuthoring`. Unknown ids throw
529
560
  * `UnknownEffectError`; an effect the provider cannot edit throws `EffectUnsupportedError`.