@overtone-art/canvas-editor-core 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +339 -25
- package/dist/index.d.ts +339 -25
- package/dist/index.global.js +53 -53
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +1053 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1034 -92
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/{types-BNzE_X5M.d.mts → types-JP8MZsIs.d.mts} +42 -1
- package/dist/{types-BNzE_X5M.d.ts → types-JP8MZsIs.d.ts} +42 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Canvas, FabricObject, ImageFormat } from 'fabric';
|
|
2
|
-
import { b as EditorEvents,
|
|
3
|
-
export { D as DEFAULT_PATTERN_CONFIG, d as ExportFormat, f as ImageAttribution,
|
|
1
|
+
import { Canvas, FabricObject, Point, ImageFormat, Group } from 'fabric';
|
|
2
|
+
import { b as EditorEvents, o as LayerType, m as LayerMeta, L as LayerData, X as SerializedLayer, P as PatternConfig, K as PatternLocks, a1 as TextCurveConfig, t as MaskPresetId, Y as ShapeMaskPresetId, a2 as TextureMaskPresetId, a4 as Unit, J as MockupPrintArea, z as MockupConfig, e as FontDefinition, p as LicenseConfig, r as LicenseStatus, T as ProjectState, M as MaskBrushOptions, s as MaskPoint, v as MaskRefinementProvider, u as MaskRefinementPrompt, x as MaskRefinementResult, k as LayerMaskEntry, l as LayerMaskMode, E as EditorConfig, Z as ShapePlugin, $ as TemplateDefinition, I as ImageAdjustments, c as EditorState, V as SemanticExportOptions, _ as SvgExportOptions, R as PrintifyPositioning, N as NormalizedLayerPosition, Q as PositioningAdapter, h as ImageProviderResult, i as ImageSearchOptions, j as ImageSearchResult, F as FileAdapter, g as ImageProvider, W as SerializedBackgroundImageOptions, B as BackgroundImageOptions, U as ResizeOptions, a as DpiIssue, n as LayerShadowConfig, C as CanvasSizePreset, A as MockupDisplacement } from './types-JP8MZsIs.mjs';
|
|
3
|
+
export { D as DEFAULT_PATTERN_CONFIG, d as ExportFormat, f as ImageAttribution, q as LicensePayload, w as MaskRefinementRequest, y as MockupBlendMode, G as MockupDisplacementChannel, H as MockupOverlay, O as PatternState, S as ProjectPage, a0 as TemplateParameter, a3 as TileMode } from './types-JP8MZsIs.mjs';
|
|
4
4
|
|
|
5
5
|
type EventHandler<T> = (data: T) => void;
|
|
6
6
|
declare class EventEmitter<TEvents extends {} = Record<string, unknown>> {
|
|
@@ -210,6 +210,7 @@ declare class PatternManager {
|
|
|
210
210
|
private history;
|
|
211
211
|
private events;
|
|
212
212
|
private proxies;
|
|
213
|
+
private readonly onObjectModified;
|
|
213
214
|
private readonly onSourceModified;
|
|
214
215
|
private readonly onLayerRemoved;
|
|
215
216
|
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
@@ -234,6 +235,14 @@ declare class PatternManager {
|
|
|
234
235
|
/** Release every proxy and the offscreen snapshot it holds. */
|
|
235
236
|
private clearProxies;
|
|
236
237
|
private attach;
|
|
238
|
+
/**
|
|
239
|
+
* Fold a finished drag / scale / rotate on the proxy back into the pattern:
|
|
240
|
+
* position becomes the grid origin (carried by the source), scale becomes the
|
|
241
|
+
* tile scale, rotation becomes the pattern angle. Read the live transform
|
|
242
|
+
* first — writing the config re-fits the box and destroys it.
|
|
243
|
+
*/
|
|
244
|
+
private commitGesture;
|
|
245
|
+
private area;
|
|
237
246
|
private detach;
|
|
238
247
|
private invalidateFor;
|
|
239
248
|
}
|
|
@@ -244,38 +253,69 @@ declare class PatternManager {
|
|
|
244
253
|
*/
|
|
245
254
|
declare function restoreLocks(obj: FabricObject, locks: PatternLocks | undefined): void;
|
|
246
255
|
|
|
256
|
+
interface PatternArea {
|
|
257
|
+
width: number;
|
|
258
|
+
height: number;
|
|
259
|
+
}
|
|
247
260
|
/**
|
|
248
261
|
* Renders a layer's source object repeated across the print area.
|
|
249
262
|
*
|
|
250
263
|
* This is a *render proxy*, not a layer: it is attached to the layer that owns
|
|
251
264
|
* the source (see `LayerManager.setRenderProxy`) and never serialized. The
|
|
252
265
|
* document keeps the real object — a `Textbox` stays a `Textbox` — so tiling is
|
|
253
|
-
* non-destructive and every source edit
|
|
266
|
+
* non-destructive and every source edit shows up on the next render.
|
|
254
267
|
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
268
|
+
* **Its box is one tile, its drawing is the whole area.** The object's own
|
|
269
|
+
* width/height/angle/position track the tile drawn at the grid origin (the
|
|
270
|
+
* "anchor" tile), so the selection frame the user grabs sits exactly on a tile
|
|
271
|
+
* they can see, while `_render` paints the full print area outside those bounds.
|
|
272
|
+
* That also makes the transform handles meaningful: dragging moves the grid,
|
|
273
|
+
* scaling is the tile scale, rotating is the pattern angle. The live transform
|
|
274
|
+
* is the truth during a gesture; `PatternManager` folds it back into the config
|
|
275
|
+
* when the gesture ends.
|
|
259
276
|
*/
|
|
260
277
|
declare class TiledPatternObject extends FabricObject {
|
|
261
278
|
static type: string;
|
|
262
279
|
/** The layer's real object. Never rendered directly (it is kept at opacity 0). */
|
|
263
280
|
source: FabricObject;
|
|
264
281
|
config: PatternConfig;
|
|
282
|
+
/** The print area this pattern fills, in canvas units. */
|
|
283
|
+
area: PatternArea;
|
|
265
284
|
private snapshotEl;
|
|
266
285
|
private snapshotScale;
|
|
267
|
-
constructor(source: FabricObject, config: PatternConfig,
|
|
268
|
-
/** Swap in a new config
|
|
286
|
+
constructor(source: FabricObject, config: PatternConfig, area: PatternArea);
|
|
287
|
+
/** Swap in a new config and re-fit the box to the tile it now describes. */
|
|
269
288
|
setConfig(config: PatternConfig): void;
|
|
270
|
-
/**
|
|
271
|
-
setArea(
|
|
272
|
-
/** Drop the cached source snapshot (
|
|
289
|
+
/** Re-fit to a new print area (canvas resize). */
|
|
290
|
+
setArea(area: PatternArea): void;
|
|
291
|
+
/** Drop the cached source snapshot (the source was edited). */
|
|
273
292
|
invalidate(): void;
|
|
274
293
|
/** Free the offscreen snapshot. */
|
|
275
294
|
dispose(): void;
|
|
295
|
+
/**
|
|
296
|
+
* Put the box back on the anchor tile: the tile's size, the pattern angle, and
|
|
297
|
+
* the grid origin displaced by the configured phase shift. Resets any live
|
|
298
|
+
* gesture scale, so it must run only once that gesture has been folded in.
|
|
299
|
+
*/
|
|
300
|
+
syncBox(): void;
|
|
301
|
+
/** Grid rotation in play right now — the live handle during a rotate gesture. */
|
|
302
|
+
liveAngle(): number;
|
|
303
|
+
/** Tile scale in play right now, as a config percentage. */
|
|
304
|
+
liveScale(): number;
|
|
305
|
+
/**
|
|
306
|
+
* Where the source's centre would have to sit for the box to stay put — i.e.
|
|
307
|
+
* the grid origin implied by a drag. `PatternManager` moves the source there.
|
|
308
|
+
*/
|
|
309
|
+
liveOrigin(): Point;
|
|
276
310
|
_render(ctx: CanvasRenderingContext2D): void;
|
|
277
311
|
/** Raster fallback for SVG export — one `<image>` covering the print area. */
|
|
278
312
|
_toSVG(): string[];
|
|
313
|
+
/**
|
|
314
|
+
* The proxy holds a live reference to its source, which would make a
|
|
315
|
+
* serialized canvas circular. Nothing persists this object (only layers are
|
|
316
|
+
* serialized) — this keeps an accidental `canvas.toObject()` from throwing.
|
|
317
|
+
*/
|
|
318
|
+
toObject(): Record<string, unknown>;
|
|
279
319
|
/**
|
|
280
320
|
* Fabric's generic clone round-trips through `toObject()` + the class
|
|
281
321
|
* registry, which cannot carry a live source reference. Export paths clone
|
|
@@ -284,18 +324,43 @@ declare class TiledPatternObject extends FabricObject {
|
|
|
284
324
|
*/
|
|
285
325
|
clone(): Promise<this>;
|
|
286
326
|
/**
|
|
287
|
-
* The
|
|
288
|
-
*
|
|
289
|
-
*
|
|
327
|
+
* The source's tile footprint: its bounding box, minus a stroke it reserves
|
|
328
|
+
* room for but never paints.
|
|
329
|
+
*
|
|
330
|
+
* fabric keeps `strokeWidth` inside an object's box whether or not a `stroke`
|
|
331
|
+
* colour paints it, and the built-in shapes arrive with `strokeWidth: 1` and no
|
|
332
|
+
* stroke. Stepping the grid by that box puts a transparent seam between every
|
|
333
|
+
* pair of neighbours at zero spacing: the artwork is a pixel narrower than the
|
|
334
|
+
* box it is stepped by.
|
|
290
335
|
*/
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
private
|
|
294
|
-
/**
|
|
295
|
-
private
|
|
336
|
+
private sourceBox;
|
|
337
|
+
/** The source's on-canvas width, before the tile scale. */
|
|
338
|
+
private baseW;
|
|
339
|
+
/** The source's on-canvas height, before the tile scale. */
|
|
340
|
+
private baseH;
|
|
341
|
+
/**
|
|
342
|
+
* Size to paint the snapshot at, for a tile of `tileW × tileH`.
|
|
343
|
+
*
|
|
344
|
+
* The snapshot is NOT exactly the source's box: `toCanvasElement` rounds the
|
|
345
|
+
* raster up to whole pixels and pads it further for a shadow. Painting it into
|
|
346
|
+
* the tile step would squeeze the artwork inside that padding — every tile
|
|
347
|
+
* shrinks by up to a pixel and the grid shows transparent seams at zero
|
|
348
|
+
* spacing. So the bitmap is painted at its own footprint, scaled by the same
|
|
349
|
+
* factor the tile is, and the step stays the source's box.
|
|
350
|
+
*/
|
|
351
|
+
private drawSize;
|
|
352
|
+
/** Tile size from the config alone, ignoring any in-flight gesture. */
|
|
353
|
+
private baseTile;
|
|
354
|
+
/** Tile size as drawn right now, including a live scale gesture. */
|
|
355
|
+
private liveTile;
|
|
356
|
+
/** Smallest tile the draw loop may use, so a tiny tile can't flood the area. */
|
|
357
|
+
private tileFloor;
|
|
358
|
+
/** Phase shift (`offsetX`/`offsetY`) as a canvas-space vector. */
|
|
359
|
+
private shiftVector;
|
|
360
|
+
private anchorFromOrigin;
|
|
296
361
|
/**
|
|
297
|
-
* Snapshot the source at (at least) `scale`, reusing the cached one
|
|
298
|
-
* still sharp enough and the source has not changed.
|
|
362
|
+
* Snapshot the source at (at least) `scale`, reusing the cached one while it
|
|
363
|
+
* is still sharp enough and the source has not changed.
|
|
299
364
|
*/
|
|
300
365
|
private ensureSnapshot;
|
|
301
366
|
/** Bound the snapshot by both a linear scale and a total pixel budget. */
|
|
@@ -315,6 +380,18 @@ interface PatternOrigin {
|
|
|
315
380
|
x: number;
|
|
316
381
|
y: number;
|
|
317
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Size the tile bitmap is painted at, when that differs from the grid step.
|
|
385
|
+
*
|
|
386
|
+
* A snapshot of the source is not always exactly the source's box: the raster is
|
|
387
|
+
* allocated in whole pixels, and a shadow pads it further. Painting such a bitmap
|
|
388
|
+
* into the step would shrink the artwork inside its own transparent margin and
|
|
389
|
+
* open a hairline gap between neighbours at zero spacing.
|
|
390
|
+
*/
|
|
391
|
+
interface TileDrawSize {
|
|
392
|
+
width: number;
|
|
393
|
+
height: number;
|
|
394
|
+
}
|
|
318
395
|
/**
|
|
319
396
|
* Pure tile geometry: where each tile centre lands and how much it is rotated,
|
|
320
397
|
* for a config + target/base size. Covers every corner of the target from the
|
|
@@ -328,8 +405,12 @@ declare function computeTilePositions(config: PatternConfig, targetW: number, ta
|
|
|
328
405
|
* Draw the tiled pattern onto a 2D context, in target coordinates (0,0 = the
|
|
329
406
|
* target's top-left corner). The geometry lives in {@link computeTilePositions};
|
|
330
407
|
* this just plays it out as canvas calls.
|
|
408
|
+
*
|
|
409
|
+
* `baseW`/`baseH` are the grid STEP. `draw` is the size the bitmap is painted at
|
|
410
|
+
* and defaults to the step — pass it when the bitmap carries padding the step
|
|
411
|
+
* does not (see {@link TileDrawSize}), so the artwork still lands step-sized.
|
|
331
412
|
*/
|
|
332
|
-
declare function drawTiles(ctx: CanvasRenderingProtocol, img: CanvasImageSource, config: PatternConfig, targetW: number, targetH: number, baseW: number, baseH: number, origin?: PatternOrigin): void;
|
|
413
|
+
declare function drawTiles(ctx: CanvasRenderingProtocol, img: CanvasImageSource, config: PatternConfig, targetW: number, targetH: number, baseW: number, baseH: number, origin?: PatternOrigin, draw?: TileDrawSize): void;
|
|
333
414
|
/** Minimal 2D-context surface used by {@link drawTiles}; lets tests inject a spy. */
|
|
334
415
|
interface CanvasRenderingProtocol {
|
|
335
416
|
save(): void;
|
|
@@ -624,6 +705,237 @@ declare class MaskController {
|
|
|
624
705
|
private assertActive;
|
|
625
706
|
}
|
|
626
707
|
|
|
708
|
+
interface MaskEditTarget {
|
|
709
|
+
target: string;
|
|
710
|
+
maskId: string;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
interface MaskBox {
|
|
714
|
+
left: number;
|
|
715
|
+
top: number;
|
|
716
|
+
width: number;
|
|
717
|
+
height: number;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/** Target id for the mask stack that clips the whole design rather than a layer. */
|
|
721
|
+
declare const CANVAS_MASK_TARGET = "canvas";
|
|
722
|
+
/**
|
|
723
|
+
* Storage half of the mask stacks: where a stack lives, how it is read back out
|
|
724
|
+
* of the composed clip, and how a new one is installed. `LayerMaskManager` adds
|
|
725
|
+
* the editing operations on top.
|
|
726
|
+
*
|
|
727
|
+
* Two things are persisted, and each has a job:
|
|
728
|
+
*
|
|
729
|
+
* - the composed `clipPath` on the host's fabric object, which is what actually
|
|
730
|
+
* renders — in the browser, in an export, and in a server-side replay that
|
|
731
|
+
* knows nothing about this class;
|
|
732
|
+
* - `layer.meta.maskStack`, the per-entry list (name, mode, link, visibility)
|
|
733
|
+
* that the UI edits.
|
|
734
|
+
*
|
|
735
|
+
* Geometry is NOT duplicated into the meta: the group's children are the single
|
|
736
|
+
* source of truth for it, unwrapped and recomposed on every mutation, so the two
|
|
737
|
+
* can never drift into disagreeing about where a mask sits. The order of
|
|
738
|
+
* `entries` matches the order of the group's children, minus the implicit base
|
|
739
|
+
* rect a stack that opens with subtract/intersect needs.
|
|
740
|
+
*/
|
|
741
|
+
declare abstract class MaskStackStore {
|
|
742
|
+
protected canvas: Canvas;
|
|
743
|
+
protected layers: LayerManager;
|
|
744
|
+
protected history: HistoryManager;
|
|
745
|
+
protected events: EventEmitter<EditorEvents>;
|
|
746
|
+
protected selected: {
|
|
747
|
+
target: string;
|
|
748
|
+
maskId: string;
|
|
749
|
+
} | null;
|
|
750
|
+
private pinning;
|
|
751
|
+
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
752
|
+
list(target: string): LayerMaskEntry[];
|
|
753
|
+
get(target: string, maskId: string): LayerMaskEntry | undefined;
|
|
754
|
+
/** Every target that currently carries at least one mask. */
|
|
755
|
+
targets(): string[];
|
|
756
|
+
/** The box a mask is fitted to, in the space the stack is composed in. */
|
|
757
|
+
hostBox(target: string, absolute?: boolean): MaskBox;
|
|
758
|
+
/** The host layer of a target, optionally creating the design overlay. */
|
|
759
|
+
protected hostLayer(target: string, create?: boolean): Layer | undefined;
|
|
760
|
+
protected host(target: string, create?: boolean): FabricObject | null;
|
|
761
|
+
/** Re-pin the design overlay, guarding the reorder that re-triggers this. */
|
|
762
|
+
protected pin(): void;
|
|
763
|
+
/**
|
|
764
|
+
* Take the current geometry back out of the composed clip, entry-aligned.
|
|
765
|
+
*
|
|
766
|
+
* The entry list is the authority on how to read the clip: with no entries the
|
|
767
|
+
* clip predates the stack (a mask preset, or a single `clipPath` an older host
|
|
768
|
+
* installed) and is one mask whole — including when it happens to be a group,
|
|
769
|
+
* which is why this cannot just unwrap anything group-shaped.
|
|
770
|
+
*/
|
|
771
|
+
protected unwrap(target: string, host: FabricObject): FabricObject[];
|
|
772
|
+
/**
|
|
773
|
+
* Entries for a stack, adopting a pre-stack clip as the first one. Without
|
|
774
|
+
* this, the first `add()` on an already-masked layer would compose a clip it
|
|
775
|
+
* has no entry for and silently throw that mask away.
|
|
776
|
+
*/
|
|
777
|
+
protected entriesFor(target: string, sources: FabricObject[]): LayerMaskEntry[];
|
|
778
|
+
/**
|
|
779
|
+
* Install a stack: convert geometry into the space the stack needs, compose the
|
|
780
|
+
* clip, store the entries, and commit one history checkpoint for the lot.
|
|
781
|
+
*/
|
|
782
|
+
protected commit(target: string, host: FabricObject, entries: LayerMaskEntry[], sources: FabricObject[], save?: boolean,
|
|
783
|
+
/** Compose in canvas space regardless of the entries — see `beginEdit`. */
|
|
784
|
+
forceAbsolute?: boolean): void;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
interface AddMaskOptions {
|
|
788
|
+
name?: string;
|
|
789
|
+
mode?: LayerMaskMode;
|
|
790
|
+
linked?: boolean;
|
|
791
|
+
/** Host data describing where the geometry came from (preset id, generator…). */
|
|
792
|
+
meta?: Record<string, unknown>;
|
|
793
|
+
/** Scale the geometry to the host's box (a number zooms it); default 1. */
|
|
794
|
+
fit?: number | false;
|
|
795
|
+
/**
|
|
796
|
+
* Fit to this box instead of the host's own, in the stack's coordinate space.
|
|
797
|
+
* The whole-design overlay spans the canvas, but a mask on it usually wants to
|
|
798
|
+
* frame the artwork, which occupies part of it.
|
|
799
|
+
*/
|
|
800
|
+
box?: {
|
|
801
|
+
left: number;
|
|
802
|
+
top: number;
|
|
803
|
+
width: number;
|
|
804
|
+
height: number;
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Stacked, boolean-composed masks — one ordered list per host, where a host is
|
|
809
|
+
* either a layer or the design as a whole (`CANVAS_MASK_TARGET`). Storage and
|
|
810
|
+
* clip composition live in `MaskStackStore`; this class is what a UI drives.
|
|
811
|
+
*/
|
|
812
|
+
declare class LayerMaskManager extends MaskStackStore {
|
|
813
|
+
private readonly edits;
|
|
814
|
+
private readonly onLayersChanged;
|
|
815
|
+
private readonly onLayerSelected;
|
|
816
|
+
private readonly onObjectModified;
|
|
817
|
+
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
818
|
+
dispose(): void;
|
|
819
|
+
/** The mask currently being dragged on the canvas, if any. */
|
|
820
|
+
editing(): MaskEditTarget | null;
|
|
821
|
+
/**
|
|
822
|
+
* Put drag handles on one mask. The stack is composed in canvas space for the
|
|
823
|
+
* duration — a linked mask would otherwise sit in the host's space, where the
|
|
824
|
+
* handle's own canvas coordinates mean something else entirely. `endEdit`
|
|
825
|
+
* returns it to whichever space its entries call for.
|
|
826
|
+
*/
|
|
827
|
+
beginEdit(target: string, maskId: string): Promise<boolean>;
|
|
828
|
+
/** Take the handles down and settle the stack back into its own space. */
|
|
829
|
+
endEdit(save?: boolean): void;
|
|
830
|
+
getSelected(): {
|
|
831
|
+
target: string;
|
|
832
|
+
maskId: string;
|
|
833
|
+
} | null;
|
|
834
|
+
select(target: string | null, maskId: string | null): void;
|
|
835
|
+
add(target: string, object: FabricObject, options?: AddMaskOptions): LayerMaskEntry | null;
|
|
836
|
+
/** Swap one mask's geometry, keeping its identity, mode and position in the stack. */
|
|
837
|
+
replaceGeometry(target: string, maskId: string, object: FabricObject, options?: AddMaskOptions): boolean;
|
|
838
|
+
/**
|
|
839
|
+
* Re-fit one mask to its host's box (or `box`) at `fit` scale, keeping the
|
|
840
|
+
* geometry it already has. This is what a zoom control drives: re-picking the
|
|
841
|
+
* mask would cost another render of a generated alpha map just to resize it.
|
|
842
|
+
*/
|
|
843
|
+
refit(target: string, maskId: string, options?: {
|
|
844
|
+
fit?: number;
|
|
845
|
+
box?: MaskBox;
|
|
846
|
+
save?: boolean;
|
|
847
|
+
}): boolean;
|
|
848
|
+
remove(target: string, maskId: string): boolean;
|
|
849
|
+
clear(target: string): boolean;
|
|
850
|
+
reorder(target: string, maskId: string, index: number): boolean;
|
|
851
|
+
/** Replace a mask's host metadata (which preset or generator produced it). */
|
|
852
|
+
setMeta(target: string, maskId: string, meta: Record<string, unknown>): boolean;
|
|
853
|
+
setMode(target: string, maskId: string, mode: LayerMaskMode): boolean;
|
|
854
|
+
setVisible(target: string, maskId: string, visible: boolean): boolean;
|
|
855
|
+
setOpacity(target: string, maskId: string, opacity: number): boolean;
|
|
856
|
+
setName(target: string, maskId: string, name: string): boolean;
|
|
857
|
+
/**
|
|
858
|
+
* Link or unlink one mask. Unlinking pins it where it currently appears;
|
|
859
|
+
* re-linking records its position relative to the host so later host moves
|
|
860
|
+
* carry it along.
|
|
861
|
+
*/
|
|
862
|
+
setLinked(target: string, maskId: string, linked: boolean): boolean;
|
|
863
|
+
/**
|
|
864
|
+
* Consume a layer, turning its artwork into a mask. Without an explicit target
|
|
865
|
+
* it masks the layer directly beneath it, and the bottom layer masks the whole
|
|
866
|
+
* design — there is nothing under it to clip.
|
|
867
|
+
*/
|
|
868
|
+
convertLayer(layerId: string, target?: string): {
|
|
869
|
+
target: string;
|
|
870
|
+
entry: LayerMaskEntry;
|
|
871
|
+
} | null;
|
|
872
|
+
/** Recompose one stack's clip from the geometry it already holds. */
|
|
873
|
+
rebuild(target: string, save?: boolean): void;
|
|
874
|
+
/** Re-derive linked masks after the host moved (canvas-space stacks only). */
|
|
875
|
+
private reflow;
|
|
876
|
+
/**
|
|
877
|
+
* Adopt a clip this manager did not install — a host's own single `clipPath` —
|
|
878
|
+
* as a one-entry stack, so it shows up in the UI as a mask row before anything
|
|
879
|
+
* is added to it. A mask preset is left alone unless asked for by name: it is
|
|
880
|
+
* still owned by `MaskPresetManager` until a stack operation takes it over.
|
|
881
|
+
*/
|
|
882
|
+
adopt(target: string, name?: string): LayerMaskEntry | null;
|
|
883
|
+
/** After a state restore: re-pin the design overlay and recompose every stack. */
|
|
884
|
+
refreshAll(): void;
|
|
885
|
+
private patch;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
interface ComposeOptions {
|
|
889
|
+
/** Host box in the coordinate space the children use, for the implicit base. */
|
|
890
|
+
box: {
|
|
891
|
+
left: number;
|
|
892
|
+
top: number;
|
|
893
|
+
width: number;
|
|
894
|
+
height: number;
|
|
895
|
+
};
|
|
896
|
+
/**
|
|
897
|
+
* Canvas-space children (an unlinked mask is pinned to the canvas, so the
|
|
898
|
+
* whole group has to leave the host's local space with it).
|
|
899
|
+
*/
|
|
900
|
+
absolute: boolean;
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Build the `clipPath` for one mask stack: one child per entry, in order, each
|
|
904
|
+
* carrying its mode's compositing operation.
|
|
905
|
+
*
|
|
906
|
+
* `children` are consumed — a Group takes ownership of what it is given and
|
|
907
|
+
* rewrites the coordinates, so callers pass clones of their sources rather than
|
|
908
|
+
* the sources themselves.
|
|
909
|
+
*/
|
|
910
|
+
declare function composeMaskGroup(children: FabricObject[], entries: LayerMaskEntry[], options: ComposeOptions): Group | undefined;
|
|
911
|
+
/** True when the stack has to be composed in canvas space rather than host space. */
|
|
912
|
+
declare function needsAbsoluteSpace(entries: LayerMaskEntry[]): boolean;
|
|
913
|
+
|
|
914
|
+
/** Host-space geometry → canvas-space, for the same on-screen result. */
|
|
915
|
+
declare function toCanvasSpace(object: FabricObject, host: FabricObject): void;
|
|
916
|
+
/** Canvas-space geometry → host-space, for the same on-screen result. */
|
|
917
|
+
declare function toHostSpace(object: FabricObject, host: FabricObject): void;
|
|
918
|
+
/** Scale an object so its unrotated box covers `box`, centred on it. */
|
|
919
|
+
declare function fitToBox(object: FabricObject, box: {
|
|
920
|
+
left: number;
|
|
921
|
+
top: number;
|
|
922
|
+
width: number;
|
|
923
|
+
height: number;
|
|
924
|
+
}, zoom?: number): void;
|
|
925
|
+
/**
|
|
926
|
+
* Pull a composed clip group back apart into standalone objects in the space the
|
|
927
|
+
* group itself was in.
|
|
928
|
+
*
|
|
929
|
+
* `removeAll` already restores each child's own transform on the way out — the
|
|
930
|
+
* group rebases children when it takes them in, and reverses that when it lets
|
|
931
|
+
* them go. Folding the group's matrix back in on top (as one would with a v5-era
|
|
932
|
+
* group) double-counts it, which stays invisible while a mask sits at the origin
|
|
933
|
+
* and moves it twice as far as it should the moment one does not.
|
|
934
|
+
*
|
|
935
|
+
* The group passed in is emptied.
|
|
936
|
+
*/
|
|
937
|
+
declare function unwrapGroup(group: Group): FabricObject[];
|
|
938
|
+
|
|
627
939
|
declare class CanvasEditor {
|
|
628
940
|
readonly canvas: Canvas;
|
|
629
941
|
readonly layers: LayerManager;
|
|
@@ -635,6 +947,8 @@ declare class CanvasEditor {
|
|
|
635
947
|
readonly patterns: PatternManager;
|
|
636
948
|
readonly curves: TextCurveManager;
|
|
637
949
|
readonly maskPresets: MaskPresetManager;
|
|
950
|
+
/** Stacked boolean masks, per layer and for the design as a whole. */
|
|
951
|
+
readonly layerMasks: LayerMaskManager;
|
|
638
952
|
readonly fonts: FontRegistry;
|
|
639
953
|
readonly licensing: LicenseManager;
|
|
640
954
|
readonly pages: ProjectManager;
|
|
@@ -901,4 +1215,4 @@ declare class AnnotationOverlay {
|
|
|
901
1215
|
*/
|
|
902
1216
|
declare function displaceRgba(source: Uint8ClampedArray, map: Uint8ClampedArray, width: number, height: number, options: Omit<MockupDisplacement, 'image'>): Uint8ClampedArray;
|
|
903
1217
|
|
|
904
|
-
export { AnnotationOverlay, type AnnotationPrimitive, BackgroundImageOptions, CANVAS_SIZE_PRESETS, CanvasEditor, type CanvasRenderingProtocol, CanvasSizePreset, type CoverPlacement, CropController, DEFAULT_LAYER_SHADOW, DEFAULT_SELECTION_STYLE, DEFAULT_TEXT_CURVE, DpiIssue, EditorConfig, EditorEvents, EditorState, EventEmitter, FileAdapter, FontDefinition, FontRegistry, HistoryManager, ImageAdjustments, ImageProvider, ImageProviderResult, ImageSearchOptions, ImageSearchResult, Layer, LayerData, LayerManager, LayerMeta, LayerShadowConfig, LayerType, LicenseConfig, LicenseManager, LicenseStatus, MaskBrushOptions, MaskController, type MaskPerformanceSample, MaskPoint, MaskPresetId, MaskPresetManager, MaskRefinementError, type MaskRefinementErrorCode, MaskRefinementPrompt, MaskRefinementProvider, MaskRefinementResult, MockupConfig, MockupDisplacement, MockupPrintArea, NormalizedLayerPosition, PatternConfig, PatternLocks, PatternManager, type PatternOrigin, type PngExportOptions, PositioningAdapter, PrintifyPositioning, ProjectManager, ProjectState, ResizeOptions, SHAPE_MASK_BOX, SHAPE_MASK_IDS, type SelectionStyle, SemanticExportOptions, SerializedBackgroundImageOptions, SerializedLayer, ShapeMaskPresetId, ShapePlugin, SnapManager, SvgExportOptions, TEXTURE_MASK_IDS, TEXTURE_MASK_SIZE, TemplateDefinition, TextCurveConfig, TextCurveManager, TextureMaskPresetId, type TilePlacement, TiledPatternObject, Unit, UnitConverter, type ViewportTransform, applyAspectLock, applyLayerShadow, applyObjectSelectionStyle, applySelectionStyle, buildCurvePathData, clamp, clearTextureMaskCache, computeCoverPlacement, computePrintAreaClip, computeTilePositions, deserializeEditor, displaceRgba, drawTiles, escapeXml, exportDataURL, exportMockup, exportPNG, exportPrintArea, exportSVG, generateId, isCssColor, isMaskPresetId, isShapeMaskId, isTextureMaskId, readLayerShadow, renderTextureMask, resetTransform, restoreLocks, round2, sanitizeSvg, serializeEditor, shapeMaskPathData };
|
|
1218
|
+
export { type AddMaskOptions, AnnotationOverlay, type AnnotationPrimitive, BackgroundImageOptions, CANVAS_MASK_TARGET, CANVAS_SIZE_PRESETS, CanvasEditor, type CanvasRenderingProtocol, CanvasSizePreset, type CoverPlacement, CropController, DEFAULT_LAYER_SHADOW, DEFAULT_SELECTION_STYLE, DEFAULT_TEXT_CURVE, DpiIssue, EditorConfig, EditorEvents, EditorState, EventEmitter, FileAdapter, FontDefinition, FontRegistry, HistoryManager, ImageAdjustments, ImageProvider, ImageProviderResult, ImageSearchOptions, ImageSearchResult, Layer, LayerData, LayerManager, LayerMaskEntry, LayerMaskManager, LayerMaskMode, LayerMeta, LayerShadowConfig, LayerType, LicenseConfig, LicenseManager, LicenseStatus, MaskBrushOptions, MaskController, type MaskPerformanceSample, MaskPoint, MaskPresetId, MaskPresetManager, MaskRefinementError, type MaskRefinementErrorCode, MaskRefinementPrompt, MaskRefinementProvider, MaskRefinementResult, MockupConfig, MockupDisplacement, MockupPrintArea, NormalizedLayerPosition, PatternConfig, PatternLocks, PatternManager, type PatternOrigin, type PngExportOptions, PositioningAdapter, PrintifyPositioning, ProjectManager, ProjectState, ResizeOptions, SHAPE_MASK_BOX, SHAPE_MASK_IDS, type SelectionStyle, SemanticExportOptions, SerializedBackgroundImageOptions, SerializedLayer, ShapeMaskPresetId, ShapePlugin, SnapManager, SvgExportOptions, TEXTURE_MASK_IDS, TEXTURE_MASK_SIZE, TemplateDefinition, TextCurveConfig, TextCurveManager, TextureMaskPresetId, type TileDrawSize, type TilePlacement, TiledPatternObject, Unit, UnitConverter, type ViewportTransform, applyAspectLock, applyLayerShadow, applyObjectSelectionStyle, applySelectionStyle, buildCurvePathData, clamp, clearTextureMaskCache, composeMaskGroup, computeCoverPlacement, computePrintAreaClip, computeTilePositions, deserializeEditor, displaceRgba, drawTiles, escapeXml, exportDataURL, exportMockup, exportPNG, exportPrintArea, exportSVG, fitToBox, generateId, isCssColor, isMaskPresetId, isShapeMaskId, isTextureMaskId, needsAbsoluteSpace, readLayerShadow, renderTextureMask, resetTransform, restoreLocks, round2, sanitizeSvg, serializeEditor, shapeMaskPathData, toCanvasSpace, toHostSpace, unwrapGroup };
|