@pixerate/flair 0.2.0 → 0.4.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 (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +44 -8
  3. package/dist/catalog/index.d.ts +5 -4
  4. package/dist/catalog/index.js +12 -4
  5. package/dist/{chunk-3FAUZOGL.js → chunk-FIJOMGPG.js} +2 -2
  6. package/dist/{chunk-JWZCPMFG.js → chunk-GL37YCCM.js} +134 -680
  7. package/dist/chunk-GL37YCCM.js.map +1 -0
  8. package/dist/{chunk-UQQNZSYL.js → chunk-GTIAOYOK.js} +211 -7
  9. package/dist/chunk-GTIAOYOK.js.map +1 -0
  10. package/dist/{chunk-MWVTQFV5.js → chunk-IWKM5FJK.js} +410 -59
  11. package/dist/chunk-IWKM5FJK.js.map +1 -0
  12. package/dist/{chunk-HKXOHRCD.js → chunk-VA74HBPK.js} +2 -2
  13. package/dist/chunk-WAMA45G3.js +998 -0
  14. package/dist/chunk-WAMA45G3.js.map +1 -0
  15. package/dist/{chunk-J55UBNAT.js → chunk-WC3VADZC.js} +42 -36
  16. package/dist/chunk-WC3VADZC.js.map +1 -0
  17. package/dist/cli.js +12 -11
  18. package/dist/cli.js.map +1 -1
  19. package/dist/{controls-DdXMbovi.d.ts → controls-Syr6drzO.d.ts} +4 -3
  20. package/dist/editor/index.d.ts +12 -8
  21. package/dist/editor/index.js +26 -16
  22. package/dist/editor/index.js.map +1 -1
  23. package/dist/{export-FEBPEEO7.js → export-DH2HMACO.js} +4 -3
  24. package/dist/index.d.ts +193 -17
  25. package/dist/index.js +69 -33
  26. package/dist/index.js.map +1 -1
  27. package/dist/node.d.ts +1 -1
  28. package/dist/node.js +2 -2
  29. package/dist/recorder-KEX3U35D.js +10 -0
  30. package/dist/{renderer-Oyynz-fs.d.ts → renderer-DtnFkpkf.d.ts} +7 -3
  31. package/dist/types-CsFUZZIv.d.ts +102 -0
  32. package/package.json +1 -1
  33. package/dist/chunk-36DTNSHU.js +0 -160
  34. package/dist/chunk-36DTNSHU.js.map +0 -1
  35. package/dist/chunk-J55UBNAT.js.map +0 -1
  36. package/dist/chunk-JWZCPMFG.js.map +0 -1
  37. package/dist/chunk-MWVTQFV5.js.map +0 -1
  38. package/dist/chunk-UQQNZSYL.js.map +0 -1
  39. package/dist/recorder-WJTWMEQN.js +0 -10
  40. package/dist/types-CkKkavvB.d.ts +0 -71
  41. /package/dist/{chunk-3FAUZOGL.js.map → chunk-FIJOMGPG.js.map} +0 -0
  42. /package/dist/{chunk-HKXOHRCD.js.map → chunk-VA74HBPK.js.map} +0 -0
  43. /package/dist/{export-FEBPEEO7.js.map → export-DH2HMACO.js.map} +0 -0
  44. /package/dist/{recorder-WJTWMEQN.js.map → recorder-KEX3U35D.js.map} +0 -0
@@ -1,11 +1,11 @@
1
- import { V as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-CkKkavvB.js';
2
- import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-DdXMbovi.js';
1
+ import { d as VectorControl, c as EffectPreset, E as EffectDefinition } from '../types-CsFUZZIv.js';
2
+ import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-Syr6drzO.js';
3
3
  import { S as SvgMotion } from '../motion-D0TVv2CF.js';
4
4
  import { AnimationEasingPreset, AnimationEasing, AnimationTrack, AnimationKeyframe, cubicBezierAt as cubicBezierAt$1, evaluateEasing as evaluateEasing$1 } from '@pixerate/editor/animation';
5
5
  export { CubicBezierEasing, SpringEasing } from '@pixerate/editor/animation';
6
6
  import { CommandRegistry, CommandSpec } from '@pixerate/editor/commands';
7
7
  import { HistoryManager, HistoryState } from '@pixerate/editor/history';
8
- import { C as CompileError, a as CompileStatus } from '../renderer-Oyynz-fs.js';
8
+ import { C as CompileError, a as CompileStatus } from '../renderer-DtnFkpkf.js';
9
9
  import { C as Clock } from '../clock-BhdXWH-n.js';
10
10
  import { AgentToolProvider, McpToolResult, ToolRegistryOptions, ToolRegistry, McpToolDefinition } from '@pixerate/editor/tools';
11
11
  import { ParameterImageOption, ParametersController, ParameterField, ParameterSchema, ParameterValue, ParameterValues } from '@pixerate/editor/parameters';
@@ -62,14 +62,18 @@ declare function keyframeTimes(tracks: Record<string, Track>): number[];
62
62
  * diffed, and written by an agent.
63
63
  */
64
64
 
65
- /** What is being edited: a fragment shader, or an animated SVG with declared controls. */
65
+ /**
66
+ * What is being edited: a fragment shader, or an animated SVG. Both declare
67
+ * their controls in themselves (`// @control`, `{{name: type …}}`); a vector
68
+ * effect's optional `controls` list is for pictures written before that.
69
+ */
66
70
  type EffectSource = {
67
71
  kind: "shader";
68
72
  source: string;
69
73
  } | {
70
74
  kind: "vector";
71
75
  motion: SvgMotion;
72
- controls: VectorControl[];
76
+ controls?: VectorControl[];
73
77
  hold?: number;
74
78
  };
75
79
  interface EffectDocument {
@@ -208,7 +212,7 @@ declare class EffectEditor {
208
212
  rename(name: string): EditResult;
209
213
  /** Replaces a shader's source. Compile errors arrive later, from the renderer (see `reportCompile`). */
210
214
  setSource(source: string): EditResult;
211
- /** Replaces a vector effect's picture (and optionally its controls). */
215
+ /** Replaces a vector effect's picture, whose `{{name: type …}}` placeholders declare its controls (and optionally a `controls` list). */
212
216
  setMotion(motion: SvgMotion, controls?: Extract<EffectDocument["effect"], {
213
217
  kind: "vector";
214
218
  }>["controls"]): EditResult;
@@ -224,7 +228,7 @@ declare class EffectEditor {
224
228
  setValues(values: Record<string, unknown>): EditResult;
225
229
  /** Back to defaults: the named controls, or all of them (values only; tracks stay). */
226
230
  resetValues(names?: readonly string[]): EditResult;
227
- /** Random values in each control's range (colours anywhere), for exploring. */
231
+ /** Random values in each control's range (colours anywhere), for exploring. Images and text keep theirs. */
228
232
  randomize(names?: readonly string[], random?: () => number): EditResult;
229
233
  applyPreset(name: string): EditResult;
230
234
  /** Saves the current values (all, or the named ones) as a preset, replacing one of the same name. */
@@ -333,8 +337,8 @@ declare function describeEditor(editor: EffectEditor): {
333
337
  canUndo: boolean;
334
338
  canRedo: boolean;
335
339
  };
340
+ vectorControls?: VectorControl[] | undefined;
336
341
  motion: SvgMotion;
337
- vectorControls: VectorControl[];
338
342
  name: string;
339
343
  basedOn: string | undefined;
340
344
  kind: "shader" | "vector";
@@ -3,8 +3,9 @@ import {
3
3
  findEffects,
4
4
  getEffect,
5
5
  renderVectorEffect,
6
- vectorControlDef
7
- } from "../chunk-MWVTQFV5.js";
6
+ vectorControlIssues,
7
+ vectorEffectControls
8
+ } from "../chunk-IWKM5FJK.js";
8
9
  import {
9
10
  svgMotionIssues,
10
11
  svgView
@@ -12,7 +13,7 @@ import {
12
13
  import {
13
14
  BUILTIN_UNIFORMS,
14
15
  interpolateOklab
15
- } from "../chunk-HKXOHRCD.js";
16
+ } from "../chunk-VA74HBPK.js";
16
17
  import "../chunk-EHDJ3CPJ.js";
17
18
  import {
18
19
  realClock
@@ -21,7 +22,7 @@ import {
21
22
  checkControlValue,
22
23
  controlValue,
23
24
  parseControls
24
- } from "../chunk-J55UBNAT.js";
25
+ } from "../chunk-WC3VADZC.js";
25
26
 
26
27
  // src/editor/timeline.ts
27
28
  import {
@@ -98,7 +99,12 @@ function createEffectDocument(from) {
98
99
  version: 1,
99
100
  name: effect.name,
100
101
  basedOn: effect.id,
101
- effect: effect.kind === "shader" ? { kind: "shader", source: effect.source } : { kind: "vector", motion: structuredClone(effect.motion), controls: effect.controls.map((c) => ({ ...c })), hold: effect.hold },
102
+ effect: effect.kind === "shader" ? { kind: "shader", source: effect.source } : {
103
+ kind: "vector",
104
+ motion: structuredClone(effect.motion),
105
+ ...effect.controls && { controls: effect.controls.map((c) => ({ ...c })) },
106
+ hold: effect.hold
107
+ },
102
108
  values: {},
103
109
  tracks: {},
104
110
  duration: effect.kind === "shader" && effect.loop ? Math.round(effect.loop * 1e3) : DEFAULT_DURATION,
@@ -111,7 +117,7 @@ function blankDocument(name, source) {
111
117
  }
112
118
  function documentControls(doc) {
113
119
  if (doc.effect.kind === "shader") return parseControls(doc.effect.source);
114
- return doc.effect.controls.map((c, i) => vectorControlDef(c, i + 1));
120
+ return vectorEffectControls(doc.effect);
115
121
  }
116
122
  function valuesAt(doc, time, controls = documentControls(doc)) {
117
123
  const out = {};
@@ -151,7 +157,7 @@ function documentIssues(doc) {
151
157
  for (const preset of doc.presets) for (const [name, value] of Object.entries(preset.values)) check(`preset "${preset.name}"`, name, value);
152
158
  if (doc.effect.kind === "vector") {
153
159
  const motion = motionAt(doc, 0);
154
- issues.push(...svgMotionIssues(motion));
160
+ issues.push(...vectorControlIssues(doc.effect.motion), ...svgMotionIssues(motion));
155
161
  if (/\{\{[^}]+\}\}/.test(JSON.stringify(motion))) issues.push("the picture has placeholders no control fills");
156
162
  }
157
163
  return issues;
@@ -175,7 +181,7 @@ function parseEffectDocument(input) {
175
181
  else if (effect.kind === "vector") {
176
182
  const v = effect;
177
183
  if (!v.motion || typeof v.motion.svg !== "string") errors.push("`effect.motion.svg` must be a string");
178
- if (!Array.isArray(v.controls)) errors.push("`effect.controls` must be a list");
184
+ if (v.controls !== void 0 && !Array.isArray(v.controls)) errors.push("`effect.controls` must be a list");
179
185
  }
180
186
  const isRecord = (v) => !!v && typeof v === "object" && !Array.isArray(v);
181
187
  if (o.values !== void 0 && !isRecord(o.values)) errors.push("`values` must be an object");
@@ -216,7 +222,7 @@ var easingSchema = {
216
222
  description: `An easing preset (${EASING_PRESETS.join(", ")}) or {"type":"cubic-bezier","x1","y1","x2","y2"} or {"type":"spring","stiffness","damping","mass"}.`
217
223
  };
218
224
  var valueSchema = {
219
- description: 'A control value: a number (float, int), true/false (bool), an array of numbers (vec2\u2013vec4; colours 0\u20131), a "#RRGGBB" colour, or an image URL (sampler2D).'
225
+ description: 'A control value: a number (float, int), true/false (bool), an array of numbers (vec2\u2013vec4; colours 0\u20131), a "#RRGGBB" colour, an image URL (sampler2D), or a string (text).'
220
226
  };
221
227
  function describeEditor(editor) {
222
228
  const state = editor.getState();
@@ -225,13 +231,13 @@ function describeEditor(editor) {
225
231
  name: doc.name,
226
232
  basedOn: doc.basedOn,
227
233
  kind: doc.effect.kind,
228
- ...doc.effect.kind === "shader" ? { source: doc.effect.source } : { motion: doc.effect.motion, vectorControls: doc.effect.controls },
234
+ ...doc.effect.kind === "shader" ? { source: doc.effect.source } : { motion: doc.effect.motion, ...doc.effect.controls && { vectorControls: doc.effect.controls } },
229
235
  controls: state.controls.map((c) => ({
230
236
  name: c.name,
231
237
  type: c.type,
232
238
  label: c.label,
233
239
  ...c.color && { color: true },
234
- ...c.type !== "bool" && c.type !== "sampler2D" && { min: c.min, max: c.max, step: c.step },
240
+ ...c.type !== "bool" && c.type !== "sampler2D" && c.type !== "text" && { min: c.min, max: c.max, step: c.step },
235
241
  default: c.default
236
242
  })),
237
243
  values: state.values,
@@ -575,7 +581,7 @@ var EffectEditor = class {
575
581
  this.commit("Edit source", { ...this.doc, effect: { kind: "shader", source } }, "source");
576
582
  return ok;
577
583
  }
578
- /** Replaces a vector effect's picture (and optionally its controls). */
584
+ /** Replaces a vector effect's picture, whose `{{name: type …}}` placeholders declare its controls (and optionally a `controls` list). */
579
585
  setMotion(motion, controls) {
580
586
  if (this.doc.effect.kind !== "vector") return fail("This is a shader effect; use setSource.");
581
587
  this.commit("Edit picture", { ...this.doc, effect: { ...this.doc.effect, motion, controls: controls ?? this.doc.effect.controls } });
@@ -626,17 +632,17 @@ var EffectEditor = class {
626
632
  this.commit("Reset values", { ...this.doc, values });
627
633
  return ok;
628
634
  }
629
- /** Random values in each control's range (colours anywhere), for exploring. */
635
+ /** Random values in each control's range (colours anywhere), for exploring. Images and text keep theirs. */
630
636
  randomize(names, random = Math.random) {
631
637
  const values = {};
632
638
  for (const control of this.controls) {
633
- if (names ? !names.includes(control.name) : control.type === "sampler2D") continue;
639
+ if (names ? !names.includes(control.name) : control.type === "sampler2D" || control.type === "text") continue;
634
640
  const pick = () => {
635
641
  const v = control.min + random() * (control.max - control.min);
636
642
  return control.type === "int" ? Math.round(v) : +v.toFixed(3);
637
643
  };
638
644
  if (control.type === "bool") values[control.name] = random() < 0.5;
639
- else if (control.type === "sampler2D") continue;
645
+ else if (control.type === "sampler2D" || control.type === "text") continue;
640
646
  else if (control.color) values[control.name] = Array.from({ length: control.type === "vec4" ? 4 : 3 }, () => +random().toFixed(3));
641
647
  else if (control.type === "float" || control.type === "int") values[control.name] = pick();
642
648
  else values[control.name] = Array.from({ length: Number(control.type.slice(3)) }, pick);
@@ -921,7 +927,9 @@ Shader effects are GLSL ES 3.00 fragment shaders written Shadertoy-style:
921
927
  - Write float literals with a decimal point (1.0, not 1); GLSL does not convert int to float implicitly. Use \`texture()\`, not \`texture2D()\`.
922
928
  - After \`effect.setSource\`, call \`effect.describe\` and read \`compile\`: fix any errors (their line numbers match your source) before going on.
923
929
 
924
- Vector effects are animated SVG pictures: change their controls' values; their picture is edited with care, keeping element ids that animations refer to.
930
+ Vector effects are animated SVG pictures that declare their controls in themselves, like shader uniforms: the first \`{{name: type \u2026}}\` declares a control (types: float, int, bool, color, text; attributes as for \`@control\`, values with spaces in single quotes), and every \`{{name}}\` is replaced by its value, e.g.
931
+ <!-- {{title: text default='Hello' label='Title'}} {{accent: color default=#6366F1}} --><text fill="{{accent}}">{{title}}</text>
932
+ Change their controls' values freely (a text control takes any words); edit the picture with care, keeping element ids that animations refer to.
925
933
 
926
934
  Make effects that loop smoothly and read well behind content: keep motion calm unless asked otherwise, keep contrast where text may sit, and expose the few controls a designer would actually want (colours, speed, scale, intensity) with sensible ranges. Use keyframes (\`keyframe.set\`, in ms) for changes over the timeline. When you can, look at the result with \`view_effect\` and refine it.`;
927
935
 
@@ -986,6 +994,8 @@ function parameterFieldFor(control, options = {}) {
986
994
  return { ...base, type: "number", min: control.min, max: control.max, step: control.step, default: Number(control.default) };
987
995
  case "sampler2D":
988
996
  return { ...base, type: "image", default: String(control.default), ...options.images && { options: options.images } };
997
+ case "text":
998
+ return { ...base, type: "text", default: String(control.default) };
989
999
  default: {
990
1000
  const value = control.default;
991
1001
  if (control.color) {