@pixerate/editor 0.280.0 → 0.282.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/animation-editor/index.cjs +59 -59
- package/dist/animation-editor/index.js +3 -3
- package/dist/brushes/index.cjs +76 -71
- package/dist/brushes/index.js +13 -8
- package/dist/brushes/schema.d.cts +1 -0
- package/dist/brushes/schema.d.ts +1 -0
- package/dist/brushes/types.d.cts +29 -3
- package/dist/brushes/types.d.ts +29 -3
- package/dist/{brushstrokeRender-EIK3625T.js → brushstrokeRender-4MA5CBW3.js} +3 -3
- package/dist/{brushstrokeRender-7HOMKZNO.cjs → brushstrokeRender-JVKVKWDA.cjs} +15 -15
- package/dist/canvas/edge-animation-tools.d.cts +115 -0
- package/dist/canvas/edge-animation-tools.d.ts +115 -0
- package/dist/canvas/edgeAnimation.d.cts +164 -0
- package/dist/canvas/edgeAnimation.d.ts +164 -0
- package/dist/canvas/edgePaths.d.cts +63 -0
- package/dist/canvas/edgePaths.d.ts +63 -0
- package/dist/canvas/index.cjs +691 -21
- package/dist/canvas/index.d.cts +3 -0
- package/dist/canvas/index.d.ts +3 -0
- package/dist/canvas/index.js +679 -9
- package/dist/{chunk-NJDEKU5D.js → chunk-2YGYYVSG.js} +1 -1
- package/dist/{chunk-JVFGK3DK.cjs → chunk-3JUKN3RM.cjs} +76 -53
- package/dist/{chunk-HN57I7KT.js → chunk-CG3FBNXE.js} +1 -1
- package/dist/{chunk-WFSYZO5Z.cjs → chunk-DFZ4I7EZ.cjs} +1 -1
- package/dist/{chunk-LZE2QZCT.js → chunk-IHMMHZGP.js} +1 -1
- package/dist/{chunk-K4ANWBF7.cjs → chunk-IJQ2YH2M.cjs} +35 -35
- package/dist/{chunk-HRUK5TFW.cjs → chunk-IUKPQCYQ.cjs} +164 -71
- package/dist/{chunk-WCC4NXWY.cjs → chunk-JD63B33V.cjs} +86 -86
- package/dist/{chunk-NJLPW4MM.js → chunk-KV7QHPKL.js} +27 -4
- package/dist/{chunk-H3EME3S5.cjs → chunk-MRIAR5DY.cjs} +2 -2
- package/dist/{chunk-ROURHJYT.js → chunk-NEDS6DSC.js} +1 -1
- package/dist/{chunk-FKO3CY2C.js → chunk-ULPXJ3NB.js} +1 -1
- package/dist/{chunk-WZYRYYXN.cjs → chunk-UOM5S4W5.cjs} +12 -12
- package/dist/{chunk-YOM76H2V.js → chunk-VEX6YVNG.js} +1 -1
- package/dist/{chunk-MNHP3AQT.cjs → chunk-WEXWDBUF.cjs} +23 -23
- package/dist/{chunk-PPDUCZZV.js → chunk-YRGTQLDN.js} +122 -29
- package/dist/image-editor/index.cjs +788 -788
- package/dist/image-editor/index.js +4 -4
- package/dist/paint-editor/antimatter.d.cts +154 -0
- package/dist/paint-editor/antimatter.d.ts +154 -0
- package/dist/paint-editor/brush-controls.d.cts +1 -0
- package/dist/paint-editor/brush-controls.d.ts +1 -0
- package/dist/paint-editor/brush-model.d.cts +9 -5
- package/dist/paint-editor/brush-model.d.ts +9 -5
- package/dist/paint-editor/controller.d.cts +23 -0
- package/dist/paint-editor/controller.d.ts +23 -0
- package/dist/paint-editor/index.cjs +1931 -891
- package/dist/paint-editor/index.d.cts +1 -0
- package/dist/paint-editor/index.d.ts +1 -0
- package/dist/paint-editor/index.js +1098 -58
- package/dist/paint-editor/mark-settings.d.cts +30 -0
- package/dist/paint-editor/mark-settings.d.ts +30 -0
- package/dist/paint-editor/stroke.d.cts +16 -0
- package/dist/paint-editor/stroke.d.ts +16 -0
- package/dist/paint-editor/strokes.d.cts +2 -0
- package/dist/paint-editor/strokes.d.ts +2 -0
- package/dist/paint-editor/ui.d.cts +4 -2
- package/dist/paint-editor/ui.d.ts +4 -2
- package/dist/vector/index.cjs +999 -999
- package/dist/vector/index.js +4 -4
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +1 -1
- package/skills/pixerate-canvas/SKILL.md +25 -2
- package/skills/pixerate-paint-editor/SKILL.md +8 -2
- package/skills/pixerate-paint-editor/references/antimatter.md +49 -0
- package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
package/dist/brushes/types.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { MixingModel } from '../paint/exchange.js';
|
|
|
16
16
|
import type { BlendMode } from '../raster/blend.js';
|
|
17
17
|
import type { BrushRotation, ImpastoTool, LivePatternKind, PaintBrush, WetMediumKind } from '../paint-editor/brushes.js';
|
|
18
18
|
import type { PaintEffectPaint } from '../paint-editor/effect-paint.js';
|
|
19
|
-
import type { DotRotation, DotTextureOrder, ParticleKind, ParticleRender, RibbonPairs } from '../paint-editor/mark-settings.js';
|
|
19
|
+
import type { DotRotation, DotTextureOrder, InvertMode, ParticleKind, ParticleRender, RibbonPairs } from '../paint-editor/mark-settings.js';
|
|
20
20
|
import type { StickerRef } from '../stickers/types.js';
|
|
21
21
|
/** `mark`: lays a material; `tool`: works on paint already down (erases, blends, smudges, wets…). */
|
|
22
22
|
export type BrushKind = 'mark' | 'tool';
|
|
@@ -35,7 +35,7 @@ export declare const BRUSH_TOOLS: readonly BrushTool[];
|
|
|
35
35
|
export type BrushTipShape = 'round' | 'flat' | 'chisel' | 'bristle' | 'stamp';
|
|
36
36
|
export declare const BRUSH_TIP_SHAPES: readonly BrushTipShape[];
|
|
37
37
|
/** How the tip is laid along the path. */
|
|
38
|
-
export type BrushMarksKind = 'continuous' | 'scatter' | 'particles' | 'objects';
|
|
38
|
+
export type BrushMarksKind = 'continuous' | 'scatter' | 'particles' | 'objects' | 'antimatter';
|
|
39
39
|
export declare const BRUSH_MARKS_KINDS: readonly BrushMarksKind[];
|
|
40
40
|
/** What the material does on the surface: stays where it lands (`dry`), flows and dries (`wet`) or stands up in relief (`thick`). */
|
|
41
41
|
export type BrushSurface = 'dry' | 'wet' | 'thick';
|
|
@@ -178,7 +178,33 @@ export interface BrushObjectMarks {
|
|
|
178
178
|
/** Random colour change, hue and lightness (default 0.2). */
|
|
179
179
|
colourJitter?: number;
|
|
180
180
|
}
|
|
181
|
-
|
|
181
|
+
/** Animated blasts that invert, scorch and destroy paint across every visible layer where the tip touches paint. */
|
|
182
|
+
export interface BrushAntimatterMarks {
|
|
183
|
+
kind: 'antimatter';
|
|
184
|
+
/** Blast size, in tip radii, 1..6 (default 2.5). */
|
|
185
|
+
blastRadius?: number;
|
|
186
|
+
/** Stroke travel between blasts, in tip diameters, 0.5..8 (default 2). */
|
|
187
|
+
blastSpacing?: number;
|
|
188
|
+
/** Paint needed under the tip to fire, 0..1 (default 0.1). */
|
|
189
|
+
threshold?: number;
|
|
190
|
+
/** Strength of the colour inversion in the blast core, 0..1 (default 1). */
|
|
191
|
+
invert?: number;
|
|
192
|
+
/** Colour inversion mode: `rgb` (default) or `oklab` (flips lightness and hue so mid-grey changes too). */
|
|
193
|
+
invertMode?: InvertMode;
|
|
194
|
+
/** Strength of the soot ring, 0..1 (default 0.6). */
|
|
195
|
+
scorch?: number;
|
|
196
|
+
/** Paint destroyed at the centre — alpha removed, 0..1 (default 0.25). */
|
|
197
|
+
annihilate?: number;
|
|
198
|
+
/** How many sparks fly out from each blast, 0..1 (default 0.5). */
|
|
199
|
+
sparks?: number;
|
|
200
|
+
/** How far sparks fly, in tip diameters, 0.5..8 (default 3). */
|
|
201
|
+
sparkReach?: number;
|
|
202
|
+
/** Depth of the dent on layers with relief, 0..1 (default 0.5). */
|
|
203
|
+
crater?: number;
|
|
204
|
+
/** Seconds a blast plays on screen, 0..2 (default 0.7; 0 shows the result at once). */
|
|
205
|
+
duration?: number;
|
|
206
|
+
}
|
|
207
|
+
export type BrushMarks = BrushContinuousMarks | BrushScatterMarks | BrushParticleMarks | BrushObjectMarks | BrushAntimatterMarks;
|
|
182
208
|
/** Pen feel. Every amount is 0 (off) .. 1 unless noted. */
|
|
183
209
|
export interface BrushDynamics {
|
|
184
210
|
/** Pressure scales the size (default true). */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
brushPreviewColours
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NEDS6DSC.js";
|
|
4
4
|
import {
|
|
5
5
|
pathDataToPolyline
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IHMMHZGP.js";
|
|
7
7
|
import {
|
|
8
8
|
BRUSH_PRESETS,
|
|
9
9
|
BUILTIN_BRUSHES,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
normalizeBrushSpec,
|
|
15
15
|
resolveBrush,
|
|
16
16
|
resolveCategory
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-YRGTQLDN.js";
|
|
18
18
|
import "./chunk-JL6YH5WD.js";
|
|
19
19
|
import {
|
|
20
20
|
formatNumber,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkMRIAR5DYcjs = require('./chunk-MRIAR5DY.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkDFZ4I7EZcjs = require('./chunk-DFZ4I7EZ.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -14,7 +14,7 @@ var _chunkWFSYZO5Zcjs = require('./chunk-WFSYZO5Z.cjs');
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
var _chunkIUKPQCYQcjs = require('./chunk-IUKPQCYQ.cjs');
|
|
18
18
|
require('./chunk-RDFHWAHL.cjs');
|
|
19
19
|
|
|
20
20
|
|
|
@@ -48,17 +48,17 @@ require('./chunk-5UEFBM2M.cjs');
|
|
|
48
48
|
require('./chunk-IPJ3TEYR.cjs');
|
|
49
49
|
|
|
50
50
|
// src/canvas/brushstrokeRender.ts
|
|
51
|
-
var PRESETS =
|
|
51
|
+
var PRESETS = _chunkIUKPQCYQcjs.listPresets.call(void 0, _chunkIUKPQCYQcjs.CANVAS_PROFILE).map((spec) => _chunkIUKPQCYQcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id));
|
|
52
52
|
var presetIds = () => PRESETS.map((b) => b.id).join(", ");
|
|
53
|
-
var refusal = (brush) =>
|
|
53
|
+
var refusal = (brush) => _chunkIUKPQCYQcjs.checkBrush.call(void 0, brush, _chunkIUKPQCYQcjs.CANVAS_PROFILE).issues.filter((i) => i.severity === "error").map((i) => `${i.reason} ${i.fix}`).join(" ");
|
|
54
54
|
function readCanvasBrushSpec(spec) {
|
|
55
55
|
let brush;
|
|
56
56
|
try {
|
|
57
|
-
brush =
|
|
57
|
+
brush = _chunkIUKPQCYQcjs.normalizeBrushSpec.call(void 0, spec);
|
|
58
58
|
} catch (e) {
|
|
59
59
|
throw new Error(`Not a brush: ${e.message}`);
|
|
60
60
|
}
|
|
61
|
-
if (!
|
|
61
|
+
if (!_chunkIUKPQCYQcjs.checkBrush.call(void 0, brush, _chunkIUKPQCYQcjs.CANVAS_PROFILE).ok) throw new Error(`Brush '${brush.id}' (${brush.name}) can't brush a canvas stroke: ${refusal(brush)}`);
|
|
62
62
|
return brush;
|
|
63
63
|
}
|
|
64
64
|
function listCanvasBrushes(user = []) {
|
|
@@ -66,12 +66,12 @@ function listCanvasBrushes(user = []) {
|
|
|
66
66
|
const d = _optionalChain([spec, 'access', _2 => _2.colour, 'optionalAccess', _3 => _3.default]);
|
|
67
67
|
return typeof d === "string" || _chunkMLLTWAXHcjs.isDualColor.call(void 0, d) ? { defaultColor: d } : {};
|
|
68
68
|
};
|
|
69
|
-
const out = PRESETS.map((b) => ({ id: b.id, name: b.name, category: b.category, size: b.tip.size, builtin: true, ...colourOf(
|
|
69
|
+
const out = PRESETS.map((b) => ({ id: b.id, name: b.name, category: b.category, size: b.tip.size, builtin: true, ...colourOf(_chunkIUKPQCYQcjs.BRUSH_PRESETS.find((p) => p.id === b.id)) }));
|
|
70
70
|
for (const raw of user) {
|
|
71
71
|
try {
|
|
72
72
|
const brush = readCanvasBrushSpec(raw);
|
|
73
73
|
if (out.some((b) => b.id === brush.id)) continue;
|
|
74
|
-
out.push({ id: brush.id, name: brush.name, category:
|
|
74
|
+
out.push({ id: brush.id, name: brush.name, category: _chunkIUKPQCYQcjs.resolveCategory.call(void 0, brush), size: _chunkIUKPQCYQcjs.resolveBrush.call(void 0, brush).tip.size, builtin: false, spec: brush, ...colourOf(brush) });
|
|
75
75
|
} catch (e2) {
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -82,15 +82,15 @@ function resolveCanvasBrush(brush, width, spec) {
|
|
|
82
82
|
const sized = (b) => given === void 0 ? b : { ...b, tip: { ...b.tip, size: given } };
|
|
83
83
|
if (typeof brush === "string") {
|
|
84
84
|
if (spec !== void 0 && spec !== null) {
|
|
85
|
-
const saved =
|
|
85
|
+
const saved = _chunkIUKPQCYQcjs.resolveBrush.call(void 0, readCanvasBrushSpec(spec));
|
|
86
86
|
if (!_chunkNPPMKMCUcjs.isBrushstrokeBrush.call(void 0, saved)) throw new Error(`Brush '${saved.id}' (${saved.name}) can't brush a canvas stroke: it is not a dry dab brush.`);
|
|
87
87
|
return sized(saved);
|
|
88
88
|
}
|
|
89
89
|
const preset = PRESETS.find((b) => b.id === brush);
|
|
90
90
|
if (preset) return sized(preset);
|
|
91
|
-
const other =
|
|
91
|
+
const other = _chunkIUKPQCYQcjs.BRUSH_PRESETS.find((b) => b.id === brush);
|
|
92
92
|
if (other) throw new Error(`Brush '${brush}' (${other.name}) can't brush a canvas stroke: ${refusal(other)} Use one of: ${presetIds()}, or a saved brush the canvas can paint.`);
|
|
93
|
-
throw new Error(`Unknown brush '${brush}'. ${
|
|
93
|
+
throw new Error(`Unknown brush '${brush}'. ${_chunkIUKPQCYQcjs.closest.call(void 0, brush, PRESETS.map((b) => b.id))}Use one of the dry presets (${presetIds()}), a saved brush from the brush library, or tip settings ({ hardness, spacing, flow, \u2026 }).`);
|
|
94
94
|
}
|
|
95
95
|
if (!brush || typeof brush !== "object" || Array.isArray(brush)) {
|
|
96
96
|
throw new Error("A brush is a preset or saved brush id (see listCanvasBrushes / canvas.listBrushes) or an object of tip settings.");
|
|
@@ -126,7 +126,7 @@ function renderShapeBrushstrokeNow(shape, scale, place = {}) {
|
|
|
126
126
|
const textured = typeof seed === "number" && Number.isFinite(seed);
|
|
127
127
|
const size = _nullishCoalesce(shape.brush.size, () => ( (textured ? void 0 : _nullishCoalesce(shape.strokeWidth, () => ( 3)))));
|
|
128
128
|
const brush = resolveCanvasBrush(shape.brush.brush, size, shape.brush.spec);
|
|
129
|
-
const points =
|
|
129
|
+
const points = _chunkDFZ4I7EZcjs.pathDataToPolyline.call(void 0, shape.d);
|
|
130
130
|
if (!points.length) return null;
|
|
131
131
|
const { pressure, tiltX, tiltY } = shape.brush;
|
|
132
132
|
const input = {
|
|
@@ -164,8 +164,8 @@ function brushedShapeSvgNow(shape, size, scale, place = {}) {
|
|
|
164
164
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${f(size.width)}" height="${f(size.height)}" viewBox="0 0 ${f(size.width)} ${f(size.height)}">${content}</svg>`;
|
|
165
165
|
}
|
|
166
166
|
function swatchColour(brush, background, spec) {
|
|
167
|
-
const facets = typeof brush !== "string" ? null : spec ? readCanvasBrushSpec(spec) :
|
|
168
|
-
return background && facets ?
|
|
167
|
+
const facets = typeof brush !== "string" ? null : spec ? readCanvasBrushSpec(spec) : _chunkIUKPQCYQcjs.BRUSH_PRESETS.find((b) => b.id === brush);
|
|
168
|
+
return background && facets ? _chunkMRIAR5DYcjs.brushPreviewColours.call(void 0, facets, { paper: background, profile: _chunkIUKPQCYQcjs.CANVAS_PROFILE, keepPaper: true }).color : "#1f2937";
|
|
169
169
|
}
|
|
170
170
|
function brushSwatchNow(brush, options, spec) {
|
|
171
171
|
const w = options.width && options.width > 8 ? options.width : 96;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tools for animated edges: `list_edge_animations`, `set_edge_animation` and
|
|
3
|
+
* `clear_edge_animation`. They read and write `edge.data.animation` through the host's edges, and
|
|
4
|
+
* each write is one undo step when a history is given.
|
|
5
|
+
*/
|
|
6
|
+
import type { Command } from '../history/types.cjs';
|
|
7
|
+
import type { AgentToolProvider } from '../tools/registry.cjs';
|
|
8
|
+
/** The edge fields the tools read: React Flow and Svelte Flow edges fit as they are. */
|
|
9
|
+
export interface CanvasEdgeAnimationToolEdge {
|
|
10
|
+
id: string;
|
|
11
|
+
source: string;
|
|
12
|
+
target: string;
|
|
13
|
+
label?: unknown;
|
|
14
|
+
data?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
export interface CanvasEdgeAnimationToolTarget<TEdge extends CanvasEdgeAnimationToolEdge = CanvasEdgeAnimationToolEdge> {
|
|
17
|
+
/** The edges on the canvas now. */
|
|
18
|
+
getEdges: () => readonly TEdge[];
|
|
19
|
+
/**
|
|
20
|
+
* Replaces the edges with the result of `update(current)`. React's `setEdges` fits as is; in
|
|
21
|
+
* Svelte, `(update) => (edges = update(edges))`.
|
|
22
|
+
*/
|
|
23
|
+
setEdges: (update: (current: TEdge[]) => TEdge[]) => void;
|
|
24
|
+
/** The canvas's undo history: each write is one step there. Without it, writes are not undoable. */
|
|
25
|
+
history?: {
|
|
26
|
+
execute(command: Command): void;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface CanvasEdgeAnimationToolProviderOptions {
|
|
30
|
+
/** Provider id (unique per registry). Default `canvas-edge-animation`. */
|
|
31
|
+
id?: string;
|
|
32
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
33
|
+
namespace?: string;
|
|
34
|
+
/** Edges cannot be changed: the write tools are hidden. A string is the reason. */
|
|
35
|
+
readOnly?: boolean | string | (() => boolean | string);
|
|
36
|
+
/** Lets the tool list follow changes. */
|
|
37
|
+
subscribe?: (notify: () => void) => () => void;
|
|
38
|
+
}
|
|
39
|
+
/** JSON Schema of {@link CanvasEdgeAnimation}, for tools and commands. */
|
|
40
|
+
export declare const CANVAS_EDGE_ANIMATION_SCHEMA: {
|
|
41
|
+
readonly type: "object";
|
|
42
|
+
readonly properties: {
|
|
43
|
+
readonly kind: {
|
|
44
|
+
readonly type: "string";
|
|
45
|
+
readonly enum: import("./edgeAnimation.cjs").CanvasEdgeAnimationKind[];
|
|
46
|
+
readonly description: "What moves: dots (travelling dots), dash (marching dashes), beam (a glowing streak that shoots along), pulse (the edge glows and fades).";
|
|
47
|
+
};
|
|
48
|
+
readonly speed: {
|
|
49
|
+
readonly type: "number";
|
|
50
|
+
readonly minimum: 1;
|
|
51
|
+
readonly maximum: 10000;
|
|
52
|
+
readonly description: "Travel speed in canvas units per second (dots, dash, beam). Defaults: dots 80, dash 40, beam 200.";
|
|
53
|
+
};
|
|
54
|
+
readonly duration: {
|
|
55
|
+
readonly type: "number";
|
|
56
|
+
readonly minimum: 100;
|
|
57
|
+
readonly maximum: 600000;
|
|
58
|
+
readonly description: "One cycle in ms; overrides speed. The pulse timing (default 1600).";
|
|
59
|
+
};
|
|
60
|
+
readonly direction: {
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
readonly enum: readonly ["forward", "reverse", "alternate"];
|
|
63
|
+
readonly description: "forward = source to target (default), reverse = target to source, alternate = back and forth.";
|
|
64
|
+
};
|
|
65
|
+
readonly color: {
|
|
66
|
+
readonly type: "string";
|
|
67
|
+
readonly minLength: 1;
|
|
68
|
+
readonly description: "CSS colour, e.g. \"#38bdf8\". Default: the edge stroke colour.";
|
|
69
|
+
};
|
|
70
|
+
readonly size: {
|
|
71
|
+
readonly type: "number";
|
|
72
|
+
readonly minimum: 0.5;
|
|
73
|
+
readonly maximum: 100;
|
|
74
|
+
readonly description: "Dot radius, or stroke width of dashes, beams and the pulse, in canvas units. Defaults: dots 3, dash 2, beam 3, pulse 4.";
|
|
75
|
+
};
|
|
76
|
+
readonly count: {
|
|
77
|
+
readonly type: "integer";
|
|
78
|
+
readonly minimum: 1;
|
|
79
|
+
readonly maximum: 50;
|
|
80
|
+
readonly description: "How many dots or beams are on the edge at once. Defaults: dots 3, beam 1.";
|
|
81
|
+
};
|
|
82
|
+
readonly length: {
|
|
83
|
+
readonly type: "number";
|
|
84
|
+
readonly minimum: 1;
|
|
85
|
+
readonly maximum: 10000;
|
|
86
|
+
readonly description: "Dash or beam length in canvas units. Defaults: dash 8, beam 40.";
|
|
87
|
+
};
|
|
88
|
+
readonly gap: {
|
|
89
|
+
readonly type: "number";
|
|
90
|
+
readonly minimum: 0;
|
|
91
|
+
readonly maximum: 10000;
|
|
92
|
+
readonly description: "Gap between dashes in canvas units (dash). Default 6.";
|
|
93
|
+
};
|
|
94
|
+
readonly glow: {
|
|
95
|
+
readonly type: "number";
|
|
96
|
+
readonly minimum: 0;
|
|
97
|
+
readonly maximum: 50;
|
|
98
|
+
readonly description: "Glow (blur) radius in canvas units; 0 is none. Defaults: beam 4, pulse 3, others 0.";
|
|
99
|
+
};
|
|
100
|
+
readonly trackOpacity: {
|
|
101
|
+
readonly type: "number";
|
|
102
|
+
readonly minimum: 0;
|
|
103
|
+
readonly maximum: 1;
|
|
104
|
+
readonly description: "Opacity of the edge's own line under the animation, 0-1. Defaults: dash 0 (the dashes are the line), beam 0.35, others 1.";
|
|
105
|
+
};
|
|
106
|
+
readonly paused: {
|
|
107
|
+
readonly type: "boolean";
|
|
108
|
+
readonly description: "Hold the animation still at its first frame. Default false.";
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
readonly required: readonly ["kind"];
|
|
112
|
+
readonly additionalProperties: false;
|
|
113
|
+
};
|
|
114
|
+
/** The edge animation tools for a canvas (see the module comment). */
|
|
115
|
+
export declare function createCanvasEdgeAnimationToolProvider<TEdge extends CanvasEdgeAnimationToolEdge = CanvasEdgeAnimationToolEdge>(target: CanvasEdgeAnimationToolTarget<TEdge>, options?: CanvasEdgeAnimationToolProviderOptions): AgentToolProvider;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tools for animated edges: `list_edge_animations`, `set_edge_animation` and
|
|
3
|
+
* `clear_edge_animation`. They read and write `edge.data.animation` through the host's edges, and
|
|
4
|
+
* each write is one undo step when a history is given.
|
|
5
|
+
*/
|
|
6
|
+
import type { Command } from '../history/types.js';
|
|
7
|
+
import type { AgentToolProvider } from '../tools/registry.js';
|
|
8
|
+
/** The edge fields the tools read: React Flow and Svelte Flow edges fit as they are. */
|
|
9
|
+
export interface CanvasEdgeAnimationToolEdge {
|
|
10
|
+
id: string;
|
|
11
|
+
source: string;
|
|
12
|
+
target: string;
|
|
13
|
+
label?: unknown;
|
|
14
|
+
data?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
export interface CanvasEdgeAnimationToolTarget<TEdge extends CanvasEdgeAnimationToolEdge = CanvasEdgeAnimationToolEdge> {
|
|
17
|
+
/** The edges on the canvas now. */
|
|
18
|
+
getEdges: () => readonly TEdge[];
|
|
19
|
+
/**
|
|
20
|
+
* Replaces the edges with the result of `update(current)`. React's `setEdges` fits as is; in
|
|
21
|
+
* Svelte, `(update) => (edges = update(edges))`.
|
|
22
|
+
*/
|
|
23
|
+
setEdges: (update: (current: TEdge[]) => TEdge[]) => void;
|
|
24
|
+
/** The canvas's undo history: each write is one step there. Without it, writes are not undoable. */
|
|
25
|
+
history?: {
|
|
26
|
+
execute(command: Command): void;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface CanvasEdgeAnimationToolProviderOptions {
|
|
30
|
+
/** Provider id (unique per registry). Default `canvas-edge-animation`. */
|
|
31
|
+
id?: string;
|
|
32
|
+
/** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
|
|
33
|
+
namespace?: string;
|
|
34
|
+
/** Edges cannot be changed: the write tools are hidden. A string is the reason. */
|
|
35
|
+
readOnly?: boolean | string | (() => boolean | string);
|
|
36
|
+
/** Lets the tool list follow changes. */
|
|
37
|
+
subscribe?: (notify: () => void) => () => void;
|
|
38
|
+
}
|
|
39
|
+
/** JSON Schema of {@link CanvasEdgeAnimation}, for tools and commands. */
|
|
40
|
+
export declare const CANVAS_EDGE_ANIMATION_SCHEMA: {
|
|
41
|
+
readonly type: "object";
|
|
42
|
+
readonly properties: {
|
|
43
|
+
readonly kind: {
|
|
44
|
+
readonly type: "string";
|
|
45
|
+
readonly enum: import("./edgeAnimation.js").CanvasEdgeAnimationKind[];
|
|
46
|
+
readonly description: "What moves: dots (travelling dots), dash (marching dashes), beam (a glowing streak that shoots along), pulse (the edge glows and fades).";
|
|
47
|
+
};
|
|
48
|
+
readonly speed: {
|
|
49
|
+
readonly type: "number";
|
|
50
|
+
readonly minimum: 1;
|
|
51
|
+
readonly maximum: 10000;
|
|
52
|
+
readonly description: "Travel speed in canvas units per second (dots, dash, beam). Defaults: dots 80, dash 40, beam 200.";
|
|
53
|
+
};
|
|
54
|
+
readonly duration: {
|
|
55
|
+
readonly type: "number";
|
|
56
|
+
readonly minimum: 100;
|
|
57
|
+
readonly maximum: 600000;
|
|
58
|
+
readonly description: "One cycle in ms; overrides speed. The pulse timing (default 1600).";
|
|
59
|
+
};
|
|
60
|
+
readonly direction: {
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
readonly enum: readonly ["forward", "reverse", "alternate"];
|
|
63
|
+
readonly description: "forward = source to target (default), reverse = target to source, alternate = back and forth.";
|
|
64
|
+
};
|
|
65
|
+
readonly color: {
|
|
66
|
+
readonly type: "string";
|
|
67
|
+
readonly minLength: 1;
|
|
68
|
+
readonly description: "CSS colour, e.g. \"#38bdf8\". Default: the edge stroke colour.";
|
|
69
|
+
};
|
|
70
|
+
readonly size: {
|
|
71
|
+
readonly type: "number";
|
|
72
|
+
readonly minimum: 0.5;
|
|
73
|
+
readonly maximum: 100;
|
|
74
|
+
readonly description: "Dot radius, or stroke width of dashes, beams and the pulse, in canvas units. Defaults: dots 3, dash 2, beam 3, pulse 4.";
|
|
75
|
+
};
|
|
76
|
+
readonly count: {
|
|
77
|
+
readonly type: "integer";
|
|
78
|
+
readonly minimum: 1;
|
|
79
|
+
readonly maximum: 50;
|
|
80
|
+
readonly description: "How many dots or beams are on the edge at once. Defaults: dots 3, beam 1.";
|
|
81
|
+
};
|
|
82
|
+
readonly length: {
|
|
83
|
+
readonly type: "number";
|
|
84
|
+
readonly minimum: 1;
|
|
85
|
+
readonly maximum: 10000;
|
|
86
|
+
readonly description: "Dash or beam length in canvas units. Defaults: dash 8, beam 40.";
|
|
87
|
+
};
|
|
88
|
+
readonly gap: {
|
|
89
|
+
readonly type: "number";
|
|
90
|
+
readonly minimum: 0;
|
|
91
|
+
readonly maximum: 10000;
|
|
92
|
+
readonly description: "Gap between dashes in canvas units (dash). Default 6.";
|
|
93
|
+
};
|
|
94
|
+
readonly glow: {
|
|
95
|
+
readonly type: "number";
|
|
96
|
+
readonly minimum: 0;
|
|
97
|
+
readonly maximum: 50;
|
|
98
|
+
readonly description: "Glow (blur) radius in canvas units; 0 is none. Defaults: beam 4, pulse 3, others 0.";
|
|
99
|
+
};
|
|
100
|
+
readonly trackOpacity: {
|
|
101
|
+
readonly type: "number";
|
|
102
|
+
readonly minimum: 0;
|
|
103
|
+
readonly maximum: 1;
|
|
104
|
+
readonly description: "Opacity of the edge's own line under the animation, 0-1. Defaults: dash 0 (the dashes are the line), beam 0.35, others 1.";
|
|
105
|
+
};
|
|
106
|
+
readonly paused: {
|
|
107
|
+
readonly type: "boolean";
|
|
108
|
+
readonly description: "Hold the animation still at its first frame. Default false.";
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
readonly required: readonly ["kind"];
|
|
112
|
+
readonly additionalProperties: false;
|
|
113
|
+
};
|
|
114
|
+
/** The edge animation tools for a canvas (see the module comment). */
|
|
115
|
+
export declare function createCanvasEdgeAnimationToolProvider<TEdge extends CanvasEdgeAnimationToolEdge = CanvasEdgeAnimationToolEdge>(target: CanvasEdgeAnimationToolTarget<TEdge>, options?: CanvasEdgeAnimationToolProviderOptions): AgentToolProvider;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animated canvas edges: dots travelling along an edge, marching dashes, beams of light and a
|
|
3
|
+
* pulsing glow. An edge's animation is data (`edge.data.animation`, a {@link CanvasEdgeAnimation}),
|
|
4
|
+
* so it saves, undoes and copies with the edge. {@link getCanvasEdgeAnimationRender} turns it into a
|
|
5
|
+
* framework-neutral list of SVG elements with SMIL timing, which `<AnimatedEdge>` /
|
|
6
|
+
* `<EdgeAnimation>` (React and Svelte) render; {@link sampleCanvasEdgeAnimation} gives the same
|
|
7
|
+
* picture at a moment in time without a browser (thumbnails, exports, tests, reduced motion).
|
|
8
|
+
*/
|
|
9
|
+
import type { CanvasConnectionLineType } from './connectors.cjs';
|
|
10
|
+
import { type MeasuredSvgPath, type SvgPathPoint } from './edgePaths.cjs';
|
|
11
|
+
/** What travels along the edge. */
|
|
12
|
+
export type CanvasEdgeAnimationKind = 'dots' | 'dash' | 'beam' | 'pulse';
|
|
13
|
+
/** Which way the animation runs: source → target, target → source, or back and forth. */
|
|
14
|
+
export type CanvasEdgeAnimationDirection = 'forward' | 'reverse' | 'alternate';
|
|
15
|
+
/** An edge's animation, stored at `edge.data.animation`. Every field but `kind` is optional. */
|
|
16
|
+
export interface CanvasEdgeAnimation {
|
|
17
|
+
kind: CanvasEdgeAnimationKind;
|
|
18
|
+
/** Travel speed in canvas units per second (`dots`, `dash`, `beam`). Defaults per kind. */
|
|
19
|
+
speed?: number;
|
|
20
|
+
/** Length of one cycle in ms; overrides `speed` (and is the only timing for `pulse`). */
|
|
21
|
+
duration?: number;
|
|
22
|
+
/** Default `forward` (source → target). */
|
|
23
|
+
direction?: CanvasEdgeAnimationDirection;
|
|
24
|
+
/** CSS colour. Default: the edge's stroke. */
|
|
25
|
+
color?: string;
|
|
26
|
+
/** Dot radius, or the stroke width of dashes, beams and the pulse, in canvas units. Defaults per kind. */
|
|
27
|
+
size?: number;
|
|
28
|
+
/** Number of dots or beams on the edge at once. Defaults per kind. */
|
|
29
|
+
count?: number;
|
|
30
|
+
/** Dash or beam length, in canvas units. Defaults per kind. */
|
|
31
|
+
length?: number;
|
|
32
|
+
/** Gap between dashes, in canvas units (`dash`). Default 6. */
|
|
33
|
+
gap?: number;
|
|
34
|
+
/** Glow radius (a blur behind the moving part), in canvas units. 0 is none. Defaults per kind. */
|
|
35
|
+
glow?: number;
|
|
36
|
+
/** Opacity of the edge's own stroke under the animation, 0–1. Default 1. */
|
|
37
|
+
trackOpacity?: number;
|
|
38
|
+
/** Held still at its first frame. Default false. */
|
|
39
|
+
paused?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface CanvasEdgeAnimationKindInfo {
|
|
42
|
+
kind: CanvasEdgeAnimationKind;
|
|
43
|
+
title: string;
|
|
44
|
+
description: string;
|
|
45
|
+
/** The values used for fields an animation leaves out. */
|
|
46
|
+
defaults: Required<Omit<CanvasEdgeAnimation, 'kind' | 'color' | 'duration' | 'paused'>> & {
|
|
47
|
+
duration?: number;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** The animation kinds, with what they look like and their defaults. */
|
|
51
|
+
export declare const CANVAS_EDGE_ANIMATION_KINDS: readonly CanvasEdgeAnimationKindInfo[];
|
|
52
|
+
/**
|
|
53
|
+
* Checks an animation and returns a clean copy (unknown fields dropped). Throws an error that says
|
|
54
|
+
* which field is wrong and what it accepts.
|
|
55
|
+
*/
|
|
56
|
+
export declare function normalizeCanvasEdgeAnimation(input: unknown): CanvasEdgeAnimation;
|
|
57
|
+
/** The edge's animation, or null when it has none or it is not valid. */
|
|
58
|
+
export declare function getCanvasEdgeAnimation(edge: {
|
|
59
|
+
data?: Record<string, any>;
|
|
60
|
+
} | null | undefined): CanvasEdgeAnimation | null;
|
|
61
|
+
/** A copy of the edge with its animation set (checked first), or removed when `animation` is null. */
|
|
62
|
+
export declare function setCanvasEdgeAnimation<TEdge extends {
|
|
63
|
+
data?: Record<string, any>;
|
|
64
|
+
}>(edge: TEdge, animation: CanvasEdgeAnimation | null): TEdge;
|
|
65
|
+
/** The animation with every default filled in, as it will play. */
|
|
66
|
+
export declare function resolveCanvasEdgeAnimation(animation: CanvasEdgeAnimation): Required<Omit<CanvasEdgeAnimation, 'color' | 'duration'>> & Pick<CanvasEdgeAnimation, 'color' | 'duration'>;
|
|
67
|
+
/** SMIL timing for an element: rendered as `<animate>` / `<animateMotion>` children. */
|
|
68
|
+
export interface CanvasEdgeAnimationTiming {
|
|
69
|
+
/** Seconds per cycle (SMIL `dur`). */
|
|
70
|
+
dur: number;
|
|
71
|
+
/** Start offset in seconds; negative starts part-way through (SMIL `begin`). */
|
|
72
|
+
begin: number;
|
|
73
|
+
}
|
|
74
|
+
/** One SVG element of an animated edge. Coordinates are canvas units. */
|
|
75
|
+
export type CanvasEdgeAnimationElement = {
|
|
76
|
+
type: 'dot';
|
|
77
|
+
key: string;
|
|
78
|
+
r: number;
|
|
79
|
+
fill: string;
|
|
80
|
+
filter?: string;
|
|
81
|
+
/** Where the dot is at the first frame (used when paused or with reduced motion). */
|
|
82
|
+
at: SvgPathPoint;
|
|
83
|
+
/** Travel along the path: `keyPoints` / `keyTimes` for `<animateMotion>`. */
|
|
84
|
+
motion: CanvasEdgeAnimationTiming & {
|
|
85
|
+
keyPoints: string;
|
|
86
|
+
keyTimes: string;
|
|
87
|
+
};
|
|
88
|
+
} | {
|
|
89
|
+
type: 'stroke';
|
|
90
|
+
key: string;
|
|
91
|
+
stroke: string;
|
|
92
|
+
strokeWidth: number;
|
|
93
|
+
strokeLinecap: 'round' | 'butt';
|
|
94
|
+
strokeDasharray?: string;
|
|
95
|
+
strokeDashoffset?: number;
|
|
96
|
+
opacity?: number;
|
|
97
|
+
filter?: string;
|
|
98
|
+
/** `<animate>`s to add: attribute, values (`;`-separated, SMIL), timing. */
|
|
99
|
+
animate: Array<CanvasEdgeAnimationTiming & {
|
|
100
|
+
attributeName: 'stroke-dashoffset' | 'stroke-opacity' | 'stroke-width';
|
|
101
|
+
values: string;
|
|
102
|
+
}>;
|
|
103
|
+
};
|
|
104
|
+
export interface CanvasEdgeAnimationRender {
|
|
105
|
+
kind: CanvasEdgeAnimationKind;
|
|
106
|
+
/** Path length in canvas units. */
|
|
107
|
+
length: number;
|
|
108
|
+
/** Opacity for the edge's own stroke. */
|
|
109
|
+
trackOpacity: number;
|
|
110
|
+
/** Whether the elements should move (false when paused, reduced motion or a zero-length path). */
|
|
111
|
+
moving: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* A blur filter to define in `<defs>` when anything glows. Its region is in user space (canvas
|
|
114
|
+
* units, `filterUnits="userSpaceOnUse"`): a straight edge has a zero-height box, and a filter
|
|
115
|
+
* sized to the box would hide it.
|
|
116
|
+
*/
|
|
117
|
+
glowFilter?: {
|
|
118
|
+
id: string;
|
|
119
|
+
stdDeviation: number;
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
};
|
|
125
|
+
elements: CanvasEdgeAnimationElement[];
|
|
126
|
+
}
|
|
127
|
+
export interface CanvasEdgeAnimationRenderOptions {
|
|
128
|
+
/** SVG path data of the edge (`getCanvasEdgePath(...).path` or the path your edge draws). */
|
|
129
|
+
path: string;
|
|
130
|
+
/** A unique id for this edge's defs (the edge id). */
|
|
131
|
+
id: string;
|
|
132
|
+
/** Colour used when the animation has none (the edge's stroke). Default `currentColor`. */
|
|
133
|
+
stroke?: string;
|
|
134
|
+
/** Draw the first frame without movement (honour `prefers-reduced-motion`). Default false. */
|
|
135
|
+
reducedMotion?: boolean;
|
|
136
|
+
/** A measured path to reuse, when you already have one for `path`. */
|
|
137
|
+
measured?: MeasuredSvgPath;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* How to draw an animated edge: SVG elements and SMIL timing, computed from the path. Dots use
|
|
141
|
+
* `<animateMotion>` along the path, dashes and beams animate `stroke-dashoffset`, the pulse animates
|
|
142
|
+
* opacity and width. Nothing here needs a DOM; the React and Svelte `<EdgeAnimation>` render it.
|
|
143
|
+
*/
|
|
144
|
+
export declare function getCanvasEdgeAnimationRender(animation: CanvasEdgeAnimation, options: CanvasEdgeAnimationRenderOptions): CanvasEdgeAnimationRender;
|
|
145
|
+
/** The animated part of an edge at one moment. */
|
|
146
|
+
export interface CanvasEdgeAnimationFrame {
|
|
147
|
+
kind: CanvasEdgeAnimationKind;
|
|
148
|
+
length: number;
|
|
149
|
+
/** Dot positions (`dots`). */
|
|
150
|
+
dots: SvgPathPoint[];
|
|
151
|
+
/** Visible stretches of the path as [from, to] distances (`dash`, `beam`), clipped to the path. */
|
|
152
|
+
segments: Array<[number, number]>;
|
|
153
|
+
/** Stroke opacity and width (`pulse`). */
|
|
154
|
+
opacity: number;
|
|
155
|
+
strokeWidth: number;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Where everything is `timeMs` into the animation: the same picture the SVG shows at that time,
|
|
159
|
+
* computed without a browser (for thumbnails, exports, canvas renderers and tests). A paused
|
|
160
|
+
* animation always returns its first frame.
|
|
161
|
+
*/
|
|
162
|
+
export declare function sampleCanvasEdgeAnimation(animation: CanvasEdgeAnimation, path: string | MeasuredSvgPath, timeMs: number): CanvasEdgeAnimationFrame;
|
|
163
|
+
/** Edge path styles `<AnimatedEdge>` can draw (read from `edge.data.pathType`). */
|
|
164
|
+
export type CanvasAnimatedEdgePathType = CanvasConnectionLineType;
|