@pixerate/flair 0.16.0 → 0.18.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 +22 -0
- package/README.md +38 -7
- package/dist/catalog/index.d.ts +8 -4
- package/dist/catalog/index.js +8 -2
- package/dist/{chunk-YLJWC4N2.js → chunk-HA6FIMH2.js} +108 -5
- package/dist/chunk-HA6FIMH2.js.map +1 -0
- package/dist/{chunk-UNLCGDCB.js → chunk-HP7CYHS5.js} +46 -11
- package/dist/chunk-HP7CYHS5.js.map +1 -0
- package/dist/{chunk-DVVQRZJ5.js → chunk-MILF5MRS.js} +11 -2
- package/dist/chunk-MILF5MRS.js.map +1 -0
- package/dist/{chunk-4RGHZWQC.js → chunk-RM3I6WZH.js} +2 -2
- package/dist/{chunk-4RGHZWQC.js.map → chunk-RM3I6WZH.js.map} +1 -1
- package/dist/{chunk-KWNFZ5NC.js → chunk-UI5X4D63.js} +292 -185
- package/dist/chunk-UI5X4D63.js.map +1 -0
- package/dist/{chunk-FIJOMGPG.js → chunk-UP6QQVRS.js} +2 -2
- package/dist/{chunk-WC3VADZC.js → chunk-VYOMXE6I.js} +46 -4
- package/dist/chunk-VYOMXE6I.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/{controls-Syr6drzO.d.ts → controls-Ec6P0Vpy.d.ts} +9 -2
- package/dist/editor/index.d.ts +3 -3
- package/dist/editor/index.js +20 -6
- package/dist/editor/index.js.map +1 -1
- package/dist/index.d.ts +19 -7
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +2 -2
- package/dist/react/index.d.ts +14 -3
- package/dist/react/index.js +18 -9
- package/dist/react/index.js.map +1 -1
- package/dist/recorder-HKFFHQES.js +10 -0
- package/dist/{renderer-SNYZu__R.d.ts → renderer-Cn4_d5Qs.d.ts} +64 -8
- package/dist/svelte/index.d.ts +16 -5
- package/dist/svelte/index.js +16 -11
- package/dist/svelte/index.js.map +1 -1
- package/dist/{types-9J6NWaN3.d.ts → types-kAFjaq2N.d.ts} +28 -3
- package/dist/vector/index.d.ts +27 -1
- package/dist/vector/index.js +4 -2
- package/package.json +1 -1
- package/dist/chunk-DVVQRZJ5.js.map +0 -1
- package/dist/chunk-KWNFZ5NC.js.map +0 -1
- package/dist/chunk-UNLCGDCB.js.map +0 -1
- package/dist/chunk-WC3VADZC.js.map +0 -1
- package/dist/chunk-YLJWC4N2.js.map +0 -1
- package/dist/recorder-KEX3U35D.js +0 -10
- /package/dist/{chunk-FIJOMGPG.js.map → chunk-UP6QQVRS.js.map} +0 -0
- /package/dist/{recorder-KEX3U35D.js.map → recorder-HKFFHQES.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
controlValue,
|
|
3
3
|
parseControls
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VYOMXE6I.js";
|
|
5
5
|
|
|
6
6
|
// src/export/recorder.ts
|
|
7
7
|
import http from "http";
|
|
@@ -328,4 +328,4 @@ export {
|
|
|
328
328
|
findChrome,
|
|
329
329
|
exportMotionGraphic
|
|
330
330
|
};
|
|
331
|
-
//# sourceMappingURL=chunk-
|
|
331
|
+
//# sourceMappingURL=chunk-UP6QQVRS.js.map
|
|
@@ -25,6 +25,43 @@ function hexToRgb(hex) {
|
|
|
25
25
|
const h = digits.length === 3 ? digits.split("").map((c) => c + c).join("") : digits;
|
|
26
26
|
return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16) / 255);
|
|
27
27
|
}
|
|
28
|
+
function parseColor(css) {
|
|
29
|
+
const text = css.trim().toLowerCase();
|
|
30
|
+
const hex = /^#?([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.exec(text);
|
|
31
|
+
if (hex) {
|
|
32
|
+
const d = hex[1].length <= 4 ? Array.from(hex[1], (c) => c + c).join("") : hex[1];
|
|
33
|
+
const rgba = (d.match(/../g) ?? []).map((h) => parseInt(h, 16) / 255);
|
|
34
|
+
return rgba.length === 4 && rgba[3] < 1 ? rgba : rgba.slice(0, 3);
|
|
35
|
+
}
|
|
36
|
+
const fn = /^(rgba?|hsla?)\(\s*([^)]*)\)$/.exec(text);
|
|
37
|
+
if (!fn) return null;
|
|
38
|
+
const parts = fn[2].split(/\s*[,/]\s*|\s+/).filter(Boolean);
|
|
39
|
+
if (parts.length < 3 || parts.length > 4) return null;
|
|
40
|
+
const num = (p, full) => {
|
|
41
|
+
const n = parseFloat(p);
|
|
42
|
+
if (!/^-?(\d+\.?\d*|\.\d+)(%|deg)?$/.test(p) || !Number.isFinite(n)) return NaN;
|
|
43
|
+
return p.endsWith("%") ? n / 100 * full : n;
|
|
44
|
+
};
|
|
45
|
+
const clamp = (n) => Math.min(1, Math.max(0, n));
|
|
46
|
+
let rgb;
|
|
47
|
+
if (fn[1].startsWith("rgb")) rgb = parts.slice(0, 3).map((p) => clamp(num(p, 255) / 255));
|
|
48
|
+
else {
|
|
49
|
+
const h = (num(parts[0], 360) % 360 + 360) % 360 / 360;
|
|
50
|
+
const sat = clamp(num(parts[1], 1));
|
|
51
|
+
const l = clamp(num(parts[2], 1));
|
|
52
|
+
const f = (k) => {
|
|
53
|
+
const t = (k + h * 12) % 12;
|
|
54
|
+
return l - sat * Math.min(l, 1 - l) * Math.max(-1, Math.min(t - 3, 9 - t, 1));
|
|
55
|
+
};
|
|
56
|
+
rgb = [f(0), f(8), f(4)];
|
|
57
|
+
}
|
|
58
|
+
const alpha = parts[3] === void 0 ? 1 : clamp(num(parts[3], 1));
|
|
59
|
+
if ([...rgb, alpha].some((n) => Number.isNaN(n))) return null;
|
|
60
|
+
return alpha < 1 ? [...rgb, alpha] : rgb;
|
|
61
|
+
}
|
|
62
|
+
function colourValue(control, rgb) {
|
|
63
|
+
return control.type === "vec4" ? [...rgb.slice(0, 3), rgb[3] ?? 1] : rgb.slice(0, 3);
|
|
64
|
+
}
|
|
28
65
|
function rgbToHex(rgb) {
|
|
29
66
|
return "#" + rgb.slice(0, 3).map(
|
|
30
67
|
(c) => Math.round(Math.min(1, Math.max(0, c)) * 255).toString(16).padStart(2, "0")
|
|
@@ -91,6 +128,10 @@ function controlValue(control, values) {
|
|
|
91
128
|
if (control.type === "sampler2D" || control.type === "text") return typeof v === "string" ? v : control.default;
|
|
92
129
|
const n = COMPONENTS[control.type];
|
|
93
130
|
if (n === 1) return typeof v === "number" ? v : control.default;
|
|
131
|
+
if (control.color && typeof v === "string") {
|
|
132
|
+
const rgb = parseColor(v);
|
|
133
|
+
return rgb ? colourValue(control, rgb) : control.default;
|
|
134
|
+
}
|
|
94
135
|
return Array.isArray(v) && v.length === n ? v : control.default;
|
|
95
136
|
}
|
|
96
137
|
function checkControlValue(control, raw) {
|
|
@@ -106,9 +147,9 @@ function checkControlValue(control, raw) {
|
|
|
106
147
|
return typeof raw === "string" ? { ok: true, value: raw } : fail(`${control.name} takes text.`);
|
|
107
148
|
}
|
|
108
149
|
if (control.color && typeof raw === "string") {
|
|
109
|
-
const rgb =
|
|
110
|
-
if (!rgb) return fail(`${control.name} takes a colour like "#77C16A".`);
|
|
111
|
-
return { ok: true, value: control
|
|
150
|
+
const rgb = parseColor(raw);
|
|
151
|
+
if (!rgb) return fail(`${control.name} takes a colour like "#77C16A", "rgb(119 193 106)" or "hsl(110 40% 59%)".`);
|
|
152
|
+
return { ok: true, value: colourValue(control, rgb) };
|
|
112
153
|
}
|
|
113
154
|
if (n === 1) {
|
|
114
155
|
if (typeof raw !== "number" || !Number.isFinite(raw)) {
|
|
@@ -157,6 +198,7 @@ export {
|
|
|
157
198
|
componentCount,
|
|
158
199
|
humanise,
|
|
159
200
|
hexToRgb,
|
|
201
|
+
parseColor,
|
|
160
202
|
rgbToHex,
|
|
161
203
|
controlFromDeclaration,
|
|
162
204
|
parseControls,
|
|
@@ -167,4 +209,4 @@ export {
|
|
|
167
209
|
imageUrls,
|
|
168
210
|
describeValue
|
|
169
211
|
};
|
|
170
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-VYOMXE6I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shader/controls.ts"],"sourcesContent":["/**\n * Controls declared in a shader's source. A uniform becomes a control when\n * its declaration carries an `@control` comment on the same line:\n *\n * uniform float uSpeed; // @control min=0 max=4 default=1 label=\"Speed\"\n * uniform int uSteps; // @control min=1 max=64 default=16\n * uniform bool uGrain; // @control default=true label=\"Film grain\"\n * uniform vec2 uCenter; // @control min=-1 max=1 default=0,0\n * uniform vec3 uTint; // @control color default=#77C16A label=\"Tint\"\n * uniform sampler2D uPhoto; // @control filter=linear wrap=clamp label=\"Photo\"\n *\n * The source is the single source of truth for which controls exist and\n * their defaults; values someone picks are stored next to it.\n */\n\n/** The uniform types a control can have. */\nexport type ControlType = \"float\" | \"int\" | \"bool\" | \"vec2\" | \"vec3\" | \"vec4\" | \"sampler2D\" | \"text\";\n\n/**\n * A control's value: a number (`float`, `int`), a boolean (`bool`), the\n * components of a vector, an image URL (`sampler2D`; \"\" for none), or a\n * string (`text`, vector effects only: shaders cannot take text).\n */\nexport type ControlValue = number | boolean | number[] | string;\n\n/** How an image is sampled: Shadertoy's channel settings. */\nexport interface TextureSettings {\n /** `mipmap` (the default), `linear` or `nearest` (pixelated). */\n filter: \"mipmap\" | \"linear\" | \"nearest\";\n /** Outside 0–1: `repeat` (the default), `clamp` to the edge, or `mirror`. */\n wrap: \"repeat\" | \"clamp\" | \"mirror\";\n}\n\n/** A control parsed from an annotated uniform. */\nexport interface ControlDef {\n /** The uniform's name. */\n name: string;\n type: ControlType;\n /** `label=\"…\"`, or the name made readable (\"uFlowSpeed\" → \"Flow speed\"). */\n label: string;\n /** A `vec3` or `vec4` shown as a colour picker. */\n color: boolean;\n min: number;\n /** Always greater than `min`. */\n max: number;\n step: number;\n default: ControlValue;\n /** 1-based line of the declaration. */\n line: number;\n /** Sampling settings, for `sampler2D` controls only. */\n texture?: TextureSettings;\n}\n\nconst DECLARATION =\n /^\\s*uniform\\s+(float|int|bool|vec2|vec3|vec4|sampler2D)\\s+([A-Za-z_]\\w*)\\s*;\\s*\\/\\/\\s*@control\\b(.*)$/;\nconst ATTRIBUTE = /([a-z]+)(?:=(\"[^\"]*\"|'[^']*'|\\S+))?/gi;\n\nconst COMPONENTS: Record<ControlType, number> = {\n float: 1,\n int: 1,\n bool: 1,\n vec2: 2,\n vec3: 3,\n vec4: 4,\n sampler2D: 1,\n text: 1,\n};\n\n/** The number of components a control type has: 1 for scalars, `bool`, `sampler2D` and `text`, else the vector size. */\nexport function componentCount(type: ControlType): number {\n return COMPONENTS[type];\n}\n\n/** \"uFlowSpeed\" → \"Flow speed\". */\nexport function humanise(name: string): string {\n const words = name\n .replace(/^u(?=[A-Z])/, \"\")\n .replace(/_/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .trim()\n .toLowerCase();\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/** \"#77C16A\" (or \"#7c6\") → [0.467, 0.757, 0.416]; null when it is not a hex colour. */\nexport function hexToRgb(hex: string): number[] | null {\n const m = /^#?([0-9a-f]{6}|[0-9a-f]{3})$/i.exec(hex.trim());\n if (!m) return null;\n const digits = m[1]!;\n const h =\n digits.length === 3\n ? digits\n .split(\"\")\n .map((c) => c + c)\n .join(\"\")\n : digits;\n return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16) / 255);\n}\n\n/**\n * A CSS colour as [r, g, b] (0–1), or [r, g, b, a] when it gives an alpha\n * below 1: hex (`#7c6`, `#7c6f`, `#77C16A`, `#77C16AFF`), `rgb()`/`rgba()`\n * and `hsl()`/`hsla()`, with commas or spaces, numbers or percentages.\n * Null for anything else (names like \"red\" and `currentColor` included).\n */\nexport function parseColor(css: string): number[] | null {\n const text = css.trim().toLowerCase();\n const hex = /^#?([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.exec(text);\n if (hex) {\n const d = hex[1]!.length <= 4 ? Array.from(hex[1]!, (c) => c + c).join(\"\") : hex[1]!;\n const rgba = (d.match(/../g) ?? []).map((h) => parseInt(h, 16) / 255);\n return rgba.length === 4 && rgba[3]! < 1 ? rgba : rgba.slice(0, 3);\n }\n const fn = /^(rgba?|hsla?)\\(\\s*([^)]*)\\)$/.exec(text);\n if (!fn) return null;\n const parts = fn[2]!.split(/\\s*[,/]\\s*|\\s+/).filter(Boolean);\n if (parts.length < 3 || parts.length > 4) return null;\n // A component: a number, or a percentage of `full`.\n const num = (p: string, full: number) => {\n const n = parseFloat(p);\n if (!/^-?(\\d+\\.?\\d*|\\.\\d+)(%|deg)?$/.test(p) || !Number.isFinite(n)) return NaN;\n return p.endsWith(\"%\") ? (n / 100) * full : n;\n };\n const clamp = (n: number) => Math.min(1, Math.max(0, n));\n let rgb: number[];\n if (fn[1]!.startsWith(\"rgb\")) rgb = parts.slice(0, 3).map((p) => clamp(num(p, 255) / 255));\n else {\n const h = (((num(parts[0]!, 360) % 360) + 360) % 360) / 360;\n const sat = clamp(num(parts[1]!, 1));\n const l = clamp(num(parts[2]!, 1));\n // HSL to RGB, per CSS Color 4.\n const f = (k: number) => {\n const t = (k + h * 12) % 12;\n return l - sat * Math.min(l, 1 - l) * Math.max(-1, Math.min(t - 3, 9 - t, 1));\n };\n rgb = [f(0), f(8), f(4)];\n }\n const alpha = parts[3] === undefined ? 1 : clamp(num(parts[3], 1));\n if ([...rgb, alpha].some((n) => Number.isNaN(n))) return null;\n return alpha < 1 ? [...rgb, alpha] : rgb;\n}\n\n/** As a control value: `rgb` padded or cut to the control's components (an alpha of 1 added for a vec4). */\nfunction colourValue(control: ControlDef, rgb: number[]): number[] {\n return control.type === \"vec4\" ? [...rgb.slice(0, 3), rgb[3] ?? 1] : rgb.slice(0, 3);\n}\n\n/** [0.467, 0.757, 0.416] → \"#77c16a\". Components are clamped to 0–1; a fourth (alpha) is ignored. */\nexport function rgbToHex(rgb: number[]): string {\n return (\n \"#\" +\n rgb\n .slice(0, 3)\n .map((c) =>\n Math.round(Math.min(1, Math.max(0, c)) * 255)\n .toString(16)\n .padStart(2, \"0\"),\n )\n .join(\"\")\n );\n}\n\nfunction parseDefault(raw: string | undefined, type: ControlType, color: boolean): ControlValue {\n const n = COMPONENTS[type];\n if (type === \"bool\") return raw === \"true\" || raw === \"1\";\n if (type === \"sampler2D\" || type === \"text\") return raw ?? \"\";\n // Without a default, numbers start at 0 and colours at white.\n if (raw === undefined) return n === 1 ? 0 : Array.from({ length: n }, () => (color ? 1 : 0));\n if (color && raw.startsWith(\"#\")) {\n const rgb = hexToRgb(raw) ?? [1, 1, 1];\n return type === \"vec4\" ? [...rgb, 1] : rgb;\n }\n const parts = raw\n .split(\",\")\n .map(Number)\n .map((v) => (Number.isFinite(v) ? v : 0));\n if (n === 1) return parts[0] ?? 0;\n // A short list repeats its last component: `default=0.5` on a vec3 is (0.5, 0.5, 0.5).\n return Array.from({ length: n }, (_, i) => parts[i] ?? parts[parts.length - 1] ?? 0);\n}\n\n/**\n * A control from its declaration's attributes (the text after `@control`):\n * `min`, `max`, `step`, `default`, `label`, `color`, and for images `filter`\n * and `wrap`. Values with spaces are quoted, in double or single quotes.\n * Shared by shader sources and vector effects' `{{name: type …}}` placeholders.\n */\nexport function controlFromDeclaration(name: string, type: ControlType, attributes: string, line: number): ControlDef {\n const attrs: Record<string, string | undefined> = {};\n for (const a of attributes.matchAll(ATTRIBUTE)) {\n attrs[a[1]!.toLowerCase()] = a[2]?.replace(/^([\"'])(.*)\\1$/s, \"$2\");\n }\n const color = \"color\" in attrs && (type === \"vec3\" || type === \"vec4\");\n const num = (v: string | undefined, fallback: number) =>\n v !== undefined && Number.isFinite(Number(v)) ? Number(v) : fallback;\n const min = num(attrs.min, 0);\n const rawMax = num(attrs.max, type === \"int\" ? 10 : 1);\n const max = rawMax > min ? rawMax : min + 1;\n const control: ControlDef = {\n name,\n type,\n label: attrs.label ?? humanise(name),\n color,\n min,\n max,\n step: num(attrs.step, type === \"int\" ? 1 : (max - min) / 200),\n default: parseDefault(attrs.default, type, color),\n line,\n };\n if (type === \"sampler2D\") {\n const pick = <T extends string>(v: string | undefined, options: readonly T[]): T =>\n options.find((o) => o === v?.toLowerCase()) ?? options[0]!;\n control.texture = {\n filter: pick(attrs.filter, [\"mipmap\", \"linear\", \"nearest\"] as const),\n wrap: pick(attrs.wrap, [\"repeat\", \"clamp\", \"mirror\"] as const),\n };\n }\n return control;\n}\n\n/**\n * The controls a source declares, in source order. A uniform declared twice\n * counts once (the first wins). Unknown attributes are ignored, and missing\n * or malformed ones fall back to defaults: `min=0`, `max=1` (10 for `int`),\n * a step of 1/200 of the range (1 for `int`).\n */\nexport function parseControls(source: string): ControlDef[] {\n const controls: ControlDef[] = [];\n const seen = new Set<string>();\n source.split(\"\\n\").forEach((text, index) => {\n const m = DECLARATION.exec(text);\n if (!m || seen.has(m[2]!)) return;\n seen.add(m[2]!);\n controls.push(controlFromDeclaration(m[2]!, m[1] as ControlType, m[3]!, index + 1));\n });\n return controls;\n}\n\n/** The value a control has: the stored one when it still fits the declaration, else the default. */\nexport function controlValue(\n control: ControlDef,\n values: Record<string, ControlValue> | undefined,\n): ControlValue {\n const v = values?.[control.name];\n if (v === undefined) return control.default;\n if (control.type === \"bool\") return typeof v === \"boolean\" ? v : control.default;\n if (control.type === \"sampler2D\" || control.type === \"text\") return typeof v === \"string\" ? v : control.default;\n const n = COMPONENTS[control.type];\n if (n === 1) return typeof v === \"number\" ? v : control.default;\n if (control.color && typeof v === \"string\") {\n const rgb = parseColor(v);\n return rgb ? colourValue(control, rgb) : control.default;\n }\n return Array.isArray(v) && v.length === n ? v : control.default;\n}\n\n/** What {@link checkControlValue} decides: the value to store, or a sentence saying what the control takes. */\nexport type ControlCheck = { ok: true; value: ControlValue } | { ok: false; message: string };\n\n/**\n * Checks a value from outside (an agent's tool call, a URL, a form) against a\n * control. Colours also accept CSS colours (see {@link parseColor}); `int` values are rounded. Images\n * take a URL: `https:`, `http:`, `data:image/…`, `blob:` or a relative path\n * (\"\" for none).\n */\nexport function checkControlValue(control: ControlDef, raw: unknown): ControlCheck {\n const fail = (message: string): ControlCheck => ({ ok: false, message });\n const n = COMPONENTS[control.type];\n if (control.type === \"bool\") {\n return typeof raw === \"boolean\"\n ? { ok: true, value: raw }\n : fail(`${control.name} takes true or false.`);\n }\n if (control.type === \"sampler2D\") {\n return typeof raw === \"string\" && (raw === \"\" || isImageUrl(raw))\n ? { ok: true, value: raw }\n : fail(`${control.name} takes an image URL: https://…, data:image/… or blob:….`);\n }\n if (control.type === \"text\") {\n return typeof raw === \"string\" ? { ok: true, value: raw } : fail(`${control.name} takes text.`);\n }\n if (control.color && typeof raw === \"string\") {\n const rgb = parseColor(raw);\n if (!rgb) return fail(`${control.name} takes a colour like \"#77C16A\", \"rgb(119 193 106)\" or \"hsl(110 40% 59%)\".`);\n return { ok: true, value: colourValue(control, rgb) };\n }\n if (n === 1) {\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n return fail(`${control.name} takes a number.`);\n }\n return { ok: true, value: control.type === \"int\" ? Math.round(raw) : raw };\n }\n if (\n !Array.isArray(raw) ||\n raw.length !== n ||\n !raw.every((x) => typeof x === \"number\" && Number.isFinite(x))\n ) {\n return fail(\n `${control.name} takes ${n} numbers${control.color ? ' (or a colour like \"#77C16A\")' : \"\"}.`,\n );\n }\n return { ok: true, value: raw as number[] };\n}\n\n/**\n * {@link checkControlValue} for controls whose values are never strings:\n * returns the value to store, or the message. An image control's value is a\n * string too, so use `checkControlValue` where images can appear.\n */\nexport function coerceControlValue(control: ControlDef, raw: unknown): ControlValue | string {\n const check = checkControlValue(control, raw);\n return check.ok ? check.value : check.message;\n}\n\n/** Whether a string is a URL an image control can load: `http(s):`, `data:image/`, `blob:` or a relative path. */\nexport function isImageUrl(url: string): boolean {\n const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(url.trim())?.[1]?.toLowerCase();\n if (scheme === undefined) return url.trim() !== \"\";\n if (scheme === \"data\") return /^data:image\\//i.test(url.trim());\n return scheme === \"http\" || scheme === \"https\" || scheme === \"blob\";\n}\n\n/** The image URLs the controls show with these values, without duplicates or empty ones. */\nexport function imageUrls(\n controls: ControlDef[],\n values: Record<string, ControlValue> | undefined,\n): string[] {\n const urls = new Set<string>();\n for (const control of controls) {\n if (control.type !== \"sampler2D\") continue;\n const url = controlValue(control, values) as string;\n if (url) urls.add(url);\n }\n return [...urls];\n}\n\n/**\n * A value as compact, JSON-friendly data: colours as hex, numbers to three\n * decimals. A long `data:` URL is shortened to its type and size, which\n * keeps it out of an agent's context but cannot be stored back.\n */\nexport function describeValue(control: ControlDef, value: ControlValue): unknown {\n if (typeof value === \"string\" && value.startsWith(\"data:\") && value.length > 100) {\n const kb = Math.round((value.length * 3) / 4 / 1024);\n return `${value.slice(0, value.indexOf(\",\") + 1)}… (about ${kb} kB)`;\n }\n if (control.color && Array.isArray(value)) return rgbToHex(value);\n if (Array.isArray(value)) return value.map((v) => Math.round(v * 1000) / 1000);\n if (typeof value === \"number\") return Math.round(value * 1000) / 1000;\n return value;\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
standaloneHtml,
|
|
4
4
|
standaloneSceneHtml,
|
|
5
5
|
validateScene
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HP7CYHS5.js";
|
|
7
7
|
import {
|
|
8
8
|
simulateScene
|
|
9
9
|
} from "./chunk-WAMA45G3.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-HA6FIMH2.js";
|
|
11
11
|
import "./chunk-EHDJ3CPJ.js";
|
|
12
12
|
import "./chunk-WMZQCUFJ.js";
|
|
13
13
|
import {
|
|
14
14
|
parseControls
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VYOMXE6I.js";
|
|
16
16
|
|
|
17
17
|
// src/cli.ts
|
|
18
18
|
import { Command } from "commander";
|
|
@@ -152,7 +152,7 @@ program.command("export <targetOrShader> [extraPath] [outputPath]").description(
|
|
|
152
152
|
const duration = parseFloat(options.duration);
|
|
153
153
|
console.log(`Rendering ${duration}s (${duration * fps} frames at ${width}x${height}, ${fps}fps) to ${options.out}...`);
|
|
154
154
|
try {
|
|
155
|
-
const { exportMotionGraphic } = await import("./recorder-
|
|
155
|
+
const { exportMotionGraphic } = await import("./recorder-HKFFHQES.js");
|
|
156
156
|
const savedPath = await exportMotionGraphic({
|
|
157
157
|
source,
|
|
158
158
|
values,
|
|
@@ -52,6 +52,13 @@ declare function componentCount(type: ControlType): number;
|
|
|
52
52
|
declare function humanise(name: string): string;
|
|
53
53
|
/** "#77C16A" (or "#7c6") → [0.467, 0.757, 0.416]; null when it is not a hex colour. */
|
|
54
54
|
declare function hexToRgb(hex: string): number[] | null;
|
|
55
|
+
/**
|
|
56
|
+
* A CSS colour as [r, g, b] (0–1), or [r, g, b, a] when it gives an alpha
|
|
57
|
+
* below 1: hex (`#7c6`, `#7c6f`, `#77C16A`, `#77C16AFF`), `rgb()`/`rgba()`
|
|
58
|
+
* and `hsl()`/`hsla()`, with commas or spaces, numbers or percentages.
|
|
59
|
+
* Null for anything else (names like "red" and `currentColor` included).
|
|
60
|
+
*/
|
|
61
|
+
declare function parseColor(css: string): number[] | null;
|
|
55
62
|
/** [0.467, 0.757, 0.416] → "#77c16a". Components are clamped to 0–1; a fourth (alpha) is ignored. */
|
|
56
63
|
declare function rgbToHex(rgb: number[]): string;
|
|
57
64
|
/**
|
|
@@ -73,7 +80,7 @@ type ControlCheck = {
|
|
|
73
80
|
};
|
|
74
81
|
/**
|
|
75
82
|
* Checks a value from outside (an agent's tool call, a URL, a form) against a
|
|
76
|
-
* control. Colours also accept
|
|
83
|
+
* control. Colours also accept CSS colours (see {@link parseColor}); `int` values are rounded. Images
|
|
77
84
|
* take a URL: `https:`, `http:`, `data:image/…`, `blob:` or a relative path
|
|
78
85
|
* ("" for none).
|
|
79
86
|
*/
|
|
@@ -95,4 +102,4 @@ declare function imageUrls(controls: ControlDef[], values: Record<string, Contro
|
|
|
95
102
|
*/
|
|
96
103
|
declare function describeValue(control: ControlDef, value: ControlValue): unknown;
|
|
97
104
|
|
|
98
|
-
export { type ControlValue as C, type TextureSettings as T, type ControlDef as a, type ControlType as b, type ControlCheck as c, checkControlValue as d, coerceControlValue as e, componentCount as f, controlValue as g, describeValue as h, hexToRgb as i, humanise as j, imageUrls as k, isImageUrl as l, parseControls as p, rgbToHex as r };
|
|
105
|
+
export { type ControlValue as C, type TextureSettings as T, type ControlDef as a, type ControlType as b, type ControlCheck as c, checkControlValue as d, coerceControlValue as e, componentCount as f, controlValue as g, describeValue as h, hexToRgb as i, humanise as j, imageUrls as k, isImageUrl as l, parseControls as m, parseColor as p, rgbToHex as r };
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-
|
|
1
|
+
import { g as VectorControl, d as EffectPreset, E as EffectDefinition } from '../types-kAFjaq2N.js';
|
|
2
|
+
import { C as ControlValue, a as ControlDef, b as ControlType } from '../controls-Ec6P0Vpy.js';
|
|
3
3
|
import { S as SvgMotion, C as Clock } from '../svg-XugR-6Ec.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-
|
|
8
|
+
import { C as CompileError, a as CompileStatus } from '../renderer-Cn4_d5Qs.js';
|
|
9
9
|
import { AgentToolProvider, McpToolResult, ToolRegistryOptions, ToolRegistry, McpToolDefinition } from '@pixerate/editor/tools';
|
|
10
10
|
import { ParameterImageOption, ParametersController, ParameterField, ParameterSchema, ParameterValue, ParameterValues } from '@pixerate/editor/parameters';
|
|
11
11
|
|
package/dist/editor/index.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EFFECT_CATEGORIES,
|
|
3
|
+
VIDEO_USES,
|
|
3
4
|
findEffects,
|
|
4
5
|
getEffect,
|
|
5
6
|
renderVectorEffect,
|
|
6
7
|
vectorControlIssues,
|
|
7
8
|
vectorEffectControls
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-UI5X4D63.js";
|
|
9
10
|
import {
|
|
10
11
|
svgMotionIssues,
|
|
11
12
|
svgView
|
|
12
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-RM3I6WZH.js";
|
|
13
14
|
import "../chunk-OHW7UG6D.js";
|
|
14
15
|
import {
|
|
15
16
|
BUILTIN_UNIFORMS,
|
|
16
17
|
interpolateOklab
|
|
17
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-HA6FIMH2.js";
|
|
18
19
|
import "../chunk-EHDJ3CPJ.js";
|
|
19
20
|
import {
|
|
20
21
|
realClock
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
checkControlValue,
|
|
24
25
|
controlValue,
|
|
25
26
|
parseControls
|
|
26
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-VYOMXE6I.js";
|
|
27
28
|
|
|
28
29
|
// src/editor/timeline.ts
|
|
29
30
|
import {
|
|
@@ -271,11 +272,24 @@ function effectCommands() {
|
|
|
271
272
|
properties: {
|
|
272
273
|
text: { type: "string", description: "Words to look for (all must match)." },
|
|
273
274
|
category: { type: "string", enum: EFFECT_CATEGORIES },
|
|
274
|
-
kind: { type: "string", enum: ["shader", "vector"] }
|
|
275
|
+
kind: { type: "string", enum: ["shader", "vector"] },
|
|
276
|
+
video: {
|
|
277
|
+
type: "array",
|
|
278
|
+
items: { type: "string", enum: VIDEO_USES },
|
|
279
|
+
description: "Only effects that suit video in one of these ways: filter (live video filter), transition (between two clips), interactive (pointer over video), stills (runs on video, made for stills), none."
|
|
280
|
+
}
|
|
275
281
|
},
|
|
276
282
|
additionalProperties: false
|
|
277
283
|
},
|
|
278
|
-
run: (_, params) => findEffects(params ?? {}).map((e) => ({
|
|
284
|
+
run: (_, params) => findEffects(params ?? {}).map((e) => ({
|
|
285
|
+
id: e.id,
|
|
286
|
+
name: e.name,
|
|
287
|
+
kind: e.kind,
|
|
288
|
+
category: e.category,
|
|
289
|
+
description: e.description,
|
|
290
|
+
...e.kind === "shader" && e.video ? { video: e.video } : {},
|
|
291
|
+
presets: e.presets?.map((p) => p.name) ?? []
|
|
292
|
+
}))
|
|
279
293
|
},
|
|
280
294
|
{
|
|
281
295
|
id: "effect.load",
|