@pixerate/editor 0.107.0 → 0.108.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/THIRD_PARTY_NOTICES.md +4 -0
- package/dist/animation-editor/index.cjs +39 -39
- package/dist/animation-editor/index.d.cts +1 -1
- package/dist/animation-editor/index.d.ts +1 -1
- package/dist/animation-editor/index.js +1 -1
- package/dist/{chunk-63EFQCT5.js → chunk-HUQ7EHVI.js} +1140 -371
- package/dist/chunk-HUQ7EHVI.js.map +1 -0
- package/dist/{chunk-KANRAHTL.cjs → chunk-UTEVPQTS.cjs} +1353 -584
- package/dist/chunk-UTEVPQTS.cjs.map +1 -0
- package/dist/paint-editor/index.cjs +196 -11
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +96 -2
- package/dist/paint-editor/index.d.ts +96 -2
- package/dist/paint-editor/index.js +190 -5
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/{svg-Bj1MQFh6.d.cts → svg-ClVIG4T7.d.cts} +26 -2
- package/dist/{svg-vme0PLNo.d.ts → svg-SseJTIrA.d.ts} +26 -2
- package/dist/vector/index.cjs +977 -948
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +266 -7
- package/dist/vector/index.d.ts +266 -7
- package/dist/vector/index.js +427 -398
- package/dist/vector/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +50 -7
- package/skills/pixerate-vector/SKILL.md +35 -5
- package/dist/chunk-63EFQCT5.js.map +0 -1
- package/dist/chunk-KANRAHTL.cjs.map +0 -1
|
@@ -4,6 +4,7 @@ export { b as MAX_BRUSH_SIZE } from '../mixer-5ziHU8OS.cjs';
|
|
|
4
4
|
import { R as RasterRect, a as TiledSurface, B as BlendMode, b as BlendModeInfo } from '../surface-CkKOHGPm.cjs';
|
|
5
5
|
export { c as BLEND_MODES, d as PAINTERLY_BLEND_MODES, e as Tile, i as isBlendMode, f as isPainterlyBlendMode, s as standardBlendMode } from '../surface-CkKOHGPm.cjs';
|
|
6
6
|
import { I as ImageEditorAssetStore, S as SerializedLayer, P as PsdExportResult } from '../export-JGWQEPJn.cjs';
|
|
7
|
+
import { g as PresenceStore, e as PresenceClock, d as PresenceActorInfo, c as PresenceActor, f as PresenceState } from '../presence-Cb6WhcrQ.cjs';
|
|
7
8
|
import { a as AgentToolProvider } from '../registry-BqA1AZt0.cjs';
|
|
8
9
|
import '../types-CwMPoRMU.cjs';
|
|
9
10
|
import '../warp-D5jz_tN7.cjs';
|
|
@@ -1385,7 +1386,8 @@ declare class PaintEditorController {
|
|
|
1385
1386
|
paintStroke(init: PaintStrokeInit & {
|
|
1386
1387
|
points: readonly PenPoint[];
|
|
1387
1388
|
}): PaintStrokeResult;
|
|
1388
|
-
|
|
1389
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
1390
|
+
checkPoints(points: readonly PenPoint[]): PenPoint[];
|
|
1389
1391
|
/** Every recorded stroke, oldest first. */
|
|
1390
1392
|
getStrokes(): readonly RecordedStroke[];
|
|
1391
1393
|
/**
|
|
@@ -1533,6 +1535,91 @@ declare class PaintEditorController {
|
|
|
1533
1535
|
/** Largest tracing or reference image side, in pixels. */
|
|
1534
1536
|
declare const MAX_IMAGE_SIDE = 8192;
|
|
1535
1537
|
|
|
1538
|
+
type PaintPresenceActor = PresenceActor;
|
|
1539
|
+
type PaintPresenceState = PresenceState;
|
|
1540
|
+
/** Cursor positions (document pixels) and notes of agents painting, for an overlay. */
|
|
1541
|
+
declare class PaintPresence extends PresenceStore {
|
|
1542
|
+
}
|
|
1543
|
+
/** What an agent asks for. Each command that paints commits as one undo step. */
|
|
1544
|
+
type PaintAgentCommand = {
|
|
1545
|
+
kind: 'stroke';
|
|
1546
|
+
stroke: PaintStrokeInit & {
|
|
1547
|
+
points: readonly PenPoint[];
|
|
1548
|
+
};
|
|
1549
|
+
note?: string;
|
|
1550
|
+
} | {
|
|
1551
|
+
kind: 'fill';
|
|
1552
|
+
fill: FillLayerOptions;
|
|
1553
|
+
note?: string;
|
|
1554
|
+
} | {
|
|
1555
|
+
kind: 'replay';
|
|
1556
|
+
replay: ReplayOptions;
|
|
1557
|
+
note?: string;
|
|
1558
|
+
} | {
|
|
1559
|
+
kind: 'point';
|
|
1560
|
+
at: {
|
|
1561
|
+
x: number;
|
|
1562
|
+
y: number;
|
|
1563
|
+
};
|
|
1564
|
+
note?: string;
|
|
1565
|
+
} | {
|
|
1566
|
+
kind: 'say';
|
|
1567
|
+
text: string;
|
|
1568
|
+
};
|
|
1569
|
+
type PaintPerformanceResult = {
|
|
1570
|
+
ok: true;
|
|
1571
|
+
command: PaintAgentCommand;
|
|
1572
|
+
result?: unknown;
|
|
1573
|
+
} | {
|
|
1574
|
+
ok: false;
|
|
1575
|
+
command: PaintAgentCommand;
|
|
1576
|
+
message: string;
|
|
1577
|
+
};
|
|
1578
|
+
interface PaintDirectorOptions {
|
|
1579
|
+
clock?: PresenceClock;
|
|
1580
|
+
/** 1 = natural speed; 2 = twice as fast. */
|
|
1581
|
+
speed?: number;
|
|
1582
|
+
/** Hide each actor's cursor this long after its last command (ms, default 1500; 0 keeps it). */
|
|
1583
|
+
linger?: number;
|
|
1584
|
+
/** Longest a stroke takes to paint at speed 1 (ms, default 1800); longer strokes are sped up. */
|
|
1585
|
+
maxStrokeMs?: number;
|
|
1586
|
+
}
|
|
1587
|
+
/** Where along a stroke each point is reached, 0..1: by its time `t` when the points have times, else by distance. */
|
|
1588
|
+
declare function strokeSchedule(points: readonly PenPoint[]): number[];
|
|
1589
|
+
/** How long a stroke takes to paint at speed 1 (ms): its recorded duration, else ~1.5 px/ms, between 250 ms and `max`. */
|
|
1590
|
+
declare function strokeDuration(points: readonly PenPoint[], max?: number): number;
|
|
1591
|
+
/** A zig-zag across `rect` (for a fill rubbed over the sheet), `rows` passes from the top. */
|
|
1592
|
+
declare function sweepPath(rect: RasterRect, rows?: number): Array<{
|
|
1593
|
+
x: number;
|
|
1594
|
+
y: number;
|
|
1595
|
+
}>;
|
|
1596
|
+
/**
|
|
1597
|
+
* Acts out agent commands on a paint canvas: the actor's cursor glides to the stroke's start and
|
|
1598
|
+
* paints it live along its points (paced by their times, or evenly), the stroke committing as
|
|
1599
|
+
* one undo step; fills are rubbed across the sheet first; replays start from the strokes they
|
|
1600
|
+
* copy and end on what they painted. Commands queue per actor. A command that cannot apply (an
|
|
1601
|
+
* unknown or locked layer, a stroke the user is still painting) fails with the controller's
|
|
1602
|
+
* sentence before anything is painted.
|
|
1603
|
+
*/
|
|
1604
|
+
declare class PaintDirector {
|
|
1605
|
+
private readonly controller;
|
|
1606
|
+
readonly presence: PaintPresence;
|
|
1607
|
+
private readonly options;
|
|
1608
|
+
private readonly clock;
|
|
1609
|
+
private readonly queue;
|
|
1610
|
+
constructor(controller: PaintEditorController, presence: PaintPresence, options?: PaintDirectorOptions);
|
|
1611
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
1612
|
+
perform(actor: PresenceActorInfo, commands: readonly PaintAgentCommand[]): Promise<PaintPerformanceResult[]>;
|
|
1613
|
+
private ms;
|
|
1614
|
+
private where;
|
|
1615
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
1616
|
+
private glide;
|
|
1617
|
+
private say;
|
|
1618
|
+
private performOne;
|
|
1619
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
1620
|
+
private stroke;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1536
1623
|
/**
|
|
1537
1624
|
* Agent tools for the paint editor (`createPaintEditorToolProvider`). Strict schemas, every
|
|
1538
1625
|
* argument described, all four annotations. Each write is one undo step (or editor state, said so)
|
|
@@ -1545,6 +1632,13 @@ interface PaintEditorToolProviderOptions {
|
|
|
1545
1632
|
id?: string;
|
|
1546
1633
|
/** Always prefix tool names with `<namespace>__`. */
|
|
1547
1634
|
namespace?: string;
|
|
1635
|
+
/**
|
|
1636
|
+
* Acts out strokes, fills and replays with an agent cursor on the canvas (see `PaintDirector`):
|
|
1637
|
+
* strokes paint live along their points. Each call is still one undo step. Without it, they apply at once.
|
|
1638
|
+
*/
|
|
1639
|
+
director?: PaintDirector;
|
|
1640
|
+
/** The agent's cursor (default `{ id: 'agent', name: 'Agent' }`). */
|
|
1641
|
+
actor?: PresenceActorInfo;
|
|
1548
1642
|
}
|
|
1549
1643
|
/** Agent tools for one paint editor. */
|
|
1550
1644
|
declare function createPaintEditorToolProvider(controller: PaintEditorController, options?: PaintEditorToolProviderOptions): AgentToolProvider;
|
|
@@ -1688,4 +1782,4 @@ interface BlendMenuGroup {
|
|
|
1688
1782
|
*/
|
|
1689
1783
|
declare const BLEND_MENU_GROUPS: readonly BlendMenuGroup[];
|
|
1690
1784
|
|
|
1691
|
-
export { type Affine, BLEND_MENU_GROUPS, BRUSH_ID, BRUSH_ROTATIONS, BRUSH_SLIDERS, BUILTIN_BRUSHES, type BlendMenuGroup, BlendMode, BlendModeInfo, type BrushDynamics, type BrushLibraryFile, type BrushRotation, type BrushThumbnail, type ColorWheel, DEFAULT_BRUSH_ID, DEFAULT_DPI, DEFAULT_DYNAMICS, DEFAULT_PAPER, DEFAULT_SWATCHES, DEFAULT_VIEW, DryStroke, type DryStrokeOptions, type FillLayerOptions, GRAIN_PATTERNS, GRAIN_TILE, type GrainPattern, type GrainTuning, HARMONY_KINDS, type Hand, type HarmonyColor, type HarmonyKind, IDENTITY_AFFINE, IDENTITY_COPY, type ImageEncoder, type ImageFormat, type ImageNode, type LayerUpdate, type Linear2, type LoadedPaintDocument, MAX_CANVAS_SIDE, MAX_COORDINATE, MAX_IMAGE_SIDE, MAX_ZOOM, MIN_CANVAS_SIDE, MIN_ZOOM, MIXING_PAD_HEIGHT, MIXING_PAD_WIDTH, MixingPad, type MixingPadTool, PAINT_BRUSH_CATEGORIES, PAINT_BRUSH_ENGINES, PAINT_FORMAT, PAINT_SCHEMA_VERSION, PAINT_TOOLS, PAPER_FAMILIES, PAPER_LIBRARY, PAPER_NODE_ID, PAPER_SLIDERS, type Paint2DContext, type PaintAssetStore, type PaintBrush, type PaintBrushCategory, type PaintBrushEngine, type PaintBrushInput, type PaintCanvas, PaintCanvasPresenter, PaintDocumentError, type PaintDocumentExtensions, type PaintDocumentState, PaintEditorController, PaintEditorError, type PaintEditorOptions, type PaintEditorState, type PaintEditorToolProviderOptions, PaintGesture, type PaintGroupLayer, type PaintGuides, type PaintLayer, type PaintLayerInfo, type PaintPixelLayer, type PaintPointerEvent, type PaintStrokeInit, type PaintStrokeResult, PaintStrokeSession, type PaintTool, type PaintView, type PaperFamily, PaperGrain, type PaperNode, type PaperSettings, type PaperTiling, type PenDab, PenDabWalker, type PenPoint, PenSmoother, type PerspectiveGuide, PerspectiveSnapper, type PixelImage, type Point2, type PointerSample, type RecordedStroke, type ReferenceImage, type RenderOptions, type ReplayOptions, type Rgb255, SNAP_DECIDE_DISTANCE, SYMMETRY_MODES, type SerializeOptions, type SerializedPaintDocument, type SliderControl, type StrokeCopy, type StrokeSessionHost, type StrokeSessionInit, type StrokeVariation, type Swatch, type SymmetryGuide, type SymmetryMode, TRACING_NODE_ID, TileableNoise, type TracingImage, type ViewLayer, type ViewportBox, affineCopy, applyAffine, brushToJSON, clonePaper, colorHarmony, composeAffine, createPaintCompositor, createPaintDocument, createPaintEditorToolProvider, createPaintLayer, decodeImageBlob, defaultGuides, defaultImageEncoder, deserializePaintDocument, deserializePaintDocumentAsync, documentExtensions, documentToScreen, downloadBytes, downsampleRgba, fitZoom, grainCatch, grainHeights, guideOverlay, handlePaintShortcut, hash2, hexToRgb8, hslToRgb, hsvToRgb, hueToWheel, invertAffine, isPalmTouch, mapPenPoint, mix32, mixerLoadForStroke, mixerTip, newPaintLayerId, normalizeBrushStroke, normalizeCanvas, normalizeDynamics, normalizePaintBrush, normalizePaper, normalizePerspective, normalizeRotation, normalizeSymmetry, normalizeView, paperGrain, paperKey, paperNode, paperPreset, parseBrushLibrary, parseHexColor, patchPath, penOrientation, perspectiveDirections, perspectiveGuideLines, pointerToPenPoint, rand01, randSigned, readPath, renderBrushThumbnail, renderColorWheel, renderPaper, rgbToHexColor, rgbToHsl, rgbToHsv, samplePressure, screenToDocument, seedFromString, serializePaintDocument, serializePaintDocumentExternal, strokeBounds, symmetryAxisAngles, symmetryAxisSegments, symmetryCopies, thumbnailStroke, tiltToOrientation, toStrokePoint, variationAffine, varyStroke, viewCssTransform, viewMatrix, viewPenToDocument, wheelAngle, wheelPick, wheelPoint, wheelToHue };
|
|
1785
|
+
export { type Affine, BLEND_MENU_GROUPS, BRUSH_ID, BRUSH_ROTATIONS, BRUSH_SLIDERS, BUILTIN_BRUSHES, type BlendMenuGroup, BlendMode, BlendModeInfo, type BrushDynamics, type BrushLibraryFile, type BrushRotation, type BrushThumbnail, type ColorWheel, DEFAULT_BRUSH_ID, DEFAULT_DPI, DEFAULT_DYNAMICS, DEFAULT_PAPER, DEFAULT_SWATCHES, DEFAULT_VIEW, DryStroke, type DryStrokeOptions, type FillLayerOptions, GRAIN_PATTERNS, GRAIN_TILE, type GrainPattern, type GrainTuning, HARMONY_KINDS, type Hand, type HarmonyColor, type HarmonyKind, IDENTITY_AFFINE, IDENTITY_COPY, type ImageEncoder, type ImageFormat, type ImageNode, type LayerUpdate, type Linear2, type LoadedPaintDocument, MAX_CANVAS_SIDE, MAX_COORDINATE, MAX_IMAGE_SIDE, MAX_ZOOM, MIN_CANVAS_SIDE, MIN_ZOOM, MIXING_PAD_HEIGHT, MIXING_PAD_WIDTH, MixingPad, type MixingPadTool, PAINT_BRUSH_CATEGORIES, PAINT_BRUSH_ENGINES, PAINT_FORMAT, PAINT_SCHEMA_VERSION, PAINT_TOOLS, PAPER_FAMILIES, PAPER_LIBRARY, PAPER_NODE_ID, PAPER_SLIDERS, type Paint2DContext, type PaintAgentCommand, type PaintAssetStore, type PaintBrush, type PaintBrushCategory, type PaintBrushEngine, type PaintBrushInput, type PaintCanvas, PaintCanvasPresenter, PaintDirector, type PaintDirectorOptions, PaintDocumentError, type PaintDocumentExtensions, type PaintDocumentState, PaintEditorController, PaintEditorError, type PaintEditorOptions, type PaintEditorState, type PaintEditorToolProviderOptions, PaintGesture, type PaintGroupLayer, type PaintGuides, type PaintLayer, type PaintLayerInfo, type PaintPerformanceResult, type PaintPixelLayer, type PaintPointerEvent, PaintPresence, type PaintPresenceActor, type PaintPresenceState, type PaintStrokeInit, type PaintStrokeResult, PaintStrokeSession, type PaintTool, type PaintView, type PaperFamily, PaperGrain, type PaperNode, type PaperSettings, type PaperTiling, type PenDab, PenDabWalker, type PenPoint, PenSmoother, type PerspectiveGuide, PerspectiveSnapper, type PixelImage, type Point2, type PointerSample, type RecordedStroke, type ReferenceImage, type RenderOptions, type ReplayOptions, type Rgb255, SNAP_DECIDE_DISTANCE, SYMMETRY_MODES, type SerializeOptions, type SerializedPaintDocument, type SliderControl, type StrokeCopy, type StrokeSessionHost, type StrokeSessionInit, type StrokeVariation, type Swatch, type SymmetryGuide, type SymmetryMode, TRACING_NODE_ID, TileableNoise, type TracingImage, type ViewLayer, type ViewportBox, affineCopy, applyAffine, brushToJSON, clonePaper, colorHarmony, composeAffine, createPaintCompositor, createPaintDocument, createPaintEditorToolProvider, createPaintLayer, decodeImageBlob, defaultGuides, defaultImageEncoder, deserializePaintDocument, deserializePaintDocumentAsync, documentExtensions, documentToScreen, downloadBytes, downsampleRgba, fitZoom, grainCatch, grainHeights, guideOverlay, handlePaintShortcut, hash2, hexToRgb8, hslToRgb, hsvToRgb, hueToWheel, invertAffine, isPalmTouch, mapPenPoint, mix32, mixerLoadForStroke, mixerTip, newPaintLayerId, normalizeBrushStroke, normalizeCanvas, normalizeDynamics, normalizePaintBrush, normalizePaper, normalizePerspective, normalizeRotation, normalizeSymmetry, normalizeView, paperGrain, paperKey, paperNode, paperPreset, parseBrushLibrary, parseHexColor, patchPath, penOrientation, perspectiveDirections, perspectiveGuideLines, pointerToPenPoint, rand01, randSigned, readPath, renderBrushThumbnail, renderColorWheel, renderPaper, rgbToHexColor, rgbToHsl, rgbToHsv, samplePressure, screenToDocument, seedFromString, serializePaintDocument, serializePaintDocumentExternal, strokeBounds, strokeDuration, strokeSchedule, sweepPath, symmetryAxisAngles, symmetryAxisSegments, symmetryCopies, thumbnailStroke, tiltToOrientation, toStrokePoint, variationAffine, varyStroke, viewCssTransform, viewMatrix, viewPenToDocument, wheelAngle, wheelPick, wheelPoint, wheelToHue };
|
|
@@ -4,6 +4,7 @@ export { b as MAX_BRUSH_SIZE } from '../mixer-DNqiYXYQ.js';
|
|
|
4
4
|
import { R as RasterRect, a as TiledSurface, B as BlendMode, b as BlendModeInfo } from '../surface-CkKOHGPm.js';
|
|
5
5
|
export { c as BLEND_MODES, d as PAINTERLY_BLEND_MODES, e as Tile, i as isBlendMode, f as isPainterlyBlendMode, s as standardBlendMode } from '../surface-CkKOHGPm.js';
|
|
6
6
|
import { I as ImageEditorAssetStore, S as SerializedLayer, P as PsdExportResult } from '../export-a9bnF7Cl.js';
|
|
7
|
+
import { g as PresenceStore, e as PresenceClock, d as PresenceActorInfo, c as PresenceActor, f as PresenceState } from '../presence-Cb6WhcrQ.js';
|
|
7
8
|
import { a as AgentToolProvider } from '../registry-D-4fit9C.js';
|
|
8
9
|
import '../types-CwMPoRMU.js';
|
|
9
10
|
import '../warp-CWHZzE3x.js';
|
|
@@ -1385,7 +1386,8 @@ declare class PaintEditorController {
|
|
|
1385
1386
|
paintStroke(init: PaintStrokeInit & {
|
|
1386
1387
|
points: readonly PenPoint[];
|
|
1387
1388
|
}): PaintStrokeResult;
|
|
1388
|
-
|
|
1389
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
1390
|
+
checkPoints(points: readonly PenPoint[]): PenPoint[];
|
|
1389
1391
|
/** Every recorded stroke, oldest first. */
|
|
1390
1392
|
getStrokes(): readonly RecordedStroke[];
|
|
1391
1393
|
/**
|
|
@@ -1533,6 +1535,91 @@ declare class PaintEditorController {
|
|
|
1533
1535
|
/** Largest tracing or reference image side, in pixels. */
|
|
1534
1536
|
declare const MAX_IMAGE_SIDE = 8192;
|
|
1535
1537
|
|
|
1538
|
+
type PaintPresenceActor = PresenceActor;
|
|
1539
|
+
type PaintPresenceState = PresenceState;
|
|
1540
|
+
/** Cursor positions (document pixels) and notes of agents painting, for an overlay. */
|
|
1541
|
+
declare class PaintPresence extends PresenceStore {
|
|
1542
|
+
}
|
|
1543
|
+
/** What an agent asks for. Each command that paints commits as one undo step. */
|
|
1544
|
+
type PaintAgentCommand = {
|
|
1545
|
+
kind: 'stroke';
|
|
1546
|
+
stroke: PaintStrokeInit & {
|
|
1547
|
+
points: readonly PenPoint[];
|
|
1548
|
+
};
|
|
1549
|
+
note?: string;
|
|
1550
|
+
} | {
|
|
1551
|
+
kind: 'fill';
|
|
1552
|
+
fill: FillLayerOptions;
|
|
1553
|
+
note?: string;
|
|
1554
|
+
} | {
|
|
1555
|
+
kind: 'replay';
|
|
1556
|
+
replay: ReplayOptions;
|
|
1557
|
+
note?: string;
|
|
1558
|
+
} | {
|
|
1559
|
+
kind: 'point';
|
|
1560
|
+
at: {
|
|
1561
|
+
x: number;
|
|
1562
|
+
y: number;
|
|
1563
|
+
};
|
|
1564
|
+
note?: string;
|
|
1565
|
+
} | {
|
|
1566
|
+
kind: 'say';
|
|
1567
|
+
text: string;
|
|
1568
|
+
};
|
|
1569
|
+
type PaintPerformanceResult = {
|
|
1570
|
+
ok: true;
|
|
1571
|
+
command: PaintAgentCommand;
|
|
1572
|
+
result?: unknown;
|
|
1573
|
+
} | {
|
|
1574
|
+
ok: false;
|
|
1575
|
+
command: PaintAgentCommand;
|
|
1576
|
+
message: string;
|
|
1577
|
+
};
|
|
1578
|
+
interface PaintDirectorOptions {
|
|
1579
|
+
clock?: PresenceClock;
|
|
1580
|
+
/** 1 = natural speed; 2 = twice as fast. */
|
|
1581
|
+
speed?: number;
|
|
1582
|
+
/** Hide each actor's cursor this long after its last command (ms, default 1500; 0 keeps it). */
|
|
1583
|
+
linger?: number;
|
|
1584
|
+
/** Longest a stroke takes to paint at speed 1 (ms, default 1800); longer strokes are sped up. */
|
|
1585
|
+
maxStrokeMs?: number;
|
|
1586
|
+
}
|
|
1587
|
+
/** Where along a stroke each point is reached, 0..1: by its time `t` when the points have times, else by distance. */
|
|
1588
|
+
declare function strokeSchedule(points: readonly PenPoint[]): number[];
|
|
1589
|
+
/** How long a stroke takes to paint at speed 1 (ms): its recorded duration, else ~1.5 px/ms, between 250 ms and `max`. */
|
|
1590
|
+
declare function strokeDuration(points: readonly PenPoint[], max?: number): number;
|
|
1591
|
+
/** A zig-zag across `rect` (for a fill rubbed over the sheet), `rows` passes from the top. */
|
|
1592
|
+
declare function sweepPath(rect: RasterRect, rows?: number): Array<{
|
|
1593
|
+
x: number;
|
|
1594
|
+
y: number;
|
|
1595
|
+
}>;
|
|
1596
|
+
/**
|
|
1597
|
+
* Acts out agent commands on a paint canvas: the actor's cursor glides to the stroke's start and
|
|
1598
|
+
* paints it live along its points (paced by their times, or evenly), the stroke committing as
|
|
1599
|
+
* one undo step; fills are rubbed across the sheet first; replays start from the strokes they
|
|
1600
|
+
* copy and end on what they painted. Commands queue per actor. A command that cannot apply (an
|
|
1601
|
+
* unknown or locked layer, a stroke the user is still painting) fails with the controller's
|
|
1602
|
+
* sentence before anything is painted.
|
|
1603
|
+
*/
|
|
1604
|
+
declare class PaintDirector {
|
|
1605
|
+
private readonly controller;
|
|
1606
|
+
readonly presence: PaintPresence;
|
|
1607
|
+
private readonly options;
|
|
1608
|
+
private readonly clock;
|
|
1609
|
+
private readonly queue;
|
|
1610
|
+
constructor(controller: PaintEditorController, presence: PaintPresence, options?: PaintDirectorOptions);
|
|
1611
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
1612
|
+
perform(actor: PresenceActorInfo, commands: readonly PaintAgentCommand[]): Promise<PaintPerformanceResult[]>;
|
|
1613
|
+
private ms;
|
|
1614
|
+
private where;
|
|
1615
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
1616
|
+
private glide;
|
|
1617
|
+
private say;
|
|
1618
|
+
private performOne;
|
|
1619
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
1620
|
+
private stroke;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1536
1623
|
/**
|
|
1537
1624
|
* Agent tools for the paint editor (`createPaintEditorToolProvider`). Strict schemas, every
|
|
1538
1625
|
* argument described, all four annotations. Each write is one undo step (or editor state, said so)
|
|
@@ -1545,6 +1632,13 @@ interface PaintEditorToolProviderOptions {
|
|
|
1545
1632
|
id?: string;
|
|
1546
1633
|
/** Always prefix tool names with `<namespace>__`. */
|
|
1547
1634
|
namespace?: string;
|
|
1635
|
+
/**
|
|
1636
|
+
* Acts out strokes, fills and replays with an agent cursor on the canvas (see `PaintDirector`):
|
|
1637
|
+
* strokes paint live along their points. Each call is still one undo step. Without it, they apply at once.
|
|
1638
|
+
*/
|
|
1639
|
+
director?: PaintDirector;
|
|
1640
|
+
/** The agent's cursor (default `{ id: 'agent', name: 'Agent' }`). */
|
|
1641
|
+
actor?: PresenceActorInfo;
|
|
1548
1642
|
}
|
|
1549
1643
|
/** Agent tools for one paint editor. */
|
|
1550
1644
|
declare function createPaintEditorToolProvider(controller: PaintEditorController, options?: PaintEditorToolProviderOptions): AgentToolProvider;
|
|
@@ -1688,4 +1782,4 @@ interface BlendMenuGroup {
|
|
|
1688
1782
|
*/
|
|
1689
1783
|
declare const BLEND_MENU_GROUPS: readonly BlendMenuGroup[];
|
|
1690
1784
|
|
|
1691
|
-
export { type Affine, BLEND_MENU_GROUPS, BRUSH_ID, BRUSH_ROTATIONS, BRUSH_SLIDERS, BUILTIN_BRUSHES, type BlendMenuGroup, BlendMode, BlendModeInfo, type BrushDynamics, type BrushLibraryFile, type BrushRotation, type BrushThumbnail, type ColorWheel, DEFAULT_BRUSH_ID, DEFAULT_DPI, DEFAULT_DYNAMICS, DEFAULT_PAPER, DEFAULT_SWATCHES, DEFAULT_VIEW, DryStroke, type DryStrokeOptions, type FillLayerOptions, GRAIN_PATTERNS, GRAIN_TILE, type GrainPattern, type GrainTuning, HARMONY_KINDS, type Hand, type HarmonyColor, type HarmonyKind, IDENTITY_AFFINE, IDENTITY_COPY, type ImageEncoder, type ImageFormat, type ImageNode, type LayerUpdate, type Linear2, type LoadedPaintDocument, MAX_CANVAS_SIDE, MAX_COORDINATE, MAX_IMAGE_SIDE, MAX_ZOOM, MIN_CANVAS_SIDE, MIN_ZOOM, MIXING_PAD_HEIGHT, MIXING_PAD_WIDTH, MixingPad, type MixingPadTool, PAINT_BRUSH_CATEGORIES, PAINT_BRUSH_ENGINES, PAINT_FORMAT, PAINT_SCHEMA_VERSION, PAINT_TOOLS, PAPER_FAMILIES, PAPER_LIBRARY, PAPER_NODE_ID, PAPER_SLIDERS, type Paint2DContext, type PaintAssetStore, type PaintBrush, type PaintBrushCategory, type PaintBrushEngine, type PaintBrushInput, type PaintCanvas, PaintCanvasPresenter, PaintDocumentError, type PaintDocumentExtensions, type PaintDocumentState, PaintEditorController, PaintEditorError, type PaintEditorOptions, type PaintEditorState, type PaintEditorToolProviderOptions, PaintGesture, type PaintGroupLayer, type PaintGuides, type PaintLayer, type PaintLayerInfo, type PaintPixelLayer, type PaintPointerEvent, type PaintStrokeInit, type PaintStrokeResult, PaintStrokeSession, type PaintTool, type PaintView, type PaperFamily, PaperGrain, type PaperNode, type PaperSettings, type PaperTiling, type PenDab, PenDabWalker, type PenPoint, PenSmoother, type PerspectiveGuide, PerspectiveSnapper, type PixelImage, type Point2, type PointerSample, type RecordedStroke, type ReferenceImage, type RenderOptions, type ReplayOptions, type Rgb255, SNAP_DECIDE_DISTANCE, SYMMETRY_MODES, type SerializeOptions, type SerializedPaintDocument, type SliderControl, type StrokeCopy, type StrokeSessionHost, type StrokeSessionInit, type StrokeVariation, type Swatch, type SymmetryGuide, type SymmetryMode, TRACING_NODE_ID, TileableNoise, type TracingImage, type ViewLayer, type ViewportBox, affineCopy, applyAffine, brushToJSON, clonePaper, colorHarmony, composeAffine, createPaintCompositor, createPaintDocument, createPaintEditorToolProvider, createPaintLayer, decodeImageBlob, defaultGuides, defaultImageEncoder, deserializePaintDocument, deserializePaintDocumentAsync, documentExtensions, documentToScreen, downloadBytes, downsampleRgba, fitZoom, grainCatch, grainHeights, guideOverlay, handlePaintShortcut, hash2, hexToRgb8, hslToRgb, hsvToRgb, hueToWheel, invertAffine, isPalmTouch, mapPenPoint, mix32, mixerLoadForStroke, mixerTip, newPaintLayerId, normalizeBrushStroke, normalizeCanvas, normalizeDynamics, normalizePaintBrush, normalizePaper, normalizePerspective, normalizeRotation, normalizeSymmetry, normalizeView, paperGrain, paperKey, paperNode, paperPreset, parseBrushLibrary, parseHexColor, patchPath, penOrientation, perspectiveDirections, perspectiveGuideLines, pointerToPenPoint, rand01, randSigned, readPath, renderBrushThumbnail, renderColorWheel, renderPaper, rgbToHexColor, rgbToHsl, rgbToHsv, samplePressure, screenToDocument, seedFromString, serializePaintDocument, serializePaintDocumentExternal, strokeBounds, symmetryAxisAngles, symmetryAxisSegments, symmetryCopies, thumbnailStroke, tiltToOrientation, toStrokePoint, variationAffine, varyStroke, viewCssTransform, viewMatrix, viewPenToDocument, wheelAngle, wheelPick, wheelPoint, wheelToHue };
|
|
1785
|
+
export { type Affine, BLEND_MENU_GROUPS, BRUSH_ID, BRUSH_ROTATIONS, BRUSH_SLIDERS, BUILTIN_BRUSHES, type BlendMenuGroup, BlendMode, BlendModeInfo, type BrushDynamics, type BrushLibraryFile, type BrushRotation, type BrushThumbnail, type ColorWheel, DEFAULT_BRUSH_ID, DEFAULT_DPI, DEFAULT_DYNAMICS, DEFAULT_PAPER, DEFAULT_SWATCHES, DEFAULT_VIEW, DryStroke, type DryStrokeOptions, type FillLayerOptions, GRAIN_PATTERNS, GRAIN_TILE, type GrainPattern, type GrainTuning, HARMONY_KINDS, type Hand, type HarmonyColor, type HarmonyKind, IDENTITY_AFFINE, IDENTITY_COPY, type ImageEncoder, type ImageFormat, type ImageNode, type LayerUpdate, type Linear2, type LoadedPaintDocument, MAX_CANVAS_SIDE, MAX_COORDINATE, MAX_IMAGE_SIDE, MAX_ZOOM, MIN_CANVAS_SIDE, MIN_ZOOM, MIXING_PAD_HEIGHT, MIXING_PAD_WIDTH, MixingPad, type MixingPadTool, PAINT_BRUSH_CATEGORIES, PAINT_BRUSH_ENGINES, PAINT_FORMAT, PAINT_SCHEMA_VERSION, PAINT_TOOLS, PAPER_FAMILIES, PAPER_LIBRARY, PAPER_NODE_ID, PAPER_SLIDERS, type Paint2DContext, type PaintAgentCommand, type PaintAssetStore, type PaintBrush, type PaintBrushCategory, type PaintBrushEngine, type PaintBrushInput, type PaintCanvas, PaintCanvasPresenter, PaintDirector, type PaintDirectorOptions, PaintDocumentError, type PaintDocumentExtensions, type PaintDocumentState, PaintEditorController, PaintEditorError, type PaintEditorOptions, type PaintEditorState, type PaintEditorToolProviderOptions, PaintGesture, type PaintGroupLayer, type PaintGuides, type PaintLayer, type PaintLayerInfo, type PaintPerformanceResult, type PaintPixelLayer, type PaintPointerEvent, PaintPresence, type PaintPresenceActor, type PaintPresenceState, type PaintStrokeInit, type PaintStrokeResult, PaintStrokeSession, type PaintTool, type PaintView, type PaperFamily, PaperGrain, type PaperNode, type PaperSettings, type PaperTiling, type PenDab, PenDabWalker, type PenPoint, PenSmoother, type PerspectiveGuide, PerspectiveSnapper, type PixelImage, type Point2, type PointerSample, type RecordedStroke, type ReferenceImage, type RenderOptions, type ReplayOptions, type Rgb255, SNAP_DECIDE_DISTANCE, SYMMETRY_MODES, type SerializeOptions, type SerializedPaintDocument, type SliderControl, type StrokeCopy, type StrokeSessionHost, type StrokeSessionInit, type StrokeVariation, type Swatch, type SymmetryGuide, type SymmetryMode, TRACING_NODE_ID, TileableNoise, type TracingImage, type ViewLayer, type ViewportBox, affineCopy, applyAffine, brushToJSON, clonePaper, colorHarmony, composeAffine, createPaintCompositor, createPaintDocument, createPaintEditorToolProvider, createPaintLayer, decodeImageBlob, defaultGuides, defaultImageEncoder, deserializePaintDocument, deserializePaintDocumentAsync, documentExtensions, documentToScreen, downloadBytes, downsampleRgba, fitZoom, grainCatch, grainHeights, guideOverlay, handlePaintShortcut, hash2, hexToRgb8, hslToRgb, hsvToRgb, hueToWheel, invertAffine, isPalmTouch, mapPenPoint, mix32, mixerLoadForStroke, mixerTip, newPaintLayerId, normalizeBrushStroke, normalizeCanvas, normalizeDynamics, normalizePaintBrush, normalizePaper, normalizePerspective, normalizeRotation, normalizeSymmetry, normalizeView, paperGrain, paperKey, paperNode, paperPreset, parseBrushLibrary, parseHexColor, patchPath, penOrientation, perspectiveDirections, perspectiveGuideLines, pointerToPenPoint, rand01, randSigned, readPath, renderBrushThumbnail, renderColorWheel, renderPaper, rgbToHexColor, rgbToHsl, rgbToHsv, samplePressure, screenToDocument, seedFromString, serializePaintDocument, serializePaintDocumentExternal, strokeBounds, strokeDuration, strokeSchedule, sweepPath, symmetryAxisAngles, symmetryAxisSegments, symmetryCopies, thumbnailStroke, tiltToOrientation, toStrokePoint, variationAffine, varyStroke, viewCssTransform, viewMatrix, viewPenToDocument, wheelAngle, wheelPick, wheelPoint, wheelToHue };
|
|
@@ -54,6 +54,12 @@ import {
|
|
|
54
54
|
tileKey,
|
|
55
55
|
tilesInRect
|
|
56
56
|
} from "../chunk-WMBIJCHA.js";
|
|
57
|
+
import {
|
|
58
|
+
PerformanceQueue,
|
|
59
|
+
PresenceStore,
|
|
60
|
+
realPresenceClock,
|
|
61
|
+
tweenPresenceCursor
|
|
62
|
+
} from "../chunk-B6DSIEXA.js";
|
|
57
63
|
import "../chunk-KKREERP2.js";
|
|
58
64
|
|
|
59
65
|
// src/paint-editor/noise.ts
|
|
@@ -2716,6 +2722,7 @@ var PaintEditorController = class {
|
|
|
2716
2722
|
else this.emit([]);
|
|
2717
2723
|
return result;
|
|
2718
2724
|
}
|
|
2725
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
2719
2726
|
checkPoints(points) {
|
|
2720
2727
|
if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
|
|
2721
2728
|
const out = [];
|
|
@@ -3250,6 +3257,169 @@ function resampleInto(src, rect, width, height) {
|
|
|
3250
3257
|
return { width, height, data: out };
|
|
3251
3258
|
}
|
|
3252
3259
|
|
|
3260
|
+
// src/paint-editor/presence.ts
|
|
3261
|
+
var PaintPresence = class extends PresenceStore {
|
|
3262
|
+
};
|
|
3263
|
+
var FRAME = 16;
|
|
3264
|
+
function strokeSchedule(points) {
|
|
3265
|
+
if (points.length < 2) return points.map(() => 1);
|
|
3266
|
+
const t0 = points[0].t;
|
|
3267
|
+
const t1 = points[points.length - 1].t;
|
|
3268
|
+
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) {
|
|
3269
|
+
return points.map((p) => Math.min(1, Math.max(0, (p.t - t0) / (t1 - t0))));
|
|
3270
|
+
}
|
|
3271
|
+
const acc = [0];
|
|
3272
|
+
for (let i = 1; i < points.length; i++) acc.push(acc[i - 1] + Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y));
|
|
3273
|
+
const total = acc[acc.length - 1];
|
|
3274
|
+
return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
|
|
3275
|
+
}
|
|
3276
|
+
function strokeDuration(points, max = 1800) {
|
|
3277
|
+
const t0 = points[0]?.t;
|
|
3278
|
+
const t1 = points[points.length - 1]?.t;
|
|
3279
|
+
let ms;
|
|
3280
|
+
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
|
|
3281
|
+
else {
|
|
3282
|
+
let length = 0;
|
|
3283
|
+
for (let i = 1; i < points.length; i++) length += Math.hypot(points[i].x - points[i - 1].x, points[i].y - points[i - 1].y);
|
|
3284
|
+
ms = length / 1.5;
|
|
3285
|
+
}
|
|
3286
|
+
return Math.min(max, Math.max(250, ms));
|
|
3287
|
+
}
|
|
3288
|
+
function sweepPath(rect, rows = 4) {
|
|
3289
|
+
const inset = Math.min(rect.width, rect.height) * 0.08;
|
|
3290
|
+
const left = rect.x + inset;
|
|
3291
|
+
const right = rect.x + rect.width - inset;
|
|
3292
|
+
const out = [];
|
|
3293
|
+
for (let r = 0; r < rows; r++) {
|
|
3294
|
+
const y = rect.y + inset + (rect.height - 2 * inset) * (r + 0.5) / rows;
|
|
3295
|
+
out.push(r % 2 ? { x: right, y } : { x: left, y }, r % 2 ? { x: left, y } : { x: right, y });
|
|
3296
|
+
}
|
|
3297
|
+
return out;
|
|
3298
|
+
}
|
|
3299
|
+
var centre = (r) => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });
|
|
3300
|
+
var PaintDirector = class {
|
|
3301
|
+
constructor(controller, presence, options = {}) {
|
|
3302
|
+
this.controller = controller;
|
|
3303
|
+
this.presence = presence;
|
|
3304
|
+
this.options = options;
|
|
3305
|
+
this.clock = options.clock ?? realPresenceClock;
|
|
3306
|
+
this.queue = new PerformanceQueue(presence, { clock: this.clock, linger: options.linger });
|
|
3307
|
+
}
|
|
3308
|
+
controller;
|
|
3309
|
+
presence;
|
|
3310
|
+
options;
|
|
3311
|
+
clock;
|
|
3312
|
+
queue;
|
|
3313
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
3314
|
+
perform(actor, commands) {
|
|
3315
|
+
return this.queue.run(actor, async () => {
|
|
3316
|
+
const results = [];
|
|
3317
|
+
for (const command of commands) {
|
|
3318
|
+
try {
|
|
3319
|
+
results.push({ ok: true, command, result: await this.performOne(actor.id, command) });
|
|
3320
|
+
} catch (error) {
|
|
3321
|
+
results.push({ ok: false, command, message: error instanceof Error ? error.message : String(error) });
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
return results;
|
|
3325
|
+
});
|
|
3326
|
+
}
|
|
3327
|
+
ms(n) {
|
|
3328
|
+
return Math.round(n / Math.max(0.1, this.options.speed ?? 1));
|
|
3329
|
+
}
|
|
3330
|
+
where(id) {
|
|
3331
|
+
const a = this.presence.get(id);
|
|
3332
|
+
return { x: a?.x ?? 0, y: a?.y ?? 0 };
|
|
3333
|
+
}
|
|
3334
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
3335
|
+
async glide(id, to, ms = 380) {
|
|
3336
|
+
const a = this.presence.get(id);
|
|
3337
|
+
if (!a || a.x === 0 && a.y === 0) {
|
|
3338
|
+
this.presence.set({ id, x: to.x, y: to.y });
|
|
3339
|
+
return;
|
|
3340
|
+
}
|
|
3341
|
+
await tweenPresenceCursor(this.presence, this.clock, id, this.where(id), to, this.ms(ms));
|
|
3342
|
+
}
|
|
3343
|
+
async say(id, text, ms) {
|
|
3344
|
+
if (!text) return;
|
|
3345
|
+
this.presence.set({ id, message: text });
|
|
3346
|
+
await this.clock.wait(this.ms(ms));
|
|
3347
|
+
}
|
|
3348
|
+
async performOne(id, command) {
|
|
3349
|
+
const c = this.controller;
|
|
3350
|
+
switch (command.kind) {
|
|
3351
|
+
case "say":
|
|
3352
|
+
await this.say(id, command.text, 900);
|
|
3353
|
+
return void 0;
|
|
3354
|
+
case "point":
|
|
3355
|
+
await this.say(id, command.note, 500);
|
|
3356
|
+
await this.glide(id, command.at);
|
|
3357
|
+
this.presence.set({ id, pressed: true });
|
|
3358
|
+
await this.clock.wait(this.ms(110));
|
|
3359
|
+
this.presence.set({ id, pressed: false });
|
|
3360
|
+
return void 0;
|
|
3361
|
+
case "stroke":
|
|
3362
|
+
await this.say(id, command.note, 500);
|
|
3363
|
+
return this.stroke(id, command.stroke);
|
|
3364
|
+
case "fill": {
|
|
3365
|
+
await this.say(id, command.note, 500);
|
|
3366
|
+
const { width, height } = c.getState().document.canvas;
|
|
3367
|
+
const path = sweepPath({ x: 0, y: 0, width, height });
|
|
3368
|
+
await this.glide(id, path[0]);
|
|
3369
|
+
this.presence.set({ id, pressed: true });
|
|
3370
|
+
try {
|
|
3371
|
+
for (let i = 1; i < path.length; i++) await tweenPresenceCursor(this.presence, this.clock, id, path[i - 1], path[i], this.ms(i % 2 ? 260 : 90));
|
|
3372
|
+
} finally {
|
|
3373
|
+
this.presence.set({ id, pressed: false });
|
|
3374
|
+
}
|
|
3375
|
+
return c.fillLayer(command.fill);
|
|
3376
|
+
}
|
|
3377
|
+
case "replay": {
|
|
3378
|
+
await this.say(id, command.note, 500);
|
|
3379
|
+
const source = c.getStrokes().filter((s) => command.replay.strokeIds?.includes(s.id));
|
|
3380
|
+
const first = source[0]?.points[0];
|
|
3381
|
+
if (first) await this.glide(id, first);
|
|
3382
|
+
const result = c.replayStrokes(command.replay);
|
|
3383
|
+
if (result.bounds) await this.glide(id, centre(result.bounds), 520);
|
|
3384
|
+
return result;
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
3389
|
+
async stroke(id, init) {
|
|
3390
|
+
const c = this.controller;
|
|
3391
|
+
const points = c.checkPoints(init.points);
|
|
3392
|
+
const { points: _points, ...rest } = init;
|
|
3393
|
+
const session = c.beginStroke({ snapToPerspective: false, start: points[0], ...rest });
|
|
3394
|
+
try {
|
|
3395
|
+
await this.glide(id, points[0]);
|
|
3396
|
+
this.presence.set({ id, pressed: true });
|
|
3397
|
+
const at = strokeSchedule(points);
|
|
3398
|
+
const duration = this.ms(strokeDuration(points, this.options.maxStrokeMs));
|
|
3399
|
+
let next = 0;
|
|
3400
|
+
const frames = Math.max(1, Math.round(duration / FRAME));
|
|
3401
|
+
for (let f = 1; f <= frames; f++) {
|
|
3402
|
+
const t = f / frames;
|
|
3403
|
+
const from = next;
|
|
3404
|
+
while (next < points.length && at[next] <= t + 1e-9) next++;
|
|
3405
|
+
if (next > from) {
|
|
3406
|
+
session.push(points.slice(from, next));
|
|
3407
|
+
const p = points[next - 1];
|
|
3408
|
+
this.presence.set({ id, x: p.x, y: p.y });
|
|
3409
|
+
}
|
|
3410
|
+
if (f < frames) await this.clock.wait(duration / frames);
|
|
3411
|
+
}
|
|
3412
|
+
if (next < points.length) session.push(points.slice(next));
|
|
3413
|
+
this.presence.set({ id, pressed: false });
|
|
3414
|
+
return session.end();
|
|
3415
|
+
} catch (error) {
|
|
3416
|
+
if (c.activeStroke === session) session.cancel();
|
|
3417
|
+
this.presence.set({ id, pressed: false });
|
|
3418
|
+
throw error;
|
|
3419
|
+
}
|
|
3420
|
+
}
|
|
3421
|
+
};
|
|
3422
|
+
|
|
3253
3423
|
// src/paint-editor/guide-tools.ts
|
|
3254
3424
|
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
3255
3425
|
var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
@@ -3685,6 +3855,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3685
3855
|
const c = controller;
|
|
3686
3856
|
const tools = [];
|
|
3687
3857
|
const add = (t) => tools.push(t);
|
|
3858
|
+
const act = async (command, direct) => {
|
|
3859
|
+
if (!options.director) return direct();
|
|
3860
|
+
const [r] = await options.director.perform(options.actor ?? { id: "agent", name: "Agent" }, [command]);
|
|
3861
|
+
if (!r || !r.ok) throw new Error(r && !r.ok ? r.message : "The director did not run the command.");
|
|
3862
|
+
return r.result;
|
|
3863
|
+
};
|
|
3688
3864
|
add({
|
|
3689
3865
|
name: "get_canvas_info",
|
|
3690
3866
|
title: "Get the canvas",
|
|
@@ -3949,7 +4125,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3949
4125
|
additionalProperties: false
|
|
3950
4126
|
},
|
|
3951
4127
|
annotations: { title: "Fill a layer", ...WRITE2 },
|
|
3952
|
-
handler: (a) => c.fillLayer(a)
|
|
4128
|
+
handler: (a) => act({ kind: "fill", fill: a }, () => c.fillLayer(a))
|
|
3953
4129
|
});
|
|
3954
4130
|
add({
|
|
3955
4131
|
name: "clear_layer",
|
|
@@ -4132,7 +4308,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4132
4308
|
add({
|
|
4133
4309
|
name: "paint_stroke",
|
|
4134
4310
|
title: "Paint a brush stroke",
|
|
4135
|
-
description: "Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.",
|
|
4311
|
+
description: "Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. With an agent cursor (a director), the stroke is painted live along the points at the pace of their times. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.",
|
|
4136
4312
|
inputSchema: {
|
|
4137
4313
|
type: "object",
|
|
4138
4314
|
properties: {
|
|
@@ -4148,8 +4324,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4148
4324
|
additionalProperties: false
|
|
4149
4325
|
},
|
|
4150
4326
|
annotations: { title: "Paint a brush stroke", ...WRITE2 },
|
|
4151
|
-
handler: (a) => {
|
|
4152
|
-
const
|
|
4327
|
+
handler: async (a) => {
|
|
4328
|
+
const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective };
|
|
4329
|
+
const r = await act({ kind: "stroke", stroke }, () => c.paintStroke(stroke));
|
|
4153
4330
|
return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
|
|
4154
4331
|
}
|
|
4155
4332
|
});
|
|
@@ -4223,7 +4400,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4223
4400
|
additionalProperties: false
|
|
4224
4401
|
},
|
|
4225
4402
|
annotations: { title: "Replay strokes, varied", ...WRITE2 },
|
|
4226
|
-
handler: (a) =>
|
|
4403
|
+
handler: (a) => {
|
|
4404
|
+
const replay = a;
|
|
4405
|
+
return act({ kind: "replay", replay }, () => c.replayStrokes(replay));
|
|
4406
|
+
}
|
|
4227
4407
|
});
|
|
4228
4408
|
add({
|
|
4229
4409
|
name: "set_view",
|
|
@@ -4675,10 +4855,12 @@ export {
|
|
|
4675
4855
|
PAPER_NODE_ID,
|
|
4676
4856
|
PAPER_SLIDERS,
|
|
4677
4857
|
PaintCanvasPresenter,
|
|
4858
|
+
PaintDirector,
|
|
4678
4859
|
PaintDocumentError,
|
|
4679
4860
|
PaintEditorController,
|
|
4680
4861
|
PaintEditorError,
|
|
4681
4862
|
PaintGesture,
|
|
4863
|
+
PaintPresence,
|
|
4682
4864
|
PaintStrokeSession,
|
|
4683
4865
|
PaperGrain,
|
|
4684
4866
|
PenDabWalker,
|
|
@@ -4762,6 +4944,9 @@ export {
|
|
|
4762
4944
|
serializePaintDocumentExternal,
|
|
4763
4945
|
standardBlendMode,
|
|
4764
4946
|
strokeBounds,
|
|
4947
|
+
strokeDuration,
|
|
4948
|
+
strokeSchedule,
|
|
4949
|
+
sweepPath,
|
|
4765
4950
|
symmetryAxisAngles,
|
|
4766
4951
|
symmetryAxisSegments,
|
|
4767
4952
|
symmetryCopies,
|