@overtone-art/canvas-editor-core 0.2.8 → 0.3.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/{chunk-ORZZ6MGQ.mjs → chunk-MCBRZQ4M.mjs} +34 -1
- package/dist/chunk-MCBRZQ4M.mjs.map +1 -0
- package/dist/index.d.mts +184 -4
- package/dist/index.d.ts +184 -4
- package/dist/index.global.js +67 -67
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +742 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +676 -22
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{types-D60CfxL9.d.mts → types-Dh1unrzT.d.mts} +28 -1
- package/dist/{types-D60CfxL9.d.ts → types-Dh1unrzT.d.ts} +28 -1
- package/package.json +6 -4
- package/dist/chunk-ORZZ6MGQ.mjs.map +0 -1
|
@@ -106,6 +106,38 @@ async function exportIsolatedPNG(source, objects, options = {}) {
|
|
|
106
106
|
canvas.dispose();
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
async function exportPrintArea(source, area, options = {}) {
|
|
110
|
+
const { multiplier = 1, format = "png", quality = 1 } = options;
|
|
111
|
+
const width = source.getWidth();
|
|
112
|
+
const height = source.getHeight();
|
|
113
|
+
const clip = computePrintAreaClip(
|
|
114
|
+
area,
|
|
115
|
+
multiplier,
|
|
116
|
+
multiplier,
|
|
117
|
+
width * multiplier,
|
|
118
|
+
height * multiplier
|
|
119
|
+
);
|
|
120
|
+
if (clip.width <= 0 || clip.height <= 0) {
|
|
121
|
+
throw new Error("Print area does not overlap the canvas");
|
|
122
|
+
}
|
|
123
|
+
const element = source.lowerCanvasEl.ownerDocument.createElement("canvas");
|
|
124
|
+
const canvas = new StaticCanvas(element, { width, height });
|
|
125
|
+
try {
|
|
126
|
+
const clones = await Promise.all(source.getObjects().map((object) => object.clone()));
|
|
127
|
+
if (clones.length) canvas.add(...clones);
|
|
128
|
+
canvas.requestRenderAll();
|
|
129
|
+
const rendered = canvas.toCanvasElement(multiplier);
|
|
130
|
+
const output = rendered.ownerDocument.createElement("canvas");
|
|
131
|
+
output.width = Math.max(1, Math.round(clip.width));
|
|
132
|
+
output.height = Math.max(1, Math.round(clip.height));
|
|
133
|
+
const context = output.getContext("2d");
|
|
134
|
+
if (!context) throw new Error("2D canvas context is unavailable");
|
|
135
|
+
context.drawImage(rendered, -clip.left, -clip.top);
|
|
136
|
+
return await canvasElementToBlob(output, format, quality);
|
|
137
|
+
} finally {
|
|
138
|
+
canvas.dispose();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
109
141
|
async function exportMockup(canvas, mockup, options = {}) {
|
|
110
142
|
const { multiplier = 1, format = "png", quality = 1 } = options;
|
|
111
143
|
const design = canvas.toCanvasElement(multiplier);
|
|
@@ -221,8 +253,9 @@ export {
|
|
|
221
253
|
computeCoverPlacement,
|
|
222
254
|
exportPNG,
|
|
223
255
|
exportIsolatedPNG,
|
|
256
|
+
exportPrintArea,
|
|
224
257
|
exportMockup,
|
|
225
258
|
exportSVG,
|
|
226
259
|
exportDataURL
|
|
227
260
|
};
|
|
228
|
-
//# sourceMappingURL=chunk-
|
|
261
|
+
//# sourceMappingURL=chunk-MCBRZQ4M.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/displacement.ts","../src/export.ts"],"sourcesContent":["import type { MockupDisplacement, MockupDisplacementChannel } from './types';\n\nconst CHANNEL_INDEX: Record<MockupDisplacementChannel, number> = {\n red: 0,\n green: 1,\n blue: 2,\n alpha: 3,\n};\n\nfunction finiteScale(value: number | undefined, fallback: number, label: string): number {\n const resolved = value ?? fallback;\n if (!Number.isFinite(resolved)) throw new Error(`${label} must be finite`);\n return resolved;\n}\n\nfunction sample(\n source: Uint8ClampedArray,\n width: number,\n height: number,\n x: number,\n y: number,\n channel: number,\n): number {\n const clampedX = Math.max(0, Math.min(width - 1, x));\n const clampedY = Math.max(0, Math.min(height - 1, y));\n const x0 = Math.floor(clampedX);\n const y0 = Math.floor(clampedY);\n const x1 = Math.min(width - 1, x0 + 1);\n const y1 = Math.min(height - 1, y0 + 1);\n const tx = clampedX - x0;\n const ty = clampedY - y0;\n const top =\n source[(y0 * width + x0) * 4 + channel] * (1 - tx) +\n source[(y0 * width + x1) * 4 + channel] * tx;\n const bottom =\n source[(y1 * width + x0) * 4 + channel] * (1 - tx) +\n source[(y1 * width + x1) * 4 + channel] * tx;\n return top * (1 - ty) + bottom * ty;\n}\n\n/**\n * Warp RGBA pixels with an equally sized channel map. A channel value of 128\n * is neutral; 0 and 255 move by the configured negative/positive maximum.\n */\nexport function displaceRgba(\n source: Uint8ClampedArray,\n map: Uint8ClampedArray,\n width: number,\n height: number,\n options: Omit<MockupDisplacement, 'image'>,\n): Uint8ClampedArray {\n if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) {\n throw new Error('Displacement dimensions must be positive integers');\n }\n const expectedLength = width * height * 4;\n if (source.length !== expectedLength || map.length !== expectedLength) {\n throw new Error('Displacement source and map must match the requested dimensions');\n }\n\n const scaleX = finiteScale(options.scaleX, 10, 'Displacement scaleX');\n const scaleY = finiteScale(options.scaleY, 10, 'Displacement scaleY');\n const channelX = CHANNEL_INDEX[options.channelX ?? 'red'];\n const channelY = CHANNEL_INDEX[options.channelY ?? 'green'];\n const output = new Uint8ClampedArray(expectedLength);\n\n for (let y = 0; y < height; y += 1) {\n for (let x = 0; x < width; x += 1) {\n const offset = (y * width + x) * 4;\n const sourceX = x + ((map[offset + channelX] - 128) / 127) * scaleX;\n const sourceY = y + ((map[offset + channelY] - 128) / 127) * scaleY;\n for (let channel = 0; channel < 4; channel += 1) {\n output[offset + channel] = Math.round(\n sample(source, width, height, sourceX, sourceY, channel),\n );\n }\n }\n }\n return output;\n}\n","import { StaticCanvas } from 'fabric';\nimport type { Canvas, FabricObject, ImageFormat } from 'fabric';\nimport type { MockupConfig, MockupPrintArea } from './types';\nimport { displaceRgba } from './displacement';\n\nexport interface PngExportOptions {\n multiplier?: number;\n format?: ImageFormat;\n quality?: number;\n}\n\nexport interface CoverPlacement {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport function computePrintAreaClip(\n area: MockupPrintArea,\n scaleX: number,\n scaleY: number,\n targetWidth: number,\n targetHeight: number,\n): MockupPrintArea {\n const left = Math.max(0, Math.min(targetWidth, area.left * scaleX));\n const top = Math.max(0, Math.min(targetHeight, area.top * scaleY));\n const right = Math.max(left, Math.min(targetWidth, (area.left + area.width) * scaleX));\n const bottom = Math.max(top, Math.min(targetHeight, (area.top + area.height) * scaleY));\n return { left, top, width: right - left, height: bottom - top };\n}\n\n/** Object-fit: cover geometry, exported for deterministic preview/composite tests. */\nexport function computeCoverPlacement(\n sourceWidth: number,\n sourceHeight: number,\n targetWidth: number,\n targetHeight: number,\n): CoverPlacement {\n if (sourceWidth <= 0 || sourceHeight <= 0 || targetWidth <= 0 || targetHeight <= 0) {\n throw new Error('Cover dimensions must be positive');\n }\n const scale = Math.max(targetWidth / sourceWidth, targetHeight / sourceHeight);\n const width = sourceWidth * scale;\n const height = sourceHeight * scale;\n return {\n left: (targetWidth - width) / 2,\n top: (targetHeight - height) / 2,\n width,\n height,\n };\n}\n\nfunction canvasElementToBlob(\n output: HTMLCanvasElement,\n format: ImageFormat,\n quality: number,\n): Promise<Blob> {\n const mime = format === 'jpeg' ? 'image/jpeg' : `image/${format}`;\n return new Promise<Blob>((resolve, reject) => {\n output.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error(`Failed to export ${format}`))),\n mime,\n quality,\n );\n });\n}\n\nexport async function exportPNG(canvas: Canvas, options: PngExportOptions = {}): Promise<Blob> {\n const { multiplier = 1, format = 'png' as ImageFormat, quality = 1 } = options;\n const output = canvas.toCanvasElement(multiplier);\n return canvasElementToBlob(output, format, quality);\n}\n\n/** Render cloned objects without mutating the live editor canvas. */\nexport async function exportIsolatedPNG(\n source: Canvas,\n objects: FabricObject[],\n options: PngExportOptions & {\n width?: number;\n height?: number;\n backgroundColor?: string;\n backgroundImage?: FabricObject | null;\n cloneObjects?: boolean;\n } = {},\n): Promise<Blob> {\n const element = source.lowerCanvasEl.ownerDocument.createElement('canvas');\n const canvas = new StaticCanvas(element, {\n width: options.width ?? source.getWidth(),\n height: options.height ?? source.getHeight(),\n backgroundColor: options.backgroundColor || undefined,\n });\n try {\n const clones =\n options.cloneObjects === false\n ? objects\n : await Promise.all(objects.map((object) => object.clone()));\n if (clones.length) canvas.add(...clones);\n if (options.backgroundImage) canvas.backgroundImage = await options.backgroundImage.clone();\n canvas.requestRenderAll();\n // Awaited, not returned: `finally` would otherwise dispose the canvas while\n // the export is still reading from it.\n return await exportPNG(canvas as unknown as Canvas, options);\n } finally {\n canvas.dispose();\n }\n}\n\n/**\n * Render just the print-area rectangle, on transparency.\n *\n * This is the file a print provider receives: the design alone, cropped to the\n * printable rectangle, with no garment behind it and no canvas background baked\n * in — so it is rendered from cloned objects rather than off the live canvas.\n */\nexport async function exportPrintArea(\n source: Canvas,\n area: MockupPrintArea,\n options: PngExportOptions = {},\n): Promise<Blob> {\n const { multiplier = 1, format = 'png' as ImageFormat, quality = 1 } = options;\n const width = source.getWidth();\n const height = source.getHeight();\n const clip = computePrintAreaClip(\n area,\n multiplier,\n multiplier,\n width * multiplier,\n height * multiplier,\n );\n if (clip.width <= 0 || clip.height <= 0) {\n throw new Error('Print area does not overlap the canvas');\n }\n\n const element = source.lowerCanvasEl.ownerDocument.createElement('canvas');\n const canvas = new StaticCanvas(element, { width, height });\n try {\n const clones = await Promise.all(source.getObjects().map((object) => object.clone()));\n if (clones.length) canvas.add(...clones);\n canvas.requestRenderAll();\n const rendered = canvas.toCanvasElement(multiplier);\n const output = rendered.ownerDocument.createElement('canvas');\n output.width = Math.max(1, Math.round(clip.width));\n output.height = Math.max(1, Math.round(clip.height));\n const context = output.getContext('2d');\n if (!context) throw new Error('2D canvas context is unavailable');\n context.drawImage(rendered, -clip.left, -clip.top);\n // Awaited, not returned: `finally` would dispose the canvas mid-read.\n return await canvasElementToBlob(output, format, quality);\n } finally {\n canvas.dispose();\n }\n}\n\n/** Rasterize the browser mockup preview together with the transparent design. */\nexport async function exportMockup(\n canvas: Canvas,\n mockup: MockupConfig,\n options: PngExportOptions = {},\n): Promise<Blob> {\n const { multiplier = 1, format = 'png' as ImageFormat, quality = 1 } = options;\n const design = canvas.toCanvasElement(multiplier);\n const output = design.ownerDocument.createElement('canvas');\n output.width = design.width;\n output.height = design.height;\n const context = output.getContext('2d');\n if (!context) throw new Error('2D canvas context is unavailable');\n\n const loadImage = (url: string) =>\n new Promise<HTMLImageElement>((resolve, reject) => {\n const element = new Image();\n element.crossOrigin = 'anonymous';\n element.onload = () => resolve(element);\n element.onerror = () => reject(new Error(`Failed to load mockup image: ${url}`));\n element.src = url;\n });\n const drawCover = (\n image: HTMLImageElement,\n targetContext: CanvasRenderingContext2D = context,\n ) => {\n const placement = computeCoverPlacement(\n image.naturalWidth || image.width,\n image.naturalHeight || image.height,\n output.width,\n output.height,\n );\n targetContext.drawImage(\n image,\n placement.left,\n placement.top,\n placement.width,\n placement.height,\n );\n };\n\n // Full-size scratch buffers, released explicitly in the finally below: a\n // detached canvas element can hold its backing store well past its last\n // reference, and a 4K mockup allocates three of them per export.\n const scratch: HTMLCanvasElement[] = [design];\n try {\n drawCover(await loadImage(mockup.image));\n let compositedDesign: CanvasImageSource = design;\n if (mockup.displacement) {\n const sourceContext = design.getContext('2d');\n if (!sourceContext) throw new Error('2D design context is unavailable');\n const mapCanvas = design.ownerDocument.createElement('canvas');\n scratch.push(mapCanvas);\n mapCanvas.width = design.width;\n mapCanvas.height = design.height;\n const mapContext = mapCanvas.getContext('2d');\n if (!mapContext) throw new Error('2D displacement-map context is unavailable');\n drawCover(await loadImage(mockup.displacement.image), mapContext);\n\n const warped = design.ownerDocument.createElement('canvas');\n scratch.push(warped);\n warped.width = design.width;\n warped.height = design.height;\n const warpedContext = warped.getContext('2d');\n if (!warpedContext) throw new Error('2D displaced-design context is unavailable');\n let sourcePixels: Uint8ClampedArray;\n let mapPixels: Uint8ClampedArray;\n try {\n sourcePixels = sourceContext.getImageData(0, 0, design.width, design.height).data;\n mapPixels = mapContext.getImageData(0, 0, design.width, design.height).data;\n } catch (error) {\n throw new Error('Failed to apply mockup displacement map; verify image CORS access', {\n cause: error,\n });\n }\n const pixels = displaceRgba(sourcePixels, mapPixels, design.width, design.height, {\n ...mockup.displacement,\n scaleX: (mockup.displacement.scaleX ?? 10) * multiplier,\n scaleY: (mockup.displacement.scaleY ?? 10) * multiplier,\n });\n const imageData = warpedContext.createImageData(design.width, design.height);\n imageData.data.set(pixels);\n warpedContext.putImageData(imageData, 0, 0);\n compositedDesign = warped;\n }\n context.save();\n if (mockup.printArea && mockup.clipToPrintArea !== false) {\n const clip = computePrintAreaClip(\n mockup.printArea,\n output.width / canvas.getWidth(),\n output.height / canvas.getHeight(),\n output.width,\n output.height,\n );\n context.beginPath();\n context.rect(clip.left, clip.top, clip.width, clip.height);\n context.clip();\n }\n context.globalAlpha = Math.max(0, Math.min(1, mockup.designOpacity ?? 1));\n context.globalCompositeOperation =\n !mockup.designBlendMode || mockup.designBlendMode === 'normal'\n ? 'source-over'\n : mockup.designBlendMode;\n context.drawImage(compositedDesign, 0, 0);\n context.restore();\n\n if (mockup.overlay) {\n context.save();\n context.globalAlpha = Math.max(0, Math.min(1, mockup.overlay.opacity ?? 1));\n context.globalCompositeOperation =\n mockup.overlay.blendMode === 'normal'\n ? 'source-over'\n : (mockup.overlay.blendMode ?? 'multiply');\n drawCover(await loadImage(mockup.overlay.image));\n context.restore();\n }\n return await canvasElementToBlob(output, format, quality);\n } finally {\n for (const element of scratch) {\n element.width = 0;\n element.height = 0;\n }\n }\n}\n\nexport function exportSVG(canvas: Canvas): string {\n return canvas.toSVG();\n}\n\nexport function exportDataURL(canvas: Canvas, format: ImageFormat = 'png', multiplier = 1): string {\n return canvas.toDataURL({ format, multiplier });\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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,
|
|
2
|
+
import { b as EditorEvents, m as LayerType, k as LayerMeta, L as LayerData, W as SerializedLayer, J as PatternSourceResolver, P as PatternConfig, H as PatternLocks, a0 as TextCurveConfig, r as MaskPresetId, X as ShapeMaskPresetId, a1 as TextureMaskPresetId, a3 as Unit, G as MockupPrintArea, x as MockupConfig, e as FontDefinition, n as LicenseConfig, p as LicenseStatus, S as ProjectState, M as MaskBrushOptions, q as MaskPoint, t as MaskRefinementProvider, s as MaskRefinementPrompt, v as MaskRefinementResult, E as EditorConfig, Y as ShapePlugin, _ as TemplateDefinition, I as ImageAdjustments, c as EditorState, U as SemanticExportOptions, Z as SvgExportOptions, Q as PrintifyPositioning, N as NormalizedLayerPosition, O as PositioningAdapter, h as ImageProviderResult, i as ImageSearchOptions, j as ImageSearchResult, F as FileAdapter, g as ImageProvider, V as SerializedBackgroundImageOptions, B as BackgroundImageOptions, T as ResizeOptions, a as DpiIssue, l as LayerShadowConfig, C as CanvasSizePreset, y as MockupDisplacement } from './types-Dh1unrzT.mjs';
|
|
3
|
+
export { D as DEFAULT_PATTERN_CONFIG, d as ExportFormat, f as ImageAttribution, o as LicensePayload, u as MaskRefinementRequest, w as MockupBlendMode, z as MockupDisplacementChannel, A as MockupOverlay, K as PatternState, R as ProjectPage, $ as TemplateParameter, a2 as TileMode } from './types-Dh1unrzT.mjs';
|
|
4
4
|
|
|
5
5
|
type EventHandler<T> = (data: T) => void;
|
|
6
6
|
declare class EventEmitter<TEvents extends {} = Record<string, unknown>> {
|
|
@@ -47,6 +47,18 @@ declare class LayerManager {
|
|
|
47
47
|
setLocked(id: string, locked: boolean): void;
|
|
48
48
|
setOpacity(id: string, opacity: number): void;
|
|
49
49
|
setName(id: string, name: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Patch a layer's host metadata. A key whose value is `undefined` is removed.
|
|
52
|
+
*
|
|
53
|
+
* `meta` is part of `LayerData` and is serialized, so a host that assigns
|
|
54
|
+
* `layer.meta.x` directly gets neither of the two things every other setter
|
|
55
|
+
* here provides: `layers:changed` (so `useLayers()` keeps returning the old
|
|
56
|
+
* meta) and the history checkpoint (so an undo silently reverts the write —
|
|
57
|
+
* the state IS versioned, it was just never committed at the moment it
|
|
58
|
+
* changed). Going through this method is what makes metadata behave like
|
|
59
|
+
* every other layer property.
|
|
60
|
+
*/
|
|
61
|
+
setMeta(id: string, patch: LayerMeta): void;
|
|
50
62
|
clear(): void;
|
|
51
63
|
count(): number;
|
|
52
64
|
private emitChanged;
|
|
@@ -246,6 +258,107 @@ interface CanvasRenderingProtocol {
|
|
|
246
258
|
drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;
|
|
247
259
|
}
|
|
248
260
|
|
|
261
|
+
/** Straight text — the state every text layer starts in. */
|
|
262
|
+
declare const DEFAULT_TEXT_CURVE: TextCurveConfig;
|
|
263
|
+
interface CurvePath {
|
|
264
|
+
/** SVG path data the text is laid out along. */
|
|
265
|
+
data: string;
|
|
266
|
+
/** Length of that path, used to centre the run on it. */
|
|
267
|
+
length: number;
|
|
268
|
+
}
|
|
269
|
+
/** Path the given curve traces for a text run of `width` px, or null when straight. */
|
|
270
|
+
declare function buildCurvePathData(config: TextCurveConfig, width: number, fontSize: number): CurvePath | null;
|
|
271
|
+
/**
|
|
272
|
+
* Bends a text layer's baseline along a generated path.
|
|
273
|
+
*
|
|
274
|
+
* The curve lives on the fabric object as a real text path, so it survives
|
|
275
|
+
* export and serialization with no extra machinery. The parameters that
|
|
276
|
+
* produced it are kept in `layer.meta.curve` so the UI can show them and so the
|
|
277
|
+
* path can be rebuilt when the text, font or size changes.
|
|
278
|
+
*/
|
|
279
|
+
declare class TextCurveManager {
|
|
280
|
+
private canvas;
|
|
281
|
+
private layers;
|
|
282
|
+
private history;
|
|
283
|
+
private events;
|
|
284
|
+
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
285
|
+
/** Curve parameters for a layer, or null when it is not curved text. */
|
|
286
|
+
get(layerId: string): TextCurveConfig | null;
|
|
287
|
+
isCurved(layerId: string): boolean;
|
|
288
|
+
/** Apply (or update) the curve on a text layer. Zeroed config clears it. */
|
|
289
|
+
apply(layerId: string, config: Partial<TextCurveConfig>, save?: boolean): boolean;
|
|
290
|
+
/** Remove the curve, restoring the authored text box width. */
|
|
291
|
+
clear(layerId: string, save?: boolean): boolean;
|
|
292
|
+
/**
|
|
293
|
+
* Rebuild the path from the stored parameters. Text content, font family and
|
|
294
|
+
* font size all change the run's width, and the path is sized to that width —
|
|
295
|
+
* without this the curve keeps the geometry of the text it was created from.
|
|
296
|
+
*/
|
|
297
|
+
refresh(layerId: string, save?: boolean): boolean;
|
|
298
|
+
/** Rebuild every curved layer — used after a state restore. */
|
|
299
|
+
refreshAll(): void;
|
|
300
|
+
private detach;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
declare function isMaskPresetId(value: unknown): value is MaskPresetId;
|
|
304
|
+
/**
|
|
305
|
+
* Clips a layer to a preset silhouette or soft texture.
|
|
306
|
+
*
|
|
307
|
+
* The preset is installed as the fabric object's `clipPath`, so it renders,
|
|
308
|
+
* exports and serializes through the same path fabric already uses. The chosen
|
|
309
|
+
* id is kept in `layer.meta.maskPreset` so the UI can show the active preset
|
|
310
|
+
* and so the clip can be rebuilt when the layer is resized.
|
|
311
|
+
*
|
|
312
|
+
* A pattern strips and restores the layer's clip while it is enabled (see
|
|
313
|
+
* `PatternManager`), so a mask preset is suspended for the duration of one.
|
|
314
|
+
*/
|
|
315
|
+
declare class MaskPresetManager {
|
|
316
|
+
private canvas;
|
|
317
|
+
private layers;
|
|
318
|
+
private history;
|
|
319
|
+
private events;
|
|
320
|
+
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
321
|
+
get(layerId: string): MaskPresetId | null;
|
|
322
|
+
/** Clip the layer to `id`. Passing null (or an unknown id) clears the clip. */
|
|
323
|
+
apply(layerId: string, id: MaskPresetId | null, save?: boolean): boolean;
|
|
324
|
+
clear(layerId: string, save?: boolean): boolean;
|
|
325
|
+
/**
|
|
326
|
+
* Re-fit the clip to the layer's current size. The clip is built for the
|
|
327
|
+
* object's dimensions at the time it was applied; editing text or replacing an
|
|
328
|
+
* image changes them, and a stale clip would crop the wrong region.
|
|
329
|
+
*/
|
|
330
|
+
refresh(layerId: string, save?: boolean): boolean;
|
|
331
|
+
/** Re-fit every masked layer — used after a state restore. */
|
|
332
|
+
refreshAll(): void;
|
|
333
|
+
private buildClip;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Silhouette masks, authored on a 0–100 square so they scale to any layer. */
|
|
337
|
+
declare const SHAPE_MASK_IDS: readonly ["circle", "square", "triangle", "star", "heart", "octagram", "arch", "zigzag"];
|
|
338
|
+
type ShapeMaskId = ShapeMaskPresetId;
|
|
339
|
+
declare function isShapeMaskId(value: unknown): value is ShapeMaskId;
|
|
340
|
+
/** SVG path data for a shape mask, on a 100×100 box. */
|
|
341
|
+
declare function shapeMaskPathData(id: ShapeMaskId): string;
|
|
342
|
+
/** Nominal authoring box every shape mask path is drawn in. */
|
|
343
|
+
declare const SHAPE_MASK_BOX = 100;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Procedural alpha textures used as soft layer masks.
|
|
347
|
+
*
|
|
348
|
+
* Each renders white-on-transparent at a fixed resolution; the opaque parts are
|
|
349
|
+
* what survives masking. They are deterministic (seeded PRNG, no `Math.random`)
|
|
350
|
+
* so a design renders identically on every load and in every export.
|
|
351
|
+
*/
|
|
352
|
+
declare const TEXTURE_MASK_IDS: readonly ["vignette", "halftone", "spray", "grunge", "torn", "band"];
|
|
353
|
+
type TextureMaskId = TextureMaskPresetId;
|
|
354
|
+
declare function isTextureMaskId(value: unknown): value is TextureMaskId;
|
|
355
|
+
/** Square resolution every texture is rendered at before being scaled to fit. */
|
|
356
|
+
declare const TEXTURE_MASK_SIZE = 320;
|
|
357
|
+
/** Render (and memoize) a texture mask. Browser-only: needs a 2D canvas. */
|
|
358
|
+
declare function renderTextureMask(id: TextureMaskId): HTMLCanvasElement;
|
|
359
|
+
/** Drop memoized textures — used by tests and by long-lived editors on dispose. */
|
|
360
|
+
declare function clearTextureMaskCache(): void;
|
|
361
|
+
|
|
249
362
|
declare class UnitConverter {
|
|
250
363
|
private unit;
|
|
251
364
|
private dpi;
|
|
@@ -273,6 +386,14 @@ declare function computePrintAreaClip(area: MockupPrintArea, scaleX: number, sca
|
|
|
273
386
|
/** Object-fit: cover geometry, exported for deterministic preview/composite tests. */
|
|
274
387
|
declare function computeCoverPlacement(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): CoverPlacement;
|
|
275
388
|
declare function exportPNG(canvas: Canvas, options?: PngExportOptions): Promise<Blob>;
|
|
389
|
+
/**
|
|
390
|
+
* Render just the print-area rectangle, on transparency.
|
|
391
|
+
*
|
|
392
|
+
* This is the file a print provider receives: the design alone, cropped to the
|
|
393
|
+
* printable rectangle, with no garment behind it and no canvas background baked
|
|
394
|
+
* in — so it is rendered from cloned objects rather than off the live canvas.
|
|
395
|
+
*/
|
|
396
|
+
declare function exportPrintArea(source: Canvas, area: MockupPrintArea, options?: PngExportOptions): Promise<Blob>;
|
|
276
397
|
/** Rasterize the browser mockup preview together with the transparent design. */
|
|
277
398
|
declare function exportMockup(canvas: Canvas, mockup: MockupConfig, options?: PngExportOptions): Promise<Blob>;
|
|
278
399
|
declare function exportSVG(canvas: Canvas): string;
|
|
@@ -390,6 +511,8 @@ declare class CanvasEditor {
|
|
|
390
511
|
readonly snapping: SnapManager;
|
|
391
512
|
readonly crop: CropController;
|
|
392
513
|
readonly patterns: PatternManager;
|
|
514
|
+
readonly curves: TextCurveManager;
|
|
515
|
+
readonly maskPresets: MaskPresetManager;
|
|
393
516
|
readonly fonts: FontRegistry;
|
|
394
517
|
readonly licensing: LicenseManager;
|
|
395
518
|
readonly pages: ProjectManager;
|
|
@@ -433,6 +556,12 @@ declare class CanvasEditor {
|
|
|
433
556
|
toSVG(): string;
|
|
434
557
|
toSVGAsync(options?: SvgExportOptions): Promise<string>;
|
|
435
558
|
toDataURL(format?: ImageFormat, multiplier?: number): string;
|
|
559
|
+
/**
|
|
560
|
+
* Export the print file: the design cropped to the mockup's print area, on
|
|
561
|
+
* transparency. Without a print area this is the whole canvas, still
|
|
562
|
+
* transparent — a print file never carries the design background.
|
|
563
|
+
*/
|
|
564
|
+
toPrintFile(options?: PngExportOptions): Promise<Blob>;
|
|
436
565
|
/** Export the current product-preview composite. Advanced warping is host-defined. */
|
|
437
566
|
toMockupImage(options?: PngExportOptions): Promise<Blob>;
|
|
438
567
|
/**
|
|
@@ -484,13 +613,64 @@ declare class CanvasEditor {
|
|
|
484
613
|
zoomToSelection(padding?: number): void;
|
|
485
614
|
applyPattern(layerId: string, config: PatternConfig): Promise<void>;
|
|
486
615
|
clearPattern(layerId: string): Promise<void>;
|
|
487
|
-
|
|
616
|
+
applyTextCurve(layerId: string, config: Partial<TextCurveConfig>): boolean;
|
|
617
|
+
clearTextCurve(layerId: string): boolean;
|
|
618
|
+
getTextCurve(layerId: string): TextCurveConfig | null;
|
|
619
|
+
applyMaskPreset(layerId: string, id: MaskPresetId | null): boolean;
|
|
620
|
+
clearMaskPreset(layerId: string): boolean;
|
|
621
|
+
getMaskPreset(layerId: string): MaskPresetId | null;
|
|
622
|
+
/**
|
|
623
|
+
* Constrain a layer to its current proportions. Persisted on the layer so a
|
|
624
|
+
* reopened design still resizes the way it was set up to.
|
|
625
|
+
*/
|
|
626
|
+
setLayerAspectLock(layerId: string, locked: boolean): boolean;
|
|
627
|
+
getLayerAspectLock(layerId: string): boolean;
|
|
628
|
+
/** Re-apply every stored aspect lock — control visibility is not serialized. */
|
|
629
|
+
restoreAspectLocks(): void;
|
|
630
|
+
/** Drop scale, rotation, skew and flips; the layer stays where it is. */
|
|
631
|
+
resetLayerTransform(layerId: string): boolean;
|
|
632
|
+
setLayerShadow(layerId: string, config: Partial<LayerShadowConfig>): boolean;
|
|
633
|
+
getLayerShadow(layerId: string): LayerShadowConfig | null;
|
|
634
|
+
/**
|
|
635
|
+
* Show (or clear) the product preview. Pass `history: false` for preview-only
|
|
636
|
+
* changes such as swapping a colourway — those are not design edits and
|
|
637
|
+
* should not fill the undo stack.
|
|
638
|
+
*/
|
|
639
|
+
setMockup(mockup: MockupConfig | null, options?: {
|
|
640
|
+
history?: boolean;
|
|
641
|
+
}): void;
|
|
488
642
|
clearMockup(): void;
|
|
489
643
|
getMockup(): MockupConfig | null;
|
|
490
644
|
dispose(): void;
|
|
491
645
|
private setupCanvasEvents;
|
|
492
646
|
}
|
|
493
647
|
|
|
648
|
+
declare const DEFAULT_LAYER_SHADOW: LayerShadowConfig;
|
|
649
|
+
/**
|
|
650
|
+
* Read a layer's drop shadow back off its fabric object.
|
|
651
|
+
*
|
|
652
|
+
* Fabric serializes `shadow` with the object, so the object — not layer meta —
|
|
653
|
+
* is the source of truth; nothing extra has to round-trip through the editor
|
|
654
|
+
* state for a shadow to survive save/load.
|
|
655
|
+
*/
|
|
656
|
+
declare function readLayerShadow(object: FabricObject): LayerShadowConfig;
|
|
657
|
+
/** Install (or remove) a drop shadow on a fabric object. */
|
|
658
|
+
declare function applyLayerShadow(object: FabricObject, config: Partial<LayerShadowConfig>): void;
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Constrain (or release) a layer's proportions.
|
|
662
|
+
*
|
|
663
|
+
* Fabric already scales uniformly from the corners (`canvas.uniformScaling`),
|
|
664
|
+
* so the lock is enforced by taking away the single-axis handles — every
|
|
665
|
+
* remaining control keeps the ratio.
|
|
666
|
+
*/
|
|
667
|
+
declare function applyAspectLock(object: FabricObject, locked: boolean): void;
|
|
668
|
+
/**
|
|
669
|
+
* Undo scaling, rotation, skew and flips, leaving the layer where it sits.
|
|
670
|
+
* Position is deliberately kept: this is "reset the shape", not "move it back".
|
|
671
|
+
*/
|
|
672
|
+
declare function resetTransform(object: FabricObject): void;
|
|
673
|
+
|
|
494
674
|
declare const generateId: () => string;
|
|
495
675
|
|
|
496
676
|
declare function clamp(v: number, min: number, max: number): number;
|
|
@@ -590,4 +770,4 @@ declare class AnnotationOverlay {
|
|
|
590
770
|
*/
|
|
591
771
|
declare function displaceRgba(source: Uint8ClampedArray, map: Uint8ClampedArray, width: number, height: number, options: Omit<MockupDisplacement, 'image'>): Uint8ClampedArray;
|
|
592
772
|
|
|
593
|
-
export { AnnotationOverlay, type AnnotationPrimitive, BackgroundImageOptions, CANVAS_SIZE_PRESETS, CanvasEditor, CanvasSizePreset, type CoverPlacement, CropController, DpiIssue, EditorConfig, EditorEvents, EditorState, EventEmitter, FileAdapter, FontDefinition, FontRegistry, HistoryManager, ImageAdjustments, ImageProvider, ImageProviderResult, ImageSearchOptions, ImageSearchResult, Layer, LayerData, LayerManager, LayerMeta, LayerType, LicenseConfig, LicenseManager, LicenseStatus, MaskBrushOptions, MaskController, type MaskPerformanceSample, MaskPoint, MaskRefinementError, type MaskRefinementErrorCode, MaskRefinementPrompt, MaskRefinementProvider, MaskRefinementResult, MockupConfig, MockupDisplacement, MockupPrintArea, NormalizedLayerPosition, PatternConfig, PatternLocks, PatternManager, PatternSourceResolver, type PngExportOptions, PositioningAdapter, PrintifyPositioning, ProjectManager, ProjectState, ResizeOptions, SemanticExportOptions, SerializedBackgroundImageOptions, SerializedLayer, ShapePlugin, SnapManager, SvgExportOptions, TemplateDefinition, type TilePlacement, Unit, UnitConverter, type ViewportTransform, applyPatternLocks, buildPatternDataURL, captureLocks, clamp, clearPatternImageCache, computeCoverPlacement, computePrintAreaClip, computeTilePositions, deserializeEditor, displaceRgba, drawTiles, escapeXml, exportDataURL, exportMockup, exportPNG, exportSVG, generateId, isCssColor, loadPatternImage, restoreLocks, round2, sanitizeSvg, serializeEditor };
|
|
773
|
+
export { AnnotationOverlay, type AnnotationPrimitive, BackgroundImageOptions, CANVAS_SIZE_PRESETS, CanvasEditor, CanvasSizePreset, type CoverPlacement, CropController, DEFAULT_LAYER_SHADOW, 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, PatternSourceResolver, type PngExportOptions, PositioningAdapter, PrintifyPositioning, ProjectManager, ProjectState, ResizeOptions, SHAPE_MASK_BOX, SHAPE_MASK_IDS, SemanticExportOptions, SerializedBackgroundImageOptions, SerializedLayer, ShapeMaskPresetId, ShapePlugin, SnapManager, SvgExportOptions, TEXTURE_MASK_IDS, TEXTURE_MASK_SIZE, TemplateDefinition, TextCurveConfig, TextCurveManager, TextureMaskPresetId, type TilePlacement, Unit, UnitConverter, type ViewportTransform, applyAspectLock, applyLayerShadow, applyPatternLocks, buildCurvePathData, buildPatternDataURL, captureLocks, clamp, clearPatternImageCache, clearTextureMaskCache, computeCoverPlacement, computePrintAreaClip, computeTilePositions, deserializeEditor, displaceRgba, drawTiles, escapeXml, exportDataURL, exportMockup, exportPNG, exportPrintArea, exportSVG, generateId, isCssColor, isMaskPresetId, isShapeMaskId, isTextureMaskId, loadPatternImage, readLayerShadow, renderTextureMask, resetTransform, restoreLocks, round2, sanitizeSvg, serializeEditor, shapeMaskPathData };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
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,
|
|
2
|
+
import { b as EditorEvents, m as LayerType, k as LayerMeta, L as LayerData, W as SerializedLayer, J as PatternSourceResolver, P as PatternConfig, H as PatternLocks, a0 as TextCurveConfig, r as MaskPresetId, X as ShapeMaskPresetId, a1 as TextureMaskPresetId, a3 as Unit, G as MockupPrintArea, x as MockupConfig, e as FontDefinition, n as LicenseConfig, p as LicenseStatus, S as ProjectState, M as MaskBrushOptions, q as MaskPoint, t as MaskRefinementProvider, s as MaskRefinementPrompt, v as MaskRefinementResult, E as EditorConfig, Y as ShapePlugin, _ as TemplateDefinition, I as ImageAdjustments, c as EditorState, U as SemanticExportOptions, Z as SvgExportOptions, Q as PrintifyPositioning, N as NormalizedLayerPosition, O as PositioningAdapter, h as ImageProviderResult, i as ImageSearchOptions, j as ImageSearchResult, F as FileAdapter, g as ImageProvider, V as SerializedBackgroundImageOptions, B as BackgroundImageOptions, T as ResizeOptions, a as DpiIssue, l as LayerShadowConfig, C as CanvasSizePreset, y as MockupDisplacement } from './types-Dh1unrzT.js';
|
|
3
|
+
export { D as DEFAULT_PATTERN_CONFIG, d as ExportFormat, f as ImageAttribution, o as LicensePayload, u as MaskRefinementRequest, w as MockupBlendMode, z as MockupDisplacementChannel, A as MockupOverlay, K as PatternState, R as ProjectPage, $ as TemplateParameter, a2 as TileMode } from './types-Dh1unrzT.js';
|
|
4
4
|
|
|
5
5
|
type EventHandler<T> = (data: T) => void;
|
|
6
6
|
declare class EventEmitter<TEvents extends {} = Record<string, unknown>> {
|
|
@@ -47,6 +47,18 @@ declare class LayerManager {
|
|
|
47
47
|
setLocked(id: string, locked: boolean): void;
|
|
48
48
|
setOpacity(id: string, opacity: number): void;
|
|
49
49
|
setName(id: string, name: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Patch a layer's host metadata. A key whose value is `undefined` is removed.
|
|
52
|
+
*
|
|
53
|
+
* `meta` is part of `LayerData` and is serialized, so a host that assigns
|
|
54
|
+
* `layer.meta.x` directly gets neither of the two things every other setter
|
|
55
|
+
* here provides: `layers:changed` (so `useLayers()` keeps returning the old
|
|
56
|
+
* meta) and the history checkpoint (so an undo silently reverts the write —
|
|
57
|
+
* the state IS versioned, it was just never committed at the moment it
|
|
58
|
+
* changed). Going through this method is what makes metadata behave like
|
|
59
|
+
* every other layer property.
|
|
60
|
+
*/
|
|
61
|
+
setMeta(id: string, patch: LayerMeta): void;
|
|
50
62
|
clear(): void;
|
|
51
63
|
count(): number;
|
|
52
64
|
private emitChanged;
|
|
@@ -246,6 +258,107 @@ interface CanvasRenderingProtocol {
|
|
|
246
258
|
drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;
|
|
247
259
|
}
|
|
248
260
|
|
|
261
|
+
/** Straight text — the state every text layer starts in. */
|
|
262
|
+
declare const DEFAULT_TEXT_CURVE: TextCurveConfig;
|
|
263
|
+
interface CurvePath {
|
|
264
|
+
/** SVG path data the text is laid out along. */
|
|
265
|
+
data: string;
|
|
266
|
+
/** Length of that path, used to centre the run on it. */
|
|
267
|
+
length: number;
|
|
268
|
+
}
|
|
269
|
+
/** Path the given curve traces for a text run of `width` px, or null when straight. */
|
|
270
|
+
declare function buildCurvePathData(config: TextCurveConfig, width: number, fontSize: number): CurvePath | null;
|
|
271
|
+
/**
|
|
272
|
+
* Bends a text layer's baseline along a generated path.
|
|
273
|
+
*
|
|
274
|
+
* The curve lives on the fabric object as a real text path, so it survives
|
|
275
|
+
* export and serialization with no extra machinery. The parameters that
|
|
276
|
+
* produced it are kept in `layer.meta.curve` so the UI can show them and so the
|
|
277
|
+
* path can be rebuilt when the text, font or size changes.
|
|
278
|
+
*/
|
|
279
|
+
declare class TextCurveManager {
|
|
280
|
+
private canvas;
|
|
281
|
+
private layers;
|
|
282
|
+
private history;
|
|
283
|
+
private events;
|
|
284
|
+
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
285
|
+
/** Curve parameters for a layer, or null when it is not curved text. */
|
|
286
|
+
get(layerId: string): TextCurveConfig | null;
|
|
287
|
+
isCurved(layerId: string): boolean;
|
|
288
|
+
/** Apply (or update) the curve on a text layer. Zeroed config clears it. */
|
|
289
|
+
apply(layerId: string, config: Partial<TextCurveConfig>, save?: boolean): boolean;
|
|
290
|
+
/** Remove the curve, restoring the authored text box width. */
|
|
291
|
+
clear(layerId: string, save?: boolean): boolean;
|
|
292
|
+
/**
|
|
293
|
+
* Rebuild the path from the stored parameters. Text content, font family and
|
|
294
|
+
* font size all change the run's width, and the path is sized to that width —
|
|
295
|
+
* without this the curve keeps the geometry of the text it was created from.
|
|
296
|
+
*/
|
|
297
|
+
refresh(layerId: string, save?: boolean): boolean;
|
|
298
|
+
/** Rebuild every curved layer — used after a state restore. */
|
|
299
|
+
refreshAll(): void;
|
|
300
|
+
private detach;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
declare function isMaskPresetId(value: unknown): value is MaskPresetId;
|
|
304
|
+
/**
|
|
305
|
+
* Clips a layer to a preset silhouette or soft texture.
|
|
306
|
+
*
|
|
307
|
+
* The preset is installed as the fabric object's `clipPath`, so it renders,
|
|
308
|
+
* exports and serializes through the same path fabric already uses. The chosen
|
|
309
|
+
* id is kept in `layer.meta.maskPreset` so the UI can show the active preset
|
|
310
|
+
* and so the clip can be rebuilt when the layer is resized.
|
|
311
|
+
*
|
|
312
|
+
* A pattern strips and restores the layer's clip while it is enabled (see
|
|
313
|
+
* `PatternManager`), so a mask preset is suspended for the duration of one.
|
|
314
|
+
*/
|
|
315
|
+
declare class MaskPresetManager {
|
|
316
|
+
private canvas;
|
|
317
|
+
private layers;
|
|
318
|
+
private history;
|
|
319
|
+
private events;
|
|
320
|
+
constructor(canvas: Canvas, layers: LayerManager, history: HistoryManager, events: EventEmitter<EditorEvents>);
|
|
321
|
+
get(layerId: string): MaskPresetId | null;
|
|
322
|
+
/** Clip the layer to `id`. Passing null (or an unknown id) clears the clip. */
|
|
323
|
+
apply(layerId: string, id: MaskPresetId | null, save?: boolean): boolean;
|
|
324
|
+
clear(layerId: string, save?: boolean): boolean;
|
|
325
|
+
/**
|
|
326
|
+
* Re-fit the clip to the layer's current size. The clip is built for the
|
|
327
|
+
* object's dimensions at the time it was applied; editing text or replacing an
|
|
328
|
+
* image changes them, and a stale clip would crop the wrong region.
|
|
329
|
+
*/
|
|
330
|
+
refresh(layerId: string, save?: boolean): boolean;
|
|
331
|
+
/** Re-fit every masked layer — used after a state restore. */
|
|
332
|
+
refreshAll(): void;
|
|
333
|
+
private buildClip;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Silhouette masks, authored on a 0–100 square so they scale to any layer. */
|
|
337
|
+
declare const SHAPE_MASK_IDS: readonly ["circle", "square", "triangle", "star", "heart", "octagram", "arch", "zigzag"];
|
|
338
|
+
type ShapeMaskId = ShapeMaskPresetId;
|
|
339
|
+
declare function isShapeMaskId(value: unknown): value is ShapeMaskId;
|
|
340
|
+
/** SVG path data for a shape mask, on a 100×100 box. */
|
|
341
|
+
declare function shapeMaskPathData(id: ShapeMaskId): string;
|
|
342
|
+
/** Nominal authoring box every shape mask path is drawn in. */
|
|
343
|
+
declare const SHAPE_MASK_BOX = 100;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Procedural alpha textures used as soft layer masks.
|
|
347
|
+
*
|
|
348
|
+
* Each renders white-on-transparent at a fixed resolution; the opaque parts are
|
|
349
|
+
* what survives masking. They are deterministic (seeded PRNG, no `Math.random`)
|
|
350
|
+
* so a design renders identically on every load and in every export.
|
|
351
|
+
*/
|
|
352
|
+
declare const TEXTURE_MASK_IDS: readonly ["vignette", "halftone", "spray", "grunge", "torn", "band"];
|
|
353
|
+
type TextureMaskId = TextureMaskPresetId;
|
|
354
|
+
declare function isTextureMaskId(value: unknown): value is TextureMaskId;
|
|
355
|
+
/** Square resolution every texture is rendered at before being scaled to fit. */
|
|
356
|
+
declare const TEXTURE_MASK_SIZE = 320;
|
|
357
|
+
/** Render (and memoize) a texture mask. Browser-only: needs a 2D canvas. */
|
|
358
|
+
declare function renderTextureMask(id: TextureMaskId): HTMLCanvasElement;
|
|
359
|
+
/** Drop memoized textures — used by tests and by long-lived editors on dispose. */
|
|
360
|
+
declare function clearTextureMaskCache(): void;
|
|
361
|
+
|
|
249
362
|
declare class UnitConverter {
|
|
250
363
|
private unit;
|
|
251
364
|
private dpi;
|
|
@@ -273,6 +386,14 @@ declare function computePrintAreaClip(area: MockupPrintArea, scaleX: number, sca
|
|
|
273
386
|
/** Object-fit: cover geometry, exported for deterministic preview/composite tests. */
|
|
274
387
|
declare function computeCoverPlacement(sourceWidth: number, sourceHeight: number, targetWidth: number, targetHeight: number): CoverPlacement;
|
|
275
388
|
declare function exportPNG(canvas: Canvas, options?: PngExportOptions): Promise<Blob>;
|
|
389
|
+
/**
|
|
390
|
+
* Render just the print-area rectangle, on transparency.
|
|
391
|
+
*
|
|
392
|
+
* This is the file a print provider receives: the design alone, cropped to the
|
|
393
|
+
* printable rectangle, with no garment behind it and no canvas background baked
|
|
394
|
+
* in — so it is rendered from cloned objects rather than off the live canvas.
|
|
395
|
+
*/
|
|
396
|
+
declare function exportPrintArea(source: Canvas, area: MockupPrintArea, options?: PngExportOptions): Promise<Blob>;
|
|
276
397
|
/** Rasterize the browser mockup preview together with the transparent design. */
|
|
277
398
|
declare function exportMockup(canvas: Canvas, mockup: MockupConfig, options?: PngExportOptions): Promise<Blob>;
|
|
278
399
|
declare function exportSVG(canvas: Canvas): string;
|
|
@@ -390,6 +511,8 @@ declare class CanvasEditor {
|
|
|
390
511
|
readonly snapping: SnapManager;
|
|
391
512
|
readonly crop: CropController;
|
|
392
513
|
readonly patterns: PatternManager;
|
|
514
|
+
readonly curves: TextCurveManager;
|
|
515
|
+
readonly maskPresets: MaskPresetManager;
|
|
393
516
|
readonly fonts: FontRegistry;
|
|
394
517
|
readonly licensing: LicenseManager;
|
|
395
518
|
readonly pages: ProjectManager;
|
|
@@ -433,6 +556,12 @@ declare class CanvasEditor {
|
|
|
433
556
|
toSVG(): string;
|
|
434
557
|
toSVGAsync(options?: SvgExportOptions): Promise<string>;
|
|
435
558
|
toDataURL(format?: ImageFormat, multiplier?: number): string;
|
|
559
|
+
/**
|
|
560
|
+
* Export the print file: the design cropped to the mockup's print area, on
|
|
561
|
+
* transparency. Without a print area this is the whole canvas, still
|
|
562
|
+
* transparent — a print file never carries the design background.
|
|
563
|
+
*/
|
|
564
|
+
toPrintFile(options?: PngExportOptions): Promise<Blob>;
|
|
436
565
|
/** Export the current product-preview composite. Advanced warping is host-defined. */
|
|
437
566
|
toMockupImage(options?: PngExportOptions): Promise<Blob>;
|
|
438
567
|
/**
|
|
@@ -484,13 +613,64 @@ declare class CanvasEditor {
|
|
|
484
613
|
zoomToSelection(padding?: number): void;
|
|
485
614
|
applyPattern(layerId: string, config: PatternConfig): Promise<void>;
|
|
486
615
|
clearPattern(layerId: string): Promise<void>;
|
|
487
|
-
|
|
616
|
+
applyTextCurve(layerId: string, config: Partial<TextCurveConfig>): boolean;
|
|
617
|
+
clearTextCurve(layerId: string): boolean;
|
|
618
|
+
getTextCurve(layerId: string): TextCurveConfig | null;
|
|
619
|
+
applyMaskPreset(layerId: string, id: MaskPresetId | null): boolean;
|
|
620
|
+
clearMaskPreset(layerId: string): boolean;
|
|
621
|
+
getMaskPreset(layerId: string): MaskPresetId | null;
|
|
622
|
+
/**
|
|
623
|
+
* Constrain a layer to its current proportions. Persisted on the layer so a
|
|
624
|
+
* reopened design still resizes the way it was set up to.
|
|
625
|
+
*/
|
|
626
|
+
setLayerAspectLock(layerId: string, locked: boolean): boolean;
|
|
627
|
+
getLayerAspectLock(layerId: string): boolean;
|
|
628
|
+
/** Re-apply every stored aspect lock — control visibility is not serialized. */
|
|
629
|
+
restoreAspectLocks(): void;
|
|
630
|
+
/** Drop scale, rotation, skew and flips; the layer stays where it is. */
|
|
631
|
+
resetLayerTransform(layerId: string): boolean;
|
|
632
|
+
setLayerShadow(layerId: string, config: Partial<LayerShadowConfig>): boolean;
|
|
633
|
+
getLayerShadow(layerId: string): LayerShadowConfig | null;
|
|
634
|
+
/**
|
|
635
|
+
* Show (or clear) the product preview. Pass `history: false` for preview-only
|
|
636
|
+
* changes such as swapping a colourway — those are not design edits and
|
|
637
|
+
* should not fill the undo stack.
|
|
638
|
+
*/
|
|
639
|
+
setMockup(mockup: MockupConfig | null, options?: {
|
|
640
|
+
history?: boolean;
|
|
641
|
+
}): void;
|
|
488
642
|
clearMockup(): void;
|
|
489
643
|
getMockup(): MockupConfig | null;
|
|
490
644
|
dispose(): void;
|
|
491
645
|
private setupCanvasEvents;
|
|
492
646
|
}
|
|
493
647
|
|
|
648
|
+
declare const DEFAULT_LAYER_SHADOW: LayerShadowConfig;
|
|
649
|
+
/**
|
|
650
|
+
* Read a layer's drop shadow back off its fabric object.
|
|
651
|
+
*
|
|
652
|
+
* Fabric serializes `shadow` with the object, so the object — not layer meta —
|
|
653
|
+
* is the source of truth; nothing extra has to round-trip through the editor
|
|
654
|
+
* state for a shadow to survive save/load.
|
|
655
|
+
*/
|
|
656
|
+
declare function readLayerShadow(object: FabricObject): LayerShadowConfig;
|
|
657
|
+
/** Install (or remove) a drop shadow on a fabric object. */
|
|
658
|
+
declare function applyLayerShadow(object: FabricObject, config: Partial<LayerShadowConfig>): void;
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Constrain (or release) a layer's proportions.
|
|
662
|
+
*
|
|
663
|
+
* Fabric already scales uniformly from the corners (`canvas.uniformScaling`),
|
|
664
|
+
* so the lock is enforced by taking away the single-axis handles — every
|
|
665
|
+
* remaining control keeps the ratio.
|
|
666
|
+
*/
|
|
667
|
+
declare function applyAspectLock(object: FabricObject, locked: boolean): void;
|
|
668
|
+
/**
|
|
669
|
+
* Undo scaling, rotation, skew and flips, leaving the layer where it sits.
|
|
670
|
+
* Position is deliberately kept: this is "reset the shape", not "move it back".
|
|
671
|
+
*/
|
|
672
|
+
declare function resetTransform(object: FabricObject): void;
|
|
673
|
+
|
|
494
674
|
declare const generateId: () => string;
|
|
495
675
|
|
|
496
676
|
declare function clamp(v: number, min: number, max: number): number;
|
|
@@ -590,4 +770,4 @@ declare class AnnotationOverlay {
|
|
|
590
770
|
*/
|
|
591
771
|
declare function displaceRgba(source: Uint8ClampedArray, map: Uint8ClampedArray, width: number, height: number, options: Omit<MockupDisplacement, 'image'>): Uint8ClampedArray;
|
|
592
772
|
|
|
593
|
-
export { AnnotationOverlay, type AnnotationPrimitive, BackgroundImageOptions, CANVAS_SIZE_PRESETS, CanvasEditor, CanvasSizePreset, type CoverPlacement, CropController, DpiIssue, EditorConfig, EditorEvents, EditorState, EventEmitter, FileAdapter, FontDefinition, FontRegistry, HistoryManager, ImageAdjustments, ImageProvider, ImageProviderResult, ImageSearchOptions, ImageSearchResult, Layer, LayerData, LayerManager, LayerMeta, LayerType, LicenseConfig, LicenseManager, LicenseStatus, MaskBrushOptions, MaskController, type MaskPerformanceSample, MaskPoint, MaskRefinementError, type MaskRefinementErrorCode, MaskRefinementPrompt, MaskRefinementProvider, MaskRefinementResult, MockupConfig, MockupDisplacement, MockupPrintArea, NormalizedLayerPosition, PatternConfig, PatternLocks, PatternManager, PatternSourceResolver, type PngExportOptions, PositioningAdapter, PrintifyPositioning, ProjectManager, ProjectState, ResizeOptions, SemanticExportOptions, SerializedBackgroundImageOptions, SerializedLayer, ShapePlugin, SnapManager, SvgExportOptions, TemplateDefinition, type TilePlacement, Unit, UnitConverter, type ViewportTransform, applyPatternLocks, buildPatternDataURL, captureLocks, clamp, clearPatternImageCache, computeCoverPlacement, computePrintAreaClip, computeTilePositions, deserializeEditor, displaceRgba, drawTiles, escapeXml, exportDataURL, exportMockup, exportPNG, exportSVG, generateId, isCssColor, loadPatternImage, restoreLocks, round2, sanitizeSvg, serializeEditor };
|
|
773
|
+
export { AnnotationOverlay, type AnnotationPrimitive, BackgroundImageOptions, CANVAS_SIZE_PRESETS, CanvasEditor, CanvasSizePreset, type CoverPlacement, CropController, DEFAULT_LAYER_SHADOW, 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, PatternSourceResolver, type PngExportOptions, PositioningAdapter, PrintifyPositioning, ProjectManager, ProjectState, ResizeOptions, SHAPE_MASK_BOX, SHAPE_MASK_IDS, SemanticExportOptions, SerializedBackgroundImageOptions, SerializedLayer, ShapeMaskPresetId, ShapePlugin, SnapManager, SvgExportOptions, TEXTURE_MASK_IDS, TEXTURE_MASK_SIZE, TemplateDefinition, TextCurveConfig, TextCurveManager, TextureMaskPresetId, type TilePlacement, Unit, UnitConverter, type ViewportTransform, applyAspectLock, applyLayerShadow, applyPatternLocks, buildCurvePathData, buildPatternDataURL, captureLocks, clamp, clearPatternImageCache, clearTextureMaskCache, computeCoverPlacement, computePrintAreaClip, computeTilePositions, deserializeEditor, displaceRgba, drawTiles, escapeXml, exportDataURL, exportMockup, exportPNG, exportPrintArea, exportSVG, generateId, isCssColor, isMaskPresetId, isShapeMaskId, isTextureMaskId, loadPatternImage, readLayerShadow, renderTextureMask, resetTransform, restoreLocks, round2, sanitizeSvg, serializeEditor, shapeMaskPathData };
|