@pixerate/editor 0.177.0 → 0.178.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/dist/effects/index.cjs +9 -1
- package/dist/effects/index.js +9 -1
- package/dist/effects/ui.d.cts +4 -1
- package/dist/effects/ui.d.ts +4 -1
- package/dist/image-editor/index.cjs +4 -14
- package/dist/image-editor/index.js +4 -14
- package/dist/image-editor/layers/panel.d.cts +8 -5
- package/dist/image-editor/layers/panel.d.ts +8 -5
- package/dist/image-editor/provider-effect-tools.d.cts +2 -1
- package/dist/image-editor/provider-effect-tools.d.ts +2 -1
- package/package.json +1 -1
- package/skills/pixerate-effect-authoring/SKILL.md +5 -0
- package/skills/pixerate-image-editor/SKILL.md +4 -1
- package/skills/pixerate-image-editor/references/provider-effects.md +4 -1
package/dist/effects/index.cjs
CHANGED
|
@@ -597,6 +597,11 @@ var EFFECT_USE_LABELS = {
|
|
|
597
597
|
};
|
|
598
598
|
var HEX2 = /^#[0-9a-f]{6}([0-9a-f]{2})?$/i;
|
|
599
599
|
var typeOf = (s) => Array.isArray(s.type) ? s.type.find((t) => t !== "null") : s.type;
|
|
600
|
+
function hexColour(value) {
|
|
601
|
+
if (typeof value === "string") return HEX2.test(value) ? value : void 0;
|
|
602
|
+
if (!Array.isArray(value) || value.length !== 3 && value.length !== 4 || !value.every((n) => typeof n === "number" && Number.isFinite(n))) return void 0;
|
|
603
|
+
return `#${value.map((n) => Math.round(Math.min(1, Math.max(0, n)) * 255).toString(16).padStart(2, "0")).join("")}`;
|
|
604
|
+
}
|
|
600
605
|
function isEffectFontControl(schema) {
|
|
601
606
|
return typeOf(schema) === "string" && (schema.format === "font" || schema["x-pixerate-control"] === "font");
|
|
602
607
|
}
|
|
@@ -649,7 +654,10 @@ function effectFontFamilies(description, values = {}) {
|
|
|
649
654
|
}
|
|
650
655
|
return out;
|
|
651
656
|
}
|
|
652
|
-
var effectFieldValue = (field, value) =>
|
|
657
|
+
var effectFieldValue = (field, value) => {
|
|
658
|
+
if (field.type === "color") return _nullishCoalesce(hexColour(value), () => ( field.default));
|
|
659
|
+
return value === void 0 || value === null || typeof value === "object" && !Array.isArray(value) ? field.default : value;
|
|
660
|
+
};
|
|
653
661
|
function effectSamplePicture(width, height, variant = 0) {
|
|
654
662
|
const p = _chunkA3A5TI6Rcjs.createEffectPixels.call(void 0, width, height);
|
|
655
663
|
for (let y = 0, i = 0; y < height; y++) {
|
package/dist/effects/index.js
CHANGED
|
@@ -597,6 +597,11 @@ var EFFECT_USE_LABELS = {
|
|
|
597
597
|
};
|
|
598
598
|
var HEX2 = /^#[0-9a-f]{6}([0-9a-f]{2})?$/i;
|
|
599
599
|
var typeOf = (s) => Array.isArray(s.type) ? s.type.find((t) => t !== "null") : s.type;
|
|
600
|
+
function hexColour(value) {
|
|
601
|
+
if (typeof value === "string") return HEX2.test(value) ? value : void 0;
|
|
602
|
+
if (!Array.isArray(value) || value.length !== 3 && value.length !== 4 || !value.every((n) => typeof n === "number" && Number.isFinite(n))) return void 0;
|
|
603
|
+
return `#${value.map((n) => Math.round(Math.min(1, Math.max(0, n)) * 255).toString(16).padStart(2, "0")).join("")}`;
|
|
604
|
+
}
|
|
600
605
|
function isEffectFontControl(schema) {
|
|
601
606
|
return typeOf(schema) === "string" && (schema.format === "font" || schema["x-pixerate-control"] === "font");
|
|
602
607
|
}
|
|
@@ -649,7 +654,10 @@ function effectFontFamilies(description, values = {}) {
|
|
|
649
654
|
}
|
|
650
655
|
return out;
|
|
651
656
|
}
|
|
652
|
-
var effectFieldValue = (field, value) =>
|
|
657
|
+
var effectFieldValue = (field, value) => {
|
|
658
|
+
if (field.type === "color") return hexColour(value) ?? field.default;
|
|
659
|
+
return value === void 0 || value === null || typeof value === "object" && !Array.isArray(value) ? field.default : value;
|
|
660
|
+
};
|
|
653
661
|
function effectSamplePicture(width, height, variant = 0) {
|
|
654
662
|
const p = createEffectPixels(width, height);
|
|
655
663
|
for (let y = 0, i = 0; y < height; y++) {
|
package/dist/effects/ui.d.cts
CHANGED
|
@@ -27,7 +27,10 @@ export declare function effectParameterFields(description: Pick<EffectDescriptio
|
|
|
27
27
|
* to load with `ensureFontsLoaded` before rendering a title preview.
|
|
28
28
|
*/
|
|
29
29
|
export declare function effectFontFamilies(description: Pick<EffectDescription, 'controls' | 'defaults'>, values?: Readonly<Record<string, unknown>>): string[];
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* A saved value as a field shows it (`ParameterValue`), or the field's default. Colour fields show
|
|
32
|
+
* channel arrays as hex, and the default for values they can't show (`"currentColor"`, `rgb(…)`).
|
|
33
|
+
*/
|
|
31
34
|
export declare const effectFieldValue: (field: ParameterField, value: unknown) => ParameterValue;
|
|
32
35
|
/**
|
|
33
36
|
* A colourful, deterministic picture for previews of filters and transitions (`variant` 0 and 1
|
package/dist/effects/ui.d.ts
CHANGED
|
@@ -27,7 +27,10 @@ export declare function effectParameterFields(description: Pick<EffectDescriptio
|
|
|
27
27
|
* to load with `ensureFontsLoaded` before rendering a title preview.
|
|
28
28
|
*/
|
|
29
29
|
export declare function effectFontFamilies(description: Pick<EffectDescription, 'controls' | 'defaults'>, values?: Readonly<Record<string, unknown>>): string[];
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* A saved value as a field shows it (`ParameterValue`), or the field's default. Colour fields show
|
|
32
|
+
* channel arrays as hex, and the default for values they can't show (`"currentColor"`, `rgb(…)`).
|
|
33
|
+
*/
|
|
31
34
|
export declare const effectFieldValue: (field: ParameterField, value: unknown) => ParameterValue;
|
|
32
35
|
/**
|
|
33
36
|
* A colourful, deterministic picture for previews of filters and transitions (`variant` 0 and 1
|
|
@@ -14711,31 +14711,21 @@ function layerPanels(layer, options = {}) {
|
|
|
14711
14711
|
];
|
|
14712
14712
|
}
|
|
14713
14713
|
const panels = [{ id: "properties", title: "Layer Properties" }];
|
|
14714
|
-
const styles = (id, title) => {
|
|
14715
|
-
if (!options.effects) panels.push({ id, title });
|
|
14716
|
-
};
|
|
14717
14714
|
const effects = () => {
|
|
14718
14715
|
if (options.effects) panels.push({ id: "provider-effects", title: "Effects" });
|
|
14719
14716
|
};
|
|
14720
14717
|
if (layer.type === "pixel") {
|
|
14721
14718
|
effects();
|
|
14722
14719
|
panels.push({ id: "paint", title: "Brush Options" });
|
|
14723
|
-
styles("effects", "Layer Effects");
|
|
14724
14720
|
} else if (layer.type === "adjustment") {
|
|
14725
14721
|
panels.push({ id: "adjustment", title: _chunkUHMSMUHKcjs.adjustmentKindLabel.call(void 0, layer.kind) });
|
|
14726
14722
|
} else if (layer.type === "type") {
|
|
14727
14723
|
panels.push({ id: "type", title: "Typography" });
|
|
14728
14724
|
effects();
|
|
14729
|
-
styles("effects", "Layer Effects");
|
|
14730
14725
|
} else if (layer.type === "shape") {
|
|
14731
14726
|
panels.push({ id: "shape", title: "Shape Options" });
|
|
14732
14727
|
effects();
|
|
14733
|
-
|
|
14734
|
-
} else if (layer.type === "smart") {
|
|
14735
|
-
effects();
|
|
14736
|
-
styles("smart-filters", "Smart Filters");
|
|
14737
|
-
styles("effects", "Layer Effects");
|
|
14738
|
-
} else if (layer.type === "group") {
|
|
14728
|
+
} else if (layer.type === "smart" || layer.type === "group") {
|
|
14739
14729
|
effects();
|
|
14740
14730
|
}
|
|
14741
14731
|
if (layer.mask) {
|
|
@@ -14747,14 +14737,14 @@ function layerPanels(layer, options = {}) {
|
|
|
14747
14737
|
// src/image-editor/layers/effects-ui.ts
|
|
14748
14738
|
function layerEffectsPanel(layer) {
|
|
14749
14739
|
const empty = { readOnly: true, enabled: true, scale: 1, rows: [] };
|
|
14750
|
-
if (!layer) return { ...empty, available: false, reason: "Select a layer to add
|
|
14751
|
-
if (layer.type === "adjustment") return { ...empty, available: false, reason: "Adjustment layers cannot have
|
|
14740
|
+
if (!layer) return { ...empty, available: false, reason: "Select a layer to add a layer style." };
|
|
14741
|
+
if (layer.type === "adjustment") return { ...empty, available: false, reason: "Adjustment layers cannot have a layer style." };
|
|
14752
14742
|
const fx = layer.effects;
|
|
14753
14743
|
const readOnly = Boolean(_optionalChain([layer, 'access', _460 => _460.locks, 'optionalAccess', _461 => _461.all]));
|
|
14754
14744
|
return {
|
|
14755
14745
|
available: true,
|
|
14756
14746
|
readOnly,
|
|
14757
|
-
reason: readOnly ? "The layer is locked; unlock it to change its
|
|
14747
|
+
reason: readOnly ? "The layer is locked; unlock it to change its layer style." : void 0,
|
|
14758
14748
|
enabled: _nullishCoalesce(_optionalChain([fx, 'optionalAccess', _462 => _462.enabled]), () => ( true)),
|
|
14759
14749
|
scale: _nullishCoalesce(_optionalChain([fx, 'optionalAccess', _463 => _463.scale]), () => ( 1)),
|
|
14760
14750
|
rows: (_nullishCoalesce(_optionalChain([fx, 'optionalAccess', _464 => _464.items]), () => ( []))).map((e) => ({ id: e.id, kind: e.kind, label: _chunkHGTDMKNEcjs.layerEffectLabel.call(void 0, e.kind), enabled: e.enabled }))
|
|
@@ -14711,31 +14711,21 @@ function layerPanels(layer, options = {}) {
|
|
|
14711
14711
|
];
|
|
14712
14712
|
}
|
|
14713
14713
|
const panels = [{ id: "properties", title: "Layer Properties" }];
|
|
14714
|
-
const styles = (id, title) => {
|
|
14715
|
-
if (!options.effects) panels.push({ id, title });
|
|
14716
|
-
};
|
|
14717
14714
|
const effects = () => {
|
|
14718
14715
|
if (options.effects) panels.push({ id: "provider-effects", title: "Effects" });
|
|
14719
14716
|
};
|
|
14720
14717
|
if (layer.type === "pixel") {
|
|
14721
14718
|
effects();
|
|
14722
14719
|
panels.push({ id: "paint", title: "Brush Options" });
|
|
14723
|
-
styles("effects", "Layer Effects");
|
|
14724
14720
|
} else if (layer.type === "adjustment") {
|
|
14725
14721
|
panels.push({ id: "adjustment", title: adjustmentKindLabel(layer.kind) });
|
|
14726
14722
|
} else if (layer.type === "type") {
|
|
14727
14723
|
panels.push({ id: "type", title: "Typography" });
|
|
14728
14724
|
effects();
|
|
14729
|
-
styles("effects", "Layer Effects");
|
|
14730
14725
|
} else if (layer.type === "shape") {
|
|
14731
14726
|
panels.push({ id: "shape", title: "Shape Options" });
|
|
14732
14727
|
effects();
|
|
14733
|
-
|
|
14734
|
-
} else if (layer.type === "smart") {
|
|
14735
|
-
effects();
|
|
14736
|
-
styles("smart-filters", "Smart Filters");
|
|
14737
|
-
styles("effects", "Layer Effects");
|
|
14738
|
-
} else if (layer.type === "group") {
|
|
14728
|
+
} else if (layer.type === "smart" || layer.type === "group") {
|
|
14739
14729
|
effects();
|
|
14740
14730
|
}
|
|
14741
14731
|
if (layer.mask) {
|
|
@@ -14747,14 +14737,14 @@ function layerPanels(layer, options = {}) {
|
|
|
14747
14737
|
// src/image-editor/layers/effects-ui.ts
|
|
14748
14738
|
function layerEffectsPanel(layer) {
|
|
14749
14739
|
const empty = { readOnly: true, enabled: true, scale: 1, rows: [] };
|
|
14750
|
-
if (!layer) return { ...empty, available: false, reason: "Select a layer to add
|
|
14751
|
-
if (layer.type === "adjustment") return { ...empty, available: false, reason: "Adjustment layers cannot have
|
|
14740
|
+
if (!layer) return { ...empty, available: false, reason: "Select a layer to add a layer style." };
|
|
14741
|
+
if (layer.type === "adjustment") return { ...empty, available: false, reason: "Adjustment layers cannot have a layer style." };
|
|
14752
14742
|
const fx = layer.effects;
|
|
14753
14743
|
const readOnly = Boolean(layer.locks?.all);
|
|
14754
14744
|
return {
|
|
14755
14745
|
available: true,
|
|
14756
14746
|
readOnly,
|
|
14757
|
-
reason: readOnly ? "The layer is locked; unlock it to change its
|
|
14747
|
+
reason: readOnly ? "The layer is locked; unlock it to change its layer style." : void 0,
|
|
14758
14748
|
enabled: fx?.enabled ?? true,
|
|
14759
14749
|
scale: fx?.scale ?? 1,
|
|
14760
14750
|
rows: (fx?.items ?? []).map((e) => ({ id: e.id, kind: e.kind, label: layerEffectLabel(e.kind), enabled: e.enabled }))
|
|
@@ -110,16 +110,19 @@ export interface LayerPanelDescriptor {
|
|
|
110
110
|
}
|
|
111
111
|
export interface LayerPanelsOptions {
|
|
112
112
|
/**
|
|
113
|
-
* The editor has an effects provider (`controller.effectsProvider`):
|
|
114
|
-
* panel ("Effects")
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* Effects) and `smart-filters` panels. New effect layers are added from the layers panel
|
|
113
|
+
* The editor has an effects provider (`controller.effectsProvider`): adds the `provider-effects`
|
|
114
|
+
* panel ("Effects") for layers that can take provider effects. It holds an effect layer's own
|
|
115
|
+
* effect (change it, its frame or animation, its controls) and the provider filters applied to
|
|
116
|
+
* the layer (smart filters). New effect layers are added from the layers panel
|
|
118
117
|
* (`newLayerOptions`).
|
|
119
118
|
*/
|
|
120
119
|
effects?: boolean;
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
123
122
|
* Returns contextual panels that apply to the currently active layer (or layer-independent panels if null).
|
|
123
|
+
*
|
|
124
|
+
* `properties` ("Layer Properties") is first for every layer and includes the layer's Layer Style
|
|
125
|
+
* (drop shadow, stroke, glow…: `layerEffectsPanel`) for layers that can take one, with or without a
|
|
126
|
+
* provider. There is no separate `effects` (Layer Effects) or `smart-filters` panel.
|
|
124
127
|
*/
|
|
125
128
|
export declare function layerPanels(layer: ImageLayer | null, options?: LayerPanelsOptions): LayerPanelDescriptor[];
|
|
@@ -110,16 +110,19 @@ export interface LayerPanelDescriptor {
|
|
|
110
110
|
}
|
|
111
111
|
export interface LayerPanelsOptions {
|
|
112
112
|
/**
|
|
113
|
-
* The editor has an effects provider (`controller.effectsProvider`):
|
|
114
|
-
* panel ("Effects")
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* Effects) and `smart-filters` panels. New effect layers are added from the layers panel
|
|
113
|
+
* The editor has an effects provider (`controller.effectsProvider`): adds the `provider-effects`
|
|
114
|
+
* panel ("Effects") for layers that can take provider effects. It holds an effect layer's own
|
|
115
|
+
* effect (change it, its frame or animation, its controls) and the provider filters applied to
|
|
116
|
+
* the layer (smart filters). New effect layers are added from the layers panel
|
|
118
117
|
* (`newLayerOptions`).
|
|
119
118
|
*/
|
|
120
119
|
effects?: boolean;
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
123
122
|
* Returns contextual panels that apply to the currently active layer (or layer-independent panels if null).
|
|
123
|
+
*
|
|
124
|
+
* `properties` ("Layer Properties") is first for every layer and includes the layer's Layer Style
|
|
125
|
+
* (drop shadow, stroke, glow…: `layerEffectsPanel`) for layers that can take one, with or without a
|
|
126
|
+
* provider. There is no separate `effects` (Layer Effects) or `smart-filters` panel.
|
|
124
127
|
*/
|
|
125
128
|
export declare function layerPanels(layer: ImageLayer | null, options?: LayerPanelsOptions): LayerPanelDescriptor[];
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* `remove_effect`) on layers, where filter effects become smart filters, plus `add_effect_layer`
|
|
5
5
|
* for generator, overlay and title effects and `set_effect_layer` to change one (its effect, still
|
|
6
6
|
* frame or animation). (Drop shadows, strokes and the other layer styles are
|
|
7
|
-
* `
|
|
7
|
+
* `add_layer_effect`, a different thing: the Layer Style section of Layer Properties, not the
|
|
8
|
+
* Effects panel.)
|
|
8
9
|
*/
|
|
9
10
|
import { type AppliedEffectInfo } from '../effects/tools.cjs';
|
|
10
11
|
import type { AgentToolProvider } from '../tools/registry.cjs';
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* `remove_effect`) on layers, where filter effects become smart filters, plus `add_effect_layer`
|
|
5
5
|
* for generator, overlay and title effects and `set_effect_layer` to change one (its effect, still
|
|
6
6
|
* frame or animation). (Drop shadows, strokes and the other layer styles are
|
|
7
|
-
* `
|
|
7
|
+
* `add_layer_effect`, a different thing: the Layer Style section of Layer Properties, not the
|
|
8
|
+
* Effects panel.)
|
|
8
9
|
*/
|
|
9
10
|
import { type AppliedEffectInfo } from '../effects/tools.js';
|
|
10
11
|
import type { AgentToolProvider } from '../tools/registry.js';
|
package/package.json
CHANGED
|
@@ -49,6 +49,11 @@ For general error reporting and undo conventions, see `pixerate-agent-tools`.
|
|
|
49
49
|
|
|
50
50
|
- **Batch parameter changes.** Set all related control values in a single `effect_authoring_set_values`
|
|
51
51
|
call so they apply cleanly in a single undo step.
|
|
52
|
+
- **Write colours as hex.** A control with `type: "color"` in `effect_authoring_describe` takes
|
|
53
|
+
`#rrggbb` (or `#rrggbbaa` when `alpha` is true), even when the provider's schema also accepts 0–1
|
|
54
|
+
channel arrays or CSS colour strings (Flair's colours do). Hex keyframes blend smoothly. A control
|
|
55
|
+
that is in `values` but has no entry in `controls` has a shape no field can edit. Set it only with a
|
|
56
|
+
value that matches the provider's schema.
|
|
52
57
|
- **Check compile issues.** When editing source code via `effect_authoring_set_source`, always verify
|
|
53
58
|
the returned `issues` array. Fix errors before attempting to preview or set controls.
|
|
54
59
|
- **Keyframe animation tracks.** Controls with active keyframes calculate their values dynamically
|
|
@@ -117,7 +117,10 @@ drawing or editing either.
|
|
|
117
117
|
annotation and group layers (not adjustment layers) and follow the layer's pixels as they
|
|
118
118
|
change. Add them with `add_layer_effect` (`kind` plus only the `settings` that differ from
|
|
119
119
|
Photoshop's defaults), tune them with `update_layer_effect` and read them back with
|
|
120
|
-
`list_layer_effects`. Each call is one undo step and returns the layer's effects.
|
|
120
|
+
`list_layer_effects`. Each call is one undo step and returns the layer's effects. In the UI
|
|
121
|
+
they are the **Layer Style** section of **Layer Properties**; the separate **Effects** panel is
|
|
122
|
+
for provider effects (effect layers and filters), so say "layer style" when you tell the user
|
|
123
|
+
where a drop shadow or stroke lives.
|
|
121
124
|
2. **Keep the ids**: `add_layer_effect` returns `effectId`; `update_layer_effect` and
|
|
122
125
|
`remove_layer_effect` need it. `list_layers` shows which layers have effects (ids and kinds
|
|
123
126
|
only).
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
The host may register an effects provider (for example Flair). The tools then reach its catalog:
|
|
4
4
|
filter effects become **smart filters**, and generator, overlay and title effects become
|
|
5
|
-
**effect layers**. These are not the layer styles of `
|
|
5
|
+
**effect layers**. These are not the layer styles of `add_layer_effect` (drop shadow, stroke, glow).
|
|
6
|
+
In the UI, the **Effects** panel holds an effect layer's controls and the layer's filters; layer
|
|
7
|
+
styles are the **Layer Style** section of **Layer Properties**. Use those names when you tell the
|
|
8
|
+
user where to find what you changed.
|
|
6
9
|
|
|
7
10
|
## Working method
|
|
8
11
|
|