@pixerate/editor 0.107.0 → 0.109.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/index.cjs +5 -5
- package/dist/animation/index.cjs.map +1 -1
- package/dist/animation/index.js +9 -9
- package/dist/animation-editor/index.cjs +59 -59
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +2 -1
- package/dist/animation-editor/index.d.ts +2 -1
- package/dist/animation-editor/index.js +29 -29
- package/dist/canvas/index.cjs +27 -27
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +11 -11
- package/dist/{chunk-2FGRTYJN.cjs → chunk-477UVMNR.cjs} +3 -3
- package/dist/{chunk-2FGRTYJN.cjs.map → chunk-477UVMNR.cjs.map} +1 -1
- package/dist/{chunk-T3QZ6S47.cjs → chunk-AZTZRLDI.cjs} +40 -2
- package/dist/chunk-AZTZRLDI.cjs.map +1 -0
- package/dist/{chunk-63EFQCT5.js → chunk-BLWCAQCW.js} +2879 -3362
- package/dist/chunk-BLWCAQCW.js.map +1 -0
- package/dist/{chunk-G4BIYE6R.js → chunk-CFMWALBM.js} +39 -1
- package/dist/chunk-CFMWALBM.js.map +1 -0
- package/dist/{chunk-FRD3FUXI.cjs → chunk-D37BX2ZA.cjs} +2081 -460
- package/dist/chunk-D37BX2ZA.cjs.map +1 -0
- package/dist/chunk-JLYX4V57.cjs +2001 -0
- package/dist/chunk-JLYX4V57.cjs.map +1 -0
- package/dist/chunk-KB2YBCVS.js +2001 -0
- package/dist/chunk-KB2YBCVS.js.map +1 -0
- package/dist/{chunk-SOROZ2BF.js → chunk-RE77QYUF.js} +1938 -317
- package/dist/chunk-RE77QYUF.js.map +1 -0
- package/dist/{chunk-KANRAHTL.cjs → chunk-W3GXSUSQ.cjs} +2830 -3313
- package/dist/chunk-W3GXSUSQ.cjs.map +1 -0
- package/dist/{chunk-JK6M6V7G.js → chunk-Z3YWVUWT.js} +4 -4
- package/dist/{export-a9bnF7Cl.d.ts → export-BLPLaE6Z.d.ts} +417 -16
- package/dist/{export-JGWQEPJn.d.cts → export-DSUc4fQD.d.cts} +417 -16
- package/dist/image-editor/index.cjs +1527 -1001
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +73 -9
- package/dist/image-editor/index.d.ts +73 -9
- package/dist/image-editor/index.js +814 -288
- package/dist/image-editor/index.js.map +1 -1
- package/dist/paint-editor/index.cjs +252 -64
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +101 -4
- package/dist/paint-editor/index.d.ts +101 -4
- package/dist/paint-editor/index.js +196 -8
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +4 -2
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +3 -129
- package/dist/raster/index.d.ts +3 -129
- package/dist/raster/index.js +3 -1
- package/dist/{compositor-D92URMlm.d.cts → render-C-fO_mes.d.cts} +135 -1
- package/dist/{compositor-Kt_M4ruo.d.ts → render-OLIMk_v0.d.ts} +135 -1
- package/dist/{svg-vme0PLNo.d.ts → svg-D_cfkhlB.d.cts} +6 -608
- package/dist/{svg-Bj1MQFh6.d.cts → svg-wIaKLrU0.d.ts} +6 -608
- package/dist/types-DtL_qLFz.d.ts +630 -0
- package/dist/types-DyQq-WPY.d.cts +630 -0
- package/dist/vector/index.cjs +1080 -1051
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +268 -7
- package/dist/vector/index.d.ts +268 -7
- package/dist/vector/index.js +495 -466
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.cjs +3 -3
- package/dist/video-editor/index.js +2 -2
- 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-DWGZUSES.cjs +0 -694
- package/dist/chunk-DWGZUSES.cjs.map +0 -1
- package/dist/chunk-FRD3FUXI.cjs.map +0 -1
- package/dist/chunk-G4BIYE6R.js.map +0 -1
- package/dist/chunk-KANRAHTL.cjs.map +0 -1
- package/dist/chunk-KKREERP2.js +0 -694
- package/dist/chunk-KKREERP2.js.map +0 -1
- package/dist/chunk-SOROZ2BF.js.map +0 -1
- package/dist/chunk-T3QZ6S47.cjs.map +0 -1
- /package/dist/{chunk-JK6M6V7G.js.map → chunk-Z3YWVUWT.js.map} +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { R as RasterLayer, a as RasterGroupLayer, b as RasterPixelLayer, C as CompositorLayer, c as RasterCompositor, d as RasterSources, L as LayerLocks } from '../
|
|
1
|
+
import { R as RasterLayer, a as RasterGroupLayer, b as RasterPixelLayer, C as CompositorLayer, c as RasterCompositor, d as RasterSources, L as LayerLocks } from '../render-C-fO_mes.cjs';
|
|
2
2
|
import { B as BrushSettings, M as MixerSettings, C as CoverageMap, D as Dab, S as StrokePoint, a as MixerLoad } from '../mixer-5ziHU8OS.cjs';
|
|
3
3
|
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
|
-
import { I as ImageEditorAssetStore, S as SerializedLayer, P as PsdExportResult } from '../export-
|
|
6
|
+
import { I as ImageEditorAssetStore, S as SerializedLayer, P as PsdExportResult } from '../export-DSUc4fQD.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';
|
|
10
|
+
import '../types-DyQq-WPY.cjs';
|
|
11
|
+
import '../bezier-BfwIbVTl.cjs';
|
|
12
|
+
import '../types-BFkYA4eF.cjs';
|
|
9
13
|
import '../warp-D5jz_tN7.cjs';
|
|
10
14
|
import '../schema-Di0CS6Pe.cjs';
|
|
11
15
|
|
|
@@ -1385,7 +1389,8 @@ declare class PaintEditorController {
|
|
|
1385
1389
|
paintStroke(init: PaintStrokeInit & {
|
|
1386
1390
|
points: readonly PenPoint[];
|
|
1387
1391
|
}): PaintStrokeResult;
|
|
1388
|
-
|
|
1392
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
1393
|
+
checkPoints(points: readonly PenPoint[]): PenPoint[];
|
|
1389
1394
|
/** Every recorded stroke, oldest first. */
|
|
1390
1395
|
getStrokes(): readonly RecordedStroke[];
|
|
1391
1396
|
/**
|
|
@@ -1533,6 +1538,91 @@ declare class PaintEditorController {
|
|
|
1533
1538
|
/** Largest tracing or reference image side, in pixels. */
|
|
1534
1539
|
declare const MAX_IMAGE_SIDE = 8192;
|
|
1535
1540
|
|
|
1541
|
+
type PaintPresenceActor = PresenceActor;
|
|
1542
|
+
type PaintPresenceState = PresenceState;
|
|
1543
|
+
/** Cursor positions (document pixels) and notes of agents painting, for an overlay. */
|
|
1544
|
+
declare class PaintPresence extends PresenceStore {
|
|
1545
|
+
}
|
|
1546
|
+
/** What an agent asks for. Each command that paints commits as one undo step. */
|
|
1547
|
+
type PaintAgentCommand = {
|
|
1548
|
+
kind: 'stroke';
|
|
1549
|
+
stroke: PaintStrokeInit & {
|
|
1550
|
+
points: readonly PenPoint[];
|
|
1551
|
+
};
|
|
1552
|
+
note?: string;
|
|
1553
|
+
} | {
|
|
1554
|
+
kind: 'fill';
|
|
1555
|
+
fill: FillLayerOptions;
|
|
1556
|
+
note?: string;
|
|
1557
|
+
} | {
|
|
1558
|
+
kind: 'replay';
|
|
1559
|
+
replay: ReplayOptions;
|
|
1560
|
+
note?: string;
|
|
1561
|
+
} | {
|
|
1562
|
+
kind: 'point';
|
|
1563
|
+
at: {
|
|
1564
|
+
x: number;
|
|
1565
|
+
y: number;
|
|
1566
|
+
};
|
|
1567
|
+
note?: string;
|
|
1568
|
+
} | {
|
|
1569
|
+
kind: 'say';
|
|
1570
|
+
text: string;
|
|
1571
|
+
};
|
|
1572
|
+
type PaintPerformanceResult = {
|
|
1573
|
+
ok: true;
|
|
1574
|
+
command: PaintAgentCommand;
|
|
1575
|
+
result?: unknown;
|
|
1576
|
+
} | {
|
|
1577
|
+
ok: false;
|
|
1578
|
+
command: PaintAgentCommand;
|
|
1579
|
+
message: string;
|
|
1580
|
+
};
|
|
1581
|
+
interface PaintDirectorOptions {
|
|
1582
|
+
clock?: PresenceClock;
|
|
1583
|
+
/** 1 = natural speed; 2 = twice as fast. */
|
|
1584
|
+
speed?: number;
|
|
1585
|
+
/** Hide each actor's cursor this long after its last command (ms, default 1500; 0 keeps it). */
|
|
1586
|
+
linger?: number;
|
|
1587
|
+
/** Longest a stroke takes to paint at speed 1 (ms, default 1800); longer strokes are sped up. */
|
|
1588
|
+
maxStrokeMs?: number;
|
|
1589
|
+
}
|
|
1590
|
+
/** Where along a stroke each point is reached, 0..1: by its time `t` when the points have times, else by distance. */
|
|
1591
|
+
declare function strokeSchedule(points: readonly PenPoint[]): number[];
|
|
1592
|
+
/** How long a stroke takes to paint at speed 1 (ms): its recorded duration, else ~1.5 px/ms, between 250 ms and `max`. */
|
|
1593
|
+
declare function strokeDuration(points: readonly PenPoint[], max?: number): number;
|
|
1594
|
+
/** A zig-zag across `rect` (for a fill rubbed over the sheet), `rows` passes from the top. */
|
|
1595
|
+
declare function sweepPath(rect: RasterRect, rows?: number): Array<{
|
|
1596
|
+
x: number;
|
|
1597
|
+
y: number;
|
|
1598
|
+
}>;
|
|
1599
|
+
/**
|
|
1600
|
+
* Acts out agent commands on a paint canvas: the actor's cursor glides to the stroke's start and
|
|
1601
|
+
* paints it live along its points (paced by their times, or evenly), the stroke committing as
|
|
1602
|
+
* one undo step; fills are rubbed across the sheet first; replays start from the strokes they
|
|
1603
|
+
* copy and end on what they painted. Commands queue per actor. A command that cannot apply (an
|
|
1604
|
+
* unknown or locked layer, a stroke the user is still painting) fails with the controller's
|
|
1605
|
+
* sentence before anything is painted.
|
|
1606
|
+
*/
|
|
1607
|
+
declare class PaintDirector {
|
|
1608
|
+
private readonly controller;
|
|
1609
|
+
readonly presence: PaintPresence;
|
|
1610
|
+
private readonly options;
|
|
1611
|
+
private readonly clock;
|
|
1612
|
+
private readonly queue;
|
|
1613
|
+
constructor(controller: PaintEditorController, presence: PaintPresence, options?: PaintDirectorOptions);
|
|
1614
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
1615
|
+
perform(actor: PresenceActorInfo, commands: readonly PaintAgentCommand[]): Promise<PaintPerformanceResult[]>;
|
|
1616
|
+
private ms;
|
|
1617
|
+
private where;
|
|
1618
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
1619
|
+
private glide;
|
|
1620
|
+
private say;
|
|
1621
|
+
private performOne;
|
|
1622
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
1623
|
+
private stroke;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1536
1626
|
/**
|
|
1537
1627
|
* Agent tools for the paint editor (`createPaintEditorToolProvider`). Strict schemas, every
|
|
1538
1628
|
* argument described, all four annotations. Each write is one undo step (or editor state, said so)
|
|
@@ -1545,6 +1635,13 @@ interface PaintEditorToolProviderOptions {
|
|
|
1545
1635
|
id?: string;
|
|
1546
1636
|
/** Always prefix tool names with `<namespace>__`. */
|
|
1547
1637
|
namespace?: string;
|
|
1638
|
+
/**
|
|
1639
|
+
* Acts out strokes, fills and replays with an agent cursor on the canvas (see `PaintDirector`):
|
|
1640
|
+
* strokes paint live along their points. Each call is still one undo step. Without it, they apply at once.
|
|
1641
|
+
*/
|
|
1642
|
+
director?: PaintDirector;
|
|
1643
|
+
/** The agent's cursor (default `{ id: 'agent', name: 'Agent' }`). */
|
|
1644
|
+
actor?: PresenceActorInfo;
|
|
1548
1645
|
}
|
|
1549
1646
|
/** Agent tools for one paint editor. */
|
|
1550
1647
|
declare function createPaintEditorToolProvider(controller: PaintEditorController, options?: PaintEditorToolProviderOptions): AgentToolProvider;
|
|
@@ -1688,4 +1785,4 @@ interface BlendMenuGroup {
|
|
|
1688
1785
|
*/
|
|
1689
1786
|
declare const BLEND_MENU_GROUPS: readonly BlendMenuGroup[];
|
|
1690
1787
|
|
|
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 };
|
|
1788
|
+
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 };
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { R as RasterLayer, a as RasterGroupLayer, b as RasterPixelLayer, C as CompositorLayer, c as RasterCompositor, d as RasterSources, L as LayerLocks } from '../
|
|
1
|
+
import { R as RasterLayer, a as RasterGroupLayer, b as RasterPixelLayer, C as CompositorLayer, c as RasterCompositor, d as RasterSources, L as LayerLocks } from '../render-OLIMk_v0.js';
|
|
2
2
|
import { B as BrushSettings, M as MixerSettings, C as CoverageMap, D as Dab, S as StrokePoint, a as MixerLoad } from '../mixer-DNqiYXYQ.js';
|
|
3
3
|
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
|
-
import { I as ImageEditorAssetStore, S as SerializedLayer, P as PsdExportResult } from '../export-
|
|
6
|
+
import { I as ImageEditorAssetStore, S as SerializedLayer, P as PsdExportResult } from '../export-BLPLaE6Z.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';
|
|
10
|
+
import '../types-DtL_qLFz.js';
|
|
11
|
+
import '../bezier-DYBvLgUH.js';
|
|
12
|
+
import '../types-BFkYA4eF.js';
|
|
9
13
|
import '../warp-CWHZzE3x.js';
|
|
10
14
|
import '../schema-Di0CS6Pe.js';
|
|
11
15
|
|
|
@@ -1385,7 +1389,8 @@ declare class PaintEditorController {
|
|
|
1385
1389
|
paintStroke(init: PaintStrokeInit & {
|
|
1386
1390
|
points: readonly PenPoint[];
|
|
1387
1391
|
}): PaintStrokeResult;
|
|
1388
|
-
|
|
1392
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
1393
|
+
checkPoints(points: readonly PenPoint[]): PenPoint[];
|
|
1389
1394
|
/** Every recorded stroke, oldest first. */
|
|
1390
1395
|
getStrokes(): readonly RecordedStroke[];
|
|
1391
1396
|
/**
|
|
@@ -1533,6 +1538,91 @@ declare class PaintEditorController {
|
|
|
1533
1538
|
/** Largest tracing or reference image side, in pixels. */
|
|
1534
1539
|
declare const MAX_IMAGE_SIDE = 8192;
|
|
1535
1540
|
|
|
1541
|
+
type PaintPresenceActor = PresenceActor;
|
|
1542
|
+
type PaintPresenceState = PresenceState;
|
|
1543
|
+
/** Cursor positions (document pixels) and notes of agents painting, for an overlay. */
|
|
1544
|
+
declare class PaintPresence extends PresenceStore {
|
|
1545
|
+
}
|
|
1546
|
+
/** What an agent asks for. Each command that paints commits as one undo step. */
|
|
1547
|
+
type PaintAgentCommand = {
|
|
1548
|
+
kind: 'stroke';
|
|
1549
|
+
stroke: PaintStrokeInit & {
|
|
1550
|
+
points: readonly PenPoint[];
|
|
1551
|
+
};
|
|
1552
|
+
note?: string;
|
|
1553
|
+
} | {
|
|
1554
|
+
kind: 'fill';
|
|
1555
|
+
fill: FillLayerOptions;
|
|
1556
|
+
note?: string;
|
|
1557
|
+
} | {
|
|
1558
|
+
kind: 'replay';
|
|
1559
|
+
replay: ReplayOptions;
|
|
1560
|
+
note?: string;
|
|
1561
|
+
} | {
|
|
1562
|
+
kind: 'point';
|
|
1563
|
+
at: {
|
|
1564
|
+
x: number;
|
|
1565
|
+
y: number;
|
|
1566
|
+
};
|
|
1567
|
+
note?: string;
|
|
1568
|
+
} | {
|
|
1569
|
+
kind: 'say';
|
|
1570
|
+
text: string;
|
|
1571
|
+
};
|
|
1572
|
+
type PaintPerformanceResult = {
|
|
1573
|
+
ok: true;
|
|
1574
|
+
command: PaintAgentCommand;
|
|
1575
|
+
result?: unknown;
|
|
1576
|
+
} | {
|
|
1577
|
+
ok: false;
|
|
1578
|
+
command: PaintAgentCommand;
|
|
1579
|
+
message: string;
|
|
1580
|
+
};
|
|
1581
|
+
interface PaintDirectorOptions {
|
|
1582
|
+
clock?: PresenceClock;
|
|
1583
|
+
/** 1 = natural speed; 2 = twice as fast. */
|
|
1584
|
+
speed?: number;
|
|
1585
|
+
/** Hide each actor's cursor this long after its last command (ms, default 1500; 0 keeps it). */
|
|
1586
|
+
linger?: number;
|
|
1587
|
+
/** Longest a stroke takes to paint at speed 1 (ms, default 1800); longer strokes are sped up. */
|
|
1588
|
+
maxStrokeMs?: number;
|
|
1589
|
+
}
|
|
1590
|
+
/** Where along a stroke each point is reached, 0..1: by its time `t` when the points have times, else by distance. */
|
|
1591
|
+
declare function strokeSchedule(points: readonly PenPoint[]): number[];
|
|
1592
|
+
/** How long a stroke takes to paint at speed 1 (ms): its recorded duration, else ~1.5 px/ms, between 250 ms and `max`. */
|
|
1593
|
+
declare function strokeDuration(points: readonly PenPoint[], max?: number): number;
|
|
1594
|
+
/** A zig-zag across `rect` (for a fill rubbed over the sheet), `rows` passes from the top. */
|
|
1595
|
+
declare function sweepPath(rect: RasterRect, rows?: number): Array<{
|
|
1596
|
+
x: number;
|
|
1597
|
+
y: number;
|
|
1598
|
+
}>;
|
|
1599
|
+
/**
|
|
1600
|
+
* Acts out agent commands on a paint canvas: the actor's cursor glides to the stroke's start and
|
|
1601
|
+
* paints it live along its points (paced by their times, or evenly), the stroke committing as
|
|
1602
|
+
* one undo step; fills are rubbed across the sheet first; replays start from the strokes they
|
|
1603
|
+
* copy and end on what they painted. Commands queue per actor. A command that cannot apply (an
|
|
1604
|
+
* unknown or locked layer, a stroke the user is still painting) fails with the controller's
|
|
1605
|
+
* sentence before anything is painted.
|
|
1606
|
+
*/
|
|
1607
|
+
declare class PaintDirector {
|
|
1608
|
+
private readonly controller;
|
|
1609
|
+
readonly presence: PaintPresence;
|
|
1610
|
+
private readonly options;
|
|
1611
|
+
private readonly clock;
|
|
1612
|
+
private readonly queue;
|
|
1613
|
+
constructor(controller: PaintEditorController, presence: PaintPresence, options?: PaintDirectorOptions);
|
|
1614
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
1615
|
+
perform(actor: PresenceActorInfo, commands: readonly PaintAgentCommand[]): Promise<PaintPerformanceResult[]>;
|
|
1616
|
+
private ms;
|
|
1617
|
+
private where;
|
|
1618
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
1619
|
+
private glide;
|
|
1620
|
+
private say;
|
|
1621
|
+
private performOne;
|
|
1622
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
1623
|
+
private stroke;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1536
1626
|
/**
|
|
1537
1627
|
* Agent tools for the paint editor (`createPaintEditorToolProvider`). Strict schemas, every
|
|
1538
1628
|
* argument described, all four annotations. Each write is one undo step (or editor state, said so)
|
|
@@ -1545,6 +1635,13 @@ interface PaintEditorToolProviderOptions {
|
|
|
1545
1635
|
id?: string;
|
|
1546
1636
|
/** Always prefix tool names with `<namespace>__`. */
|
|
1547
1637
|
namespace?: string;
|
|
1638
|
+
/**
|
|
1639
|
+
* Acts out strokes, fills and replays with an agent cursor on the canvas (see `PaintDirector`):
|
|
1640
|
+
* strokes paint live along their points. Each call is still one undo step. Without it, they apply at once.
|
|
1641
|
+
*/
|
|
1642
|
+
director?: PaintDirector;
|
|
1643
|
+
/** The agent's cursor (default `{ id: 'agent', name: 'Agent' }`). */
|
|
1644
|
+
actor?: PresenceActorInfo;
|
|
1548
1645
|
}
|
|
1549
1646
|
/** Agent tools for one paint editor. */
|
|
1550
1647
|
declare function createPaintEditorToolProvider(controller: PaintEditorController, options?: PaintEditorToolProviderOptions): AgentToolProvider;
|
|
@@ -1688,4 +1785,4 @@ interface BlendMenuGroup {
|
|
|
1688
1785
|
*/
|
|
1689
1786
|
declare const BLEND_MENU_GROUPS: readonly BlendMenuGroup[];
|
|
1690
1787
|
|
|
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 };
|
|
1788
|
+
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,7 +4,7 @@ import {
|
|
|
4
4
|
resolveExternalAssets,
|
|
5
5
|
serializeLayers,
|
|
6
6
|
serializeLayersExternal
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-RE77QYUF.js";
|
|
8
8
|
import {
|
|
9
9
|
RasterCompositor,
|
|
10
10
|
bytesToBase64,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
mapLayer,
|
|
18
18
|
parseDataUrl,
|
|
19
19
|
pngDataUrl
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-CFMWALBM.js";
|
|
21
21
|
import "../chunk-GX332W2C.js";
|
|
22
22
|
import {
|
|
23
23
|
CoverageMap,
|
|
@@ -54,7 +54,16 @@ import {
|
|
|
54
54
|
tileKey,
|
|
55
55
|
tilesInRect
|
|
56
56
|
} from "../chunk-WMBIJCHA.js";
|
|
57
|
-
import
|
|
57
|
+
import {
|
|
58
|
+
PerformanceQueue,
|
|
59
|
+
PresenceStore,
|
|
60
|
+
realPresenceClock,
|
|
61
|
+
tweenPresenceCursor
|
|
62
|
+
} from "../chunk-B6DSIEXA.js";
|
|
63
|
+
import "../chunk-BLWCAQCW.js";
|
|
64
|
+
import "../chunk-YCSFS3GK.js";
|
|
65
|
+
import "../chunk-ZRJMJIQU.js";
|
|
66
|
+
import "../chunk-TGD52FEZ.js";
|
|
58
67
|
|
|
59
68
|
// src/paint-editor/noise.ts
|
|
60
69
|
function mix32(h) {
|
|
@@ -2716,6 +2725,7 @@ var PaintEditorController = class {
|
|
|
2716
2725
|
else this.emit([]);
|
|
2717
2726
|
return result;
|
|
2718
2727
|
}
|
|
2728
|
+
/** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */
|
|
2719
2729
|
checkPoints(points) {
|
|
2720
2730
|
if (!Array.isArray(points) || !points.length) throw new PaintEditorError("points is empty; give at least one {x, y} in document pixels.");
|
|
2721
2731
|
const out = [];
|
|
@@ -3250,6 +3260,169 @@ function resampleInto(src, rect, width, height) {
|
|
|
3250
3260
|
return { width, height, data: out };
|
|
3251
3261
|
}
|
|
3252
3262
|
|
|
3263
|
+
// src/paint-editor/presence.ts
|
|
3264
|
+
var PaintPresence = class extends PresenceStore {
|
|
3265
|
+
};
|
|
3266
|
+
var FRAME = 16;
|
|
3267
|
+
function strokeSchedule(points) {
|
|
3268
|
+
if (points.length < 2) return points.map(() => 1);
|
|
3269
|
+
const t0 = points[0].t;
|
|
3270
|
+
const t1 = points[points.length - 1].t;
|
|
3271
|
+
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) {
|
|
3272
|
+
return points.map((p) => Math.min(1, Math.max(0, (p.t - t0) / (t1 - t0))));
|
|
3273
|
+
}
|
|
3274
|
+
const acc = [0];
|
|
3275
|
+
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));
|
|
3276
|
+
const total = acc[acc.length - 1];
|
|
3277
|
+
return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
|
|
3278
|
+
}
|
|
3279
|
+
function strokeDuration(points, max = 1800) {
|
|
3280
|
+
const t0 = points[0]?.t;
|
|
3281
|
+
const t1 = points[points.length - 1]?.t;
|
|
3282
|
+
let ms;
|
|
3283
|
+
if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
|
|
3284
|
+
else {
|
|
3285
|
+
let length = 0;
|
|
3286
|
+
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);
|
|
3287
|
+
ms = length / 1.5;
|
|
3288
|
+
}
|
|
3289
|
+
return Math.min(max, Math.max(250, ms));
|
|
3290
|
+
}
|
|
3291
|
+
function sweepPath(rect, rows = 4) {
|
|
3292
|
+
const inset = Math.min(rect.width, rect.height) * 0.08;
|
|
3293
|
+
const left = rect.x + inset;
|
|
3294
|
+
const right = rect.x + rect.width - inset;
|
|
3295
|
+
const out = [];
|
|
3296
|
+
for (let r = 0; r < rows; r++) {
|
|
3297
|
+
const y = rect.y + inset + (rect.height - 2 * inset) * (r + 0.5) / rows;
|
|
3298
|
+
out.push(r % 2 ? { x: right, y } : { x: left, y }, r % 2 ? { x: left, y } : { x: right, y });
|
|
3299
|
+
}
|
|
3300
|
+
return out;
|
|
3301
|
+
}
|
|
3302
|
+
var centre = (r) => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });
|
|
3303
|
+
var PaintDirector = class {
|
|
3304
|
+
constructor(controller, presence, options = {}) {
|
|
3305
|
+
this.controller = controller;
|
|
3306
|
+
this.presence = presence;
|
|
3307
|
+
this.options = options;
|
|
3308
|
+
this.clock = options.clock ?? realPresenceClock;
|
|
3309
|
+
this.queue = new PerformanceQueue(presence, { clock: this.clock, linger: options.linger });
|
|
3310
|
+
}
|
|
3311
|
+
controller;
|
|
3312
|
+
presence;
|
|
3313
|
+
options;
|
|
3314
|
+
clock;
|
|
3315
|
+
queue;
|
|
3316
|
+
/** Acts out `commands` in order for `actor`. Resolves with one result per command. */
|
|
3317
|
+
perform(actor, commands) {
|
|
3318
|
+
return this.queue.run(actor, async () => {
|
|
3319
|
+
const results = [];
|
|
3320
|
+
for (const command of commands) {
|
|
3321
|
+
try {
|
|
3322
|
+
results.push({ ok: true, command, result: await this.performOne(actor.id, command) });
|
|
3323
|
+
} catch (error) {
|
|
3324
|
+
results.push({ ok: false, command, message: error instanceof Error ? error.message : String(error) });
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
return results;
|
|
3328
|
+
});
|
|
3329
|
+
}
|
|
3330
|
+
ms(n) {
|
|
3331
|
+
return Math.round(n / Math.max(0.1, this.options.speed ?? 1));
|
|
3332
|
+
}
|
|
3333
|
+
where(id) {
|
|
3334
|
+
const a = this.presence.get(id);
|
|
3335
|
+
return { x: a?.x ?? 0, y: a?.y ?? 0 };
|
|
3336
|
+
}
|
|
3337
|
+
/** Glides to `to`; an actor that just appeared starts there instead of the corner. */
|
|
3338
|
+
async glide(id, to, ms = 380) {
|
|
3339
|
+
const a = this.presence.get(id);
|
|
3340
|
+
if (!a || a.x === 0 && a.y === 0) {
|
|
3341
|
+
this.presence.set({ id, x: to.x, y: to.y });
|
|
3342
|
+
return;
|
|
3343
|
+
}
|
|
3344
|
+
await tweenPresenceCursor(this.presence, this.clock, id, this.where(id), to, this.ms(ms));
|
|
3345
|
+
}
|
|
3346
|
+
async say(id, text, ms) {
|
|
3347
|
+
if (!text) return;
|
|
3348
|
+
this.presence.set({ id, message: text });
|
|
3349
|
+
await this.clock.wait(this.ms(ms));
|
|
3350
|
+
}
|
|
3351
|
+
async performOne(id, command) {
|
|
3352
|
+
const c = this.controller;
|
|
3353
|
+
switch (command.kind) {
|
|
3354
|
+
case "say":
|
|
3355
|
+
await this.say(id, command.text, 900);
|
|
3356
|
+
return void 0;
|
|
3357
|
+
case "point":
|
|
3358
|
+
await this.say(id, command.note, 500);
|
|
3359
|
+
await this.glide(id, command.at);
|
|
3360
|
+
this.presence.set({ id, pressed: true });
|
|
3361
|
+
await this.clock.wait(this.ms(110));
|
|
3362
|
+
this.presence.set({ id, pressed: false });
|
|
3363
|
+
return void 0;
|
|
3364
|
+
case "stroke":
|
|
3365
|
+
await this.say(id, command.note, 500);
|
|
3366
|
+
return this.stroke(id, command.stroke);
|
|
3367
|
+
case "fill": {
|
|
3368
|
+
await this.say(id, command.note, 500);
|
|
3369
|
+
const { width, height } = c.getState().document.canvas;
|
|
3370
|
+
const path = sweepPath({ x: 0, y: 0, width, height });
|
|
3371
|
+
await this.glide(id, path[0]);
|
|
3372
|
+
this.presence.set({ id, pressed: true });
|
|
3373
|
+
try {
|
|
3374
|
+
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));
|
|
3375
|
+
} finally {
|
|
3376
|
+
this.presence.set({ id, pressed: false });
|
|
3377
|
+
}
|
|
3378
|
+
return c.fillLayer(command.fill);
|
|
3379
|
+
}
|
|
3380
|
+
case "replay": {
|
|
3381
|
+
await this.say(id, command.note, 500);
|
|
3382
|
+
const source = c.getStrokes().filter((s) => command.replay.strokeIds?.includes(s.id));
|
|
3383
|
+
const first = source[0]?.points[0];
|
|
3384
|
+
if (first) await this.glide(id, first);
|
|
3385
|
+
const result = c.replayStrokes(command.replay);
|
|
3386
|
+
if (result.bounds) await this.glide(id, centre(result.bounds), 520);
|
|
3387
|
+
return result;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
/** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */
|
|
3392
|
+
async stroke(id, init) {
|
|
3393
|
+
const c = this.controller;
|
|
3394
|
+
const points = c.checkPoints(init.points);
|
|
3395
|
+
const { points: _points, ...rest } = init;
|
|
3396
|
+
const session = c.beginStroke({ snapToPerspective: false, start: points[0], ...rest });
|
|
3397
|
+
try {
|
|
3398
|
+
await this.glide(id, points[0]);
|
|
3399
|
+
this.presence.set({ id, pressed: true });
|
|
3400
|
+
const at = strokeSchedule(points);
|
|
3401
|
+
const duration = this.ms(strokeDuration(points, this.options.maxStrokeMs));
|
|
3402
|
+
let next = 0;
|
|
3403
|
+
const frames = Math.max(1, Math.round(duration / FRAME));
|
|
3404
|
+
for (let f = 1; f <= frames; f++) {
|
|
3405
|
+
const t = f / frames;
|
|
3406
|
+
const from = next;
|
|
3407
|
+
while (next < points.length && at[next] <= t + 1e-9) next++;
|
|
3408
|
+
if (next > from) {
|
|
3409
|
+
session.push(points.slice(from, next));
|
|
3410
|
+
const p = points[next - 1];
|
|
3411
|
+
this.presence.set({ id, x: p.x, y: p.y });
|
|
3412
|
+
}
|
|
3413
|
+
if (f < frames) await this.clock.wait(duration / frames);
|
|
3414
|
+
}
|
|
3415
|
+
if (next < points.length) session.push(points.slice(next));
|
|
3416
|
+
this.presence.set({ id, pressed: false });
|
|
3417
|
+
return session.end();
|
|
3418
|
+
} catch (error) {
|
|
3419
|
+
if (c.activeStroke === session) session.cancel();
|
|
3420
|
+
this.presence.set({ id, pressed: false });
|
|
3421
|
+
throw error;
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
};
|
|
3425
|
+
|
|
3253
3426
|
// src/paint-editor/guide-tools.ts
|
|
3254
3427
|
var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
3255
3428
|
var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
@@ -3685,6 +3858,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3685
3858
|
const c = controller;
|
|
3686
3859
|
const tools = [];
|
|
3687
3860
|
const add = (t) => tools.push(t);
|
|
3861
|
+
const act = async (command, direct) => {
|
|
3862
|
+
if (!options.director) return direct();
|
|
3863
|
+
const [r] = await options.director.perform(options.actor ?? { id: "agent", name: "Agent" }, [command]);
|
|
3864
|
+
if (!r || !r.ok) throw new Error(r && !r.ok ? r.message : "The director did not run the command.");
|
|
3865
|
+
return r.result;
|
|
3866
|
+
};
|
|
3688
3867
|
add({
|
|
3689
3868
|
name: "get_canvas_info",
|
|
3690
3869
|
title: "Get the canvas",
|
|
@@ -3949,7 +4128,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
3949
4128
|
additionalProperties: false
|
|
3950
4129
|
},
|
|
3951
4130
|
annotations: { title: "Fill a layer", ...WRITE2 },
|
|
3952
|
-
handler: (a) => c.fillLayer(a)
|
|
4131
|
+
handler: (a) => act({ kind: "fill", fill: a }, () => c.fillLayer(a))
|
|
3953
4132
|
});
|
|
3954
4133
|
add({
|
|
3955
4134
|
name: "clear_layer",
|
|
@@ -4132,7 +4311,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4132
4311
|
add({
|
|
4133
4312
|
name: "paint_stroke",
|
|
4134
4313
|
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.",
|
|
4314
|
+
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
4315
|
inputSchema: {
|
|
4137
4316
|
type: "object",
|
|
4138
4317
|
properties: {
|
|
@@ -4148,8 +4327,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4148
4327
|
additionalProperties: false
|
|
4149
4328
|
},
|
|
4150
4329
|
annotations: { title: "Paint a brush stroke", ...WRITE2 },
|
|
4151
|
-
handler: (a) => {
|
|
4152
|
-
const
|
|
4330
|
+
handler: async (a) => {
|
|
4331
|
+
const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective };
|
|
4332
|
+
const r = await act({ kind: "stroke", stroke }, () => c.paintStroke(stroke));
|
|
4153
4333
|
return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
|
|
4154
4334
|
}
|
|
4155
4335
|
});
|
|
@@ -4223,7 +4403,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
|
|
|
4223
4403
|
additionalProperties: false
|
|
4224
4404
|
},
|
|
4225
4405
|
annotations: { title: "Replay strokes, varied", ...WRITE2 },
|
|
4226
|
-
handler: (a) =>
|
|
4406
|
+
handler: (a) => {
|
|
4407
|
+
const replay = a;
|
|
4408
|
+
return act({ kind: "replay", replay }, () => c.replayStrokes(replay));
|
|
4409
|
+
}
|
|
4227
4410
|
});
|
|
4228
4411
|
add({
|
|
4229
4412
|
name: "set_view",
|
|
@@ -4675,10 +4858,12 @@ export {
|
|
|
4675
4858
|
PAPER_NODE_ID,
|
|
4676
4859
|
PAPER_SLIDERS,
|
|
4677
4860
|
PaintCanvasPresenter,
|
|
4861
|
+
PaintDirector,
|
|
4678
4862
|
PaintDocumentError,
|
|
4679
4863
|
PaintEditorController,
|
|
4680
4864
|
PaintEditorError,
|
|
4681
4865
|
PaintGesture,
|
|
4866
|
+
PaintPresence,
|
|
4682
4867
|
PaintStrokeSession,
|
|
4683
4868
|
PaperGrain,
|
|
4684
4869
|
PenDabWalker,
|
|
@@ -4762,6 +4947,9 @@ export {
|
|
|
4762
4947
|
serializePaintDocumentExternal,
|
|
4763
4948
|
standardBlendMode,
|
|
4764
4949
|
strokeBounds,
|
|
4950
|
+
strokeDuration,
|
|
4951
|
+
strokeSchedule,
|
|
4952
|
+
sweepPath,
|
|
4765
4953
|
symmetryAxisAngles,
|
|
4766
4954
|
symmetryAxisSegments,
|
|
4767
4955
|
symmetryCopies,
|