@pixerate/flair 0.33.0 → 0.35.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.
- package/CHANGELOG.md +19 -0
- package/README.md +23 -5
- package/dist/catalog/index.d.ts +4 -2
- package/dist/catalog/index.js +5 -1
- package/dist/{chunk-ARYM5VEJ.js → chunk-2O3RMSOE.js} +2 -2
- package/dist/{chunk-4FFBIVPI.js → chunk-IHUNCBMF.js} +17 -1
- package/dist/chunk-IHUNCBMF.js.map +1 -0
- package/dist/{chunk-ZULFHADW.js → chunk-OLTY4APV.js} +33 -5
- package/dist/{chunk-ZULFHADW.js.map → chunk-OLTY4APV.js.map} +1 -1
- package/dist/{chunk-6ZG2RIWA.js → chunk-UU4PHRVF.js} +3 -3
- package/dist/cli.js +3 -3
- package/dist/editor/index.d.ts +14 -12
- package/dist/editor/index.js +84 -25
- package/dist/editor/index.js.map +1 -1
- package/dist/{effect-6PRVCU55.js → effect-6VQS2CA5.js} +4 -4
- package/dist/embed/index.d.ts +1 -1
- package/dist/embed/index.js +2 -2
- package/dist/index.d.ts +24 -4
- package/dist/index.js +288 -165
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +3 -3
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +2 -2
- package/dist/svelte/index.d.ts +1 -1
- package/dist/svelte/index.js +2 -2
- package/dist/{types-c8cnPzuE.d.ts → types-B4Wjzde0.d.ts} +10 -1
- package/package.json +1 -1
- package/dist/chunk-4FFBIVPI.js.map +0 -1
- /package/dist/{chunk-ARYM5VEJ.js.map → chunk-2O3RMSOE.js.map} +0 -0
- /package/dist/{chunk-6ZG2RIWA.js.map → chunk-UU4PHRVF.js.map} +0 -0
- /package/dist/{effect-6PRVCU55.js.map → effect-6VQS2CA5.js.map} +0 -0
package/dist/editor/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "../chunk-HDYBY3PQ.js";
|
|
7
7
|
import {
|
|
8
8
|
EFFECT_CATEGORIES,
|
|
9
|
+
EFFECT_CATEGORY_GROUPS,
|
|
9
10
|
EFFECT_INPUTS,
|
|
10
11
|
EFFECT_INTERACTIONS,
|
|
11
12
|
VIDEO_USES,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
renderVectorEffect,
|
|
16
17
|
vectorControlIssues,
|
|
17
18
|
vectorEffectControls
|
|
18
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-IHUNCBMF.js";
|
|
19
20
|
import "../chunk-EHDJ3CPJ.js";
|
|
20
21
|
import {
|
|
21
22
|
checkControlValue,
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
parseControls
|
|
24
25
|
} from "../chunk-VYOMXE6I.js";
|
|
25
26
|
import {
|
|
27
|
+
svgDuration,
|
|
26
28
|
svgView
|
|
27
29
|
} from "../chunk-JETRHCP3.js";
|
|
28
30
|
import {
|
|
@@ -115,7 +117,7 @@ function createEffectDocument(from) {
|
|
|
115
117
|
},
|
|
116
118
|
values: {},
|
|
117
119
|
tracks: {},
|
|
118
|
-
duration: effect.kind === "
|
|
120
|
+
duration: effect.kind === "vector" ? Math.round(svgDuration(effect.motion) + (effect.hold ?? 600)) : effect.loop ? Math.round(effect.loop * 1e3) : DEFAULT_DURATION,
|
|
119
121
|
loop: true,
|
|
120
122
|
presets: (effect.presets ?? []).map((p) => ({ name: p.name, values: { ...p.values } }))
|
|
121
123
|
};
|
|
@@ -232,6 +234,12 @@ var easingSchema = {
|
|
|
232
234
|
var valueSchema = {
|
|
233
235
|
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).'
|
|
234
236
|
};
|
|
237
|
+
var CATALOG_SEARCH_LIMIT = 20;
|
|
238
|
+
function compileStatus(editor) {
|
|
239
|
+
const state = editor.getState();
|
|
240
|
+
if (state.document.effect.kind !== "shader") return void 0;
|
|
241
|
+
return state.compile ?? "not compiled yet: no renderer has compiled this source, so compile errors are unknown";
|
|
242
|
+
}
|
|
235
243
|
function describeEditor(editor) {
|
|
236
244
|
const state = editor.getState();
|
|
237
245
|
const doc = state.document;
|
|
@@ -253,7 +261,7 @@ function describeEditor(editor) {
|
|
|
253
261
|
presets: doc.presets.map((p) => p.name),
|
|
254
262
|
timeline: { duration: doc.duration, loop: doc.loop, time: state.time, playing: state.playing, recording: state.recording },
|
|
255
263
|
issues: state.issues,
|
|
256
|
-
compile:
|
|
264
|
+
...doc.effect.kind === "shader" && { compile: compileStatus(editor) },
|
|
257
265
|
history: { canUndo: state.history.canUndo, canRedo: state.history.canRedo }
|
|
258
266
|
};
|
|
259
267
|
}
|
|
@@ -271,13 +279,18 @@ function effectCommands() {
|
|
|
271
279
|
id: "catalog.search",
|
|
272
280
|
label: "Search effects",
|
|
273
281
|
group: "Catalog",
|
|
274
|
-
description:
|
|
282
|
+
description: `Searches the built-in effect catalog: {total, effects}, at most \`limit\` effects (default ${CATALOG_SEARCH_LIMIT}). Narrow with words and filters rather than raising the limit. Load one with effect.load to start from it.`,
|
|
275
283
|
readOnly: true,
|
|
276
284
|
params: {
|
|
277
285
|
type: "object",
|
|
278
286
|
properties: {
|
|
279
287
|
text: { type: "string", description: "Words to look for (all must match)." },
|
|
280
288
|
category: { type: "string", enum: EFFECT_CATEGORIES },
|
|
289
|
+
group: {
|
|
290
|
+
type: "string",
|
|
291
|
+
enum: EFFECT_CATEGORY_GROUPS.map((g) => g.name),
|
|
292
|
+
description: `A set of related categories: ${EFFECT_CATEGORY_GROUPS.map((g) => `${g.name} (${g.categories.join(", ")})`).join("; ")}.`
|
|
293
|
+
},
|
|
281
294
|
kind: { type: "string", enum: ["shader", "vector"] },
|
|
282
295
|
video: {
|
|
283
296
|
type: "array",
|
|
@@ -294,25 +307,37 @@ function effectCommands() {
|
|
|
294
307
|
items: { type: "string", enum: EFFECT_INTERACTIONS },
|
|
295
308
|
description: "Only effects that answer the pointer in one of these ways: hover, press, click, trail (follows where it has been), pointer (follows where it is). An empty list finds effects that don't answer it."
|
|
296
309
|
},
|
|
297
|
-
transparent: { type: "boolean", description: "Only overlays (true), drawn over other content, or only effects that fill their frame (false)." }
|
|
310
|
+
transparent: { type: "boolean", description: "Only overlays (true), drawn over other content, or only effects that fill their frame (false)." },
|
|
311
|
+
limit: { type: "integer", minimum: 1, description: `Most effects to return (default ${CATALOG_SEARCH_LIMIT}).` },
|
|
312
|
+
offset: { type: "integer", minimum: 0, description: "Effects to skip first, to page through more (default 0)." }
|
|
298
313
|
},
|
|
299
314
|
additionalProperties: false
|
|
300
315
|
},
|
|
301
|
-
run: (_, params) =>
|
|
302
|
-
const
|
|
316
|
+
run: (_, params) => {
|
|
317
|
+
const { limit = CATALOG_SEARCH_LIMIT, offset = 0, ...filters } = params ?? {};
|
|
318
|
+
const found = findEffects(filters);
|
|
319
|
+
const effects = found.slice(offset, offset + limit).map((e) => {
|
|
320
|
+
const inputs = effectInputs(e);
|
|
321
|
+
return {
|
|
322
|
+
id: e.id,
|
|
323
|
+
name: e.name,
|
|
324
|
+
kind: e.kind,
|
|
325
|
+
category: e.category,
|
|
326
|
+
description: e.description,
|
|
327
|
+
...e.kind === "shader" && e.video ? { video: e.video } : {},
|
|
328
|
+
accepts: inputs.accepts,
|
|
329
|
+
...inputs.interactions.length ? { interactions: inputs.interactions } : {},
|
|
330
|
+
...inputs.transparent ? { transparent: true } : {},
|
|
331
|
+
presets: e.presets?.map((p) => p.name) ?? []
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
const more = found.length - offset - effects.length;
|
|
303
335
|
return {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
category: e.category,
|
|
308
|
-
description: e.description,
|
|
309
|
-
...e.kind === "shader" && e.video ? { video: e.video } : {},
|
|
310
|
-
accepts: inputs.accepts,
|
|
311
|
-
...inputs.interactions.length ? { interactions: inputs.interactions } : {},
|
|
312
|
-
...inputs.transparent ? { transparent: true } : {},
|
|
313
|
-
presets: e.presets?.map((p) => p.name) ?? []
|
|
336
|
+
total: found.length,
|
|
337
|
+
effects,
|
|
338
|
+
...more > 0 && { more: `${more} more match; narrow the search, or pass offset ${offset + effects.length} for the next ones.` }
|
|
314
339
|
};
|
|
315
|
-
}
|
|
340
|
+
}
|
|
316
341
|
},
|
|
317
342
|
{
|
|
318
343
|
id: "effect.load",
|
|
@@ -335,9 +360,40 @@ function effectCommands() {
|
|
|
335
360
|
id: "effect.setSource",
|
|
336
361
|
label: "Set shader source",
|
|
337
362
|
group: "Effect",
|
|
338
|
-
description: "Replaces
|
|
363
|
+
description: "Replaces a shader effect's GLSL ES 3.00 source (Shadertoy-style mainImage; controls are uniforms annotated `// @control`). Returns the compile report when a preview compiled it (errors carry your source's line numbers), and the document's issues.",
|
|
339
364
|
params: { type: "object", properties: { source: { type: "string" } }, required: ["source"], additionalProperties: false },
|
|
340
|
-
run: (editor, p) =>
|
|
365
|
+
run: (editor, p) => {
|
|
366
|
+
done(editor.setSource(p.source));
|
|
367
|
+
return { ok: true, compile: compileStatus(editor), issues: editor.getState().issues };
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
id: "effect.setMotion",
|
|
372
|
+
label: "Set vector picture",
|
|
373
|
+
group: "Effect",
|
|
374
|
+
description: "Replaces a vector effect's picture: {svg, animate?}. `svg` is one self-contained <svg> with a viewBox (no scripts); `{{name: type \u2026}}` placeholders in it declare controls and `{{name}}` fills them. `animate` lists changes to elements by id: {id, step?, delay?, ms?, ease?, attrs?: {name: [from, to]}, draw?, view?, along?, count?, write?}. Returns the document's issues.",
|
|
375
|
+
params: {
|
|
376
|
+
type: "object",
|
|
377
|
+
properties: {
|
|
378
|
+
motion: {
|
|
379
|
+
type: "object",
|
|
380
|
+
properties: { svg: { type: "string" }, animate: { type: "array", items: { type: "object" } } },
|
|
381
|
+
required: ["svg"],
|
|
382
|
+
description: "The picture and its animation."
|
|
383
|
+
},
|
|
384
|
+
controls: {
|
|
385
|
+
type: "array",
|
|
386
|
+
items: { type: "object" },
|
|
387
|
+
description: "Controls declared outside the picture, for older pictures: {name, type, default, label?, color?, min?, max?, step?}. Leave out to keep the current list."
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
required: ["motion"],
|
|
391
|
+
additionalProperties: false
|
|
392
|
+
},
|
|
393
|
+
run: (editor, p) => {
|
|
394
|
+
done(editor.setMotion(p.motion, p.controls));
|
|
395
|
+
return { ok: true, issues: editor.getState().issues };
|
|
396
|
+
}
|
|
341
397
|
},
|
|
342
398
|
{
|
|
343
399
|
id: "effect.rename",
|
|
@@ -614,14 +670,16 @@ var EffectEditor = class {
|
|
|
614
670
|
// ── The effect itself ───────────────────────────────────────────────
|
|
615
671
|
/** Replaces a shader's source. Compile errors arrive later, from the renderer (see `reportCompile`). */
|
|
616
672
|
setSource(source) {
|
|
617
|
-
if (this.doc.effect.kind !== "shader") return fail("This is a vector effect;
|
|
673
|
+
if (this.doc.effect.kind !== "shader") return fail("This is a vector effect; change its picture with setMotion (the effect.setMotion command).");
|
|
618
674
|
if (source === this.doc.effect.source) return ok;
|
|
619
675
|
this.commit("Edit source", { ...this.doc, effect: { kind: "shader", source } }, "source");
|
|
620
676
|
return ok;
|
|
621
677
|
}
|
|
622
678
|
/** Replaces a vector effect's picture, whose `{{name: type …}}` placeholders declare its controls (and optionally a `controls` list). */
|
|
623
679
|
setMotion(motion, controls) {
|
|
624
|
-
if (this.doc.effect.kind !== "vector") return fail("This is a shader effect;
|
|
680
|
+
if (this.doc.effect.kind !== "vector") return fail("This is a shader effect; change its source with setSource (the effect.setSource command).");
|
|
681
|
+
if (!motion || typeof motion.svg !== "string" || !motion.svg.trim()) return fail("The picture needs `svg`: one <svg>\u2026</svg> element with a viewBox.");
|
|
682
|
+
if (motion.animate !== void 0 && !Array.isArray(motion.animate)) return fail("`animate` must be a list of changes to the picture's elements.");
|
|
625
683
|
this.commit("Edit picture", { ...this.doc, effect: { ...this.doc.effect, motion, controls: controls ?? this.doc.effect.controls } });
|
|
626
684
|
return ok;
|
|
627
685
|
}
|
|
@@ -951,7 +1009,7 @@ async function callTool(provider, name, args = {}) {
|
|
|
951
1009
|
}
|
|
952
1010
|
var EFFECT_AGENT_INSTRUCTIONS = `You design web visual effects in an effect editor. Work through its tools: \`list_commands\` shows every command with its parameters; \`run_command\` runs one; \`run_commands\` runs several in order.
|
|
953
1011
|
|
|
954
|
-
Start with \`effect.describe\` to see what is being edited. To start from something close, use \`catalog.search\` then \`effect.load\` (with a preset if one fits). Every change is one undo step; \`history.undo\` reverts a step.
|
|
1012
|
+
Start with \`effect.describe\` to see what is being edited. To start from something close, use \`catalog.search\` (it returns the first matches and a \`total\`; narrow it with words and filters) then \`effect.load\` (with a preset if one fits). Every change is one undo step; \`history.undo\` reverts a step.
|
|
955
1013
|
|
|
956
1014
|
Shader effects are GLSL ES 3.00 fragment shaders written Shadertoy-style:
|
|
957
1015
|
- Define \`void mainImage(out vec4 fragColor, in vec2 fragCoord)\`; the output is opaque unless the host renders with \`alpha: true\` (overlays), when \`fragColor.a\` is coverage.
|
|
@@ -963,11 +1021,11 @@ Shader effects are GLSL ES 3.00 fragment shaders written Shadertoy-style:
|
|
|
963
1021
|
uniform sampler2D uPhoto; // @control filter=linear wrap=clamp label="Photo"
|
|
964
1022
|
Types: float, int, bool, vec2, vec3, vec4, sampler2D. Every uniform you declare should be a control.
|
|
965
1023
|
- Write float literals with a decimal point (1.0, not 1); GLSL does not convert int to float implicitly. Use \`texture()\`, not \`texture2D()\`.
|
|
966
|
-
-
|
|
1024
|
+
- \`effect.setSource\` returns \`compile\`: fix any errors (their line numbers match your source) before going on. When it says the source is not compiled yet, no preview is attached; check again with \`effect.describe\` or \`view_effect\` later.
|
|
967
1025
|
|
|
968
1026
|
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.
|
|
969
1027
|
<!-- {{title: text default='Hello' label='Title'}} {{accent: color default=#6366F1}} --><text fill="{{accent}}">{{title}}</text>
|
|
970
|
-
Change their controls' values freely (a text control takes any words)
|
|
1028
|
+
Change their controls' values freely (a text control takes any words). Replace the picture with \`effect.setMotion\` ({svg, animate}), with care: keep the viewBox and the element ids that animations refer to, and read the issues it returns.
|
|
971
1029
|
|
|
972
1030
|
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.`;
|
|
973
1031
|
|
|
@@ -1112,6 +1170,7 @@ function bindEffectParameters(editor, options = {}) {
|
|
|
1112
1170
|
};
|
|
1113
1171
|
}
|
|
1114
1172
|
export {
|
|
1173
|
+
CATALOG_SEARCH_LIMIT,
|
|
1115
1174
|
EASING_PRESETS,
|
|
1116
1175
|
EFFECT_AGENT_INSTRUCTIONS,
|
|
1117
1176
|
EffectEditor,
|