@pixerate/editor 0.150.0 → 0.150.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-QCEQIRJQ.cjs → chunk-PI45JMP7.cjs} +163 -136
- package/dist/{chunk-ZQUANEK4.js → chunk-Y64YPIFT.js} +28 -1
- package/dist/image-editor/canvas-viewport.d.cts +52 -0
- package/dist/image-editor/canvas-viewport.d.ts +52 -0
- package/dist/image-editor/index.cjs +663 -596
- package/dist/image-editor/index.d.cts +1 -0
- package/dist/image-editor/index.d.ts +1 -0
- package/dist/image-editor/index.js +96 -29
- package/dist/image-editor/layers/ops.d.cts +21 -3
- package/dist/image-editor/layers/ops.d.ts +21 -3
- package/dist/image-editor/renderer.d.cts +7 -0
- package/dist/image-editor/renderer.d.ts +7 -0
- package/dist/paint-editor/index.cjs +6 -6
- package/dist/paint-editor/index.js +1 -1
- package/package.json +2 -2
- package/skills/pixerate-image-editor/SKILL.md +6 -6
|
@@ -2901,11 +2901,34 @@ function combineCoverage(a, b, op, n) {
|
|
|
2901
2901
|
|
|
2902
2902
|
// src/image-editor/layers/ops.ts
|
|
2903
2903
|
var LayerOperationError = class extends Error {
|
|
2904
|
-
|
|
2904
|
+
userMessage;
|
|
2905
|
+
constructor(message, userMessage) {
|
|
2905
2906
|
super(message);
|
|
2906
2907
|
this.name = "LayerOperationError";
|
|
2908
|
+
if (userMessage) this.userMessage = userMessage;
|
|
2907
2909
|
}
|
|
2908
2910
|
};
|
|
2911
|
+
function userErrorMessage(err) {
|
|
2912
|
+
if (err instanceof LayerOperationError && err.userMessage) return err.userMessage;
|
|
2913
|
+
return err instanceof Error ? err.message : String(err);
|
|
2914
|
+
}
|
|
2915
|
+
function isPaintableLayer(layer) {
|
|
2916
|
+
return layer.type === "pixel" && layer.visible && !isLayerLocked(layer, "pixels");
|
|
2917
|
+
}
|
|
2918
|
+
function defaultActiveLayerId(layers) {
|
|
2919
|
+
const pixels = flattenLayers(layers).filter((l) => l.type === "pixel");
|
|
2920
|
+
for (let i = pixels.length - 1; i >= 0; i--) if (isPaintableLayer(pixels[i])) return pixels[i].id;
|
|
2921
|
+
return pixels[pixels.length - 1]?.id ?? null;
|
|
2922
|
+
}
|
|
2923
|
+
function activeLayerAfterRemoval(prev, next, removedId) {
|
|
2924
|
+
const before = flattenLayers(prev);
|
|
2925
|
+
const at = before.findIndex((l) => l.id === removedId);
|
|
2926
|
+
for (let i = at - 1; i >= 0; i--) {
|
|
2927
|
+
const loc = findLayer(next, before[i].id);
|
|
2928
|
+
if (loc && isPaintableLayer(loc.layer)) return loc.layer.id;
|
|
2929
|
+
}
|
|
2930
|
+
return defaultActiveLayerId(next);
|
|
2931
|
+
}
|
|
2909
2932
|
var fail = (message) => {
|
|
2910
2933
|
throw new LayerOperationError(message);
|
|
2911
2934
|
};
|
|
@@ -11612,6 +11635,10 @@ export {
|
|
|
11612
11635
|
flattenPath,
|
|
11613
11636
|
rasterizeCoverage,
|
|
11614
11637
|
LayerOperationError,
|
|
11638
|
+
userErrorMessage,
|
|
11639
|
+
isPaintableLayer,
|
|
11640
|
+
defaultActiveLayerId,
|
|
11641
|
+
activeLayerAfterRemoval,
|
|
11615
11642
|
requireLayer,
|
|
11616
11643
|
requireUnlocked,
|
|
11617
11644
|
placeLayer,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sizing an on-screen editor canvas: its layout size in CSS pixels (what the projection, overlays
|
|
3
|
+
* and pointer mapping use) and how many backing-store pixels each CSS pixel needs to look sharp.
|
|
4
|
+
*/
|
|
5
|
+
/** What `measureCanvasViewport` reads from the element that holds the canvas. */
|
|
6
|
+
export interface MeasurableElement {
|
|
7
|
+
readonly clientWidth: number;
|
|
8
|
+
readonly clientHeight: number;
|
|
9
|
+
/** Layout size including borders, compared with the on-screen box to find the CSS transform scale. */
|
|
10
|
+
readonly offsetWidth?: number;
|
|
11
|
+
readonly offsetHeight?: number;
|
|
12
|
+
getBoundingClientRect(): {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface CanvasViewport {
|
|
18
|
+
/** Layout width in CSS pixels (pass as `RenderOptions.viewportWidth`). */
|
|
19
|
+
width: number;
|
|
20
|
+
/** Layout height in CSS pixels (pass as `RenderOptions.viewportHeight`). */
|
|
21
|
+
height: number;
|
|
22
|
+
/** Backing-store pixels per CSS pixel (pass as `RenderOptions.pixelRatio`). */
|
|
23
|
+
pixelRatio: number;
|
|
24
|
+
}
|
|
25
|
+
/** The size `measureCanvasViewport` gives an element without layout (e.g. before it is shown, or in jsdom). */
|
|
26
|
+
export declare const DEFAULT_CANVAS_VIEWPORT: Readonly<{
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
}>;
|
|
30
|
+
/** The longest side a viewport backing store may reach; the pixel ratio is lowered to fit. */
|
|
31
|
+
export declare const MAX_CANVAS_BACKING_SIDE = 8192;
|
|
32
|
+
/**
|
|
33
|
+
* Measures the element a viewport canvas fills. `clientWidth` / `clientHeight` give the layout size
|
|
34
|
+
* (they ignore CSS transforms); `getBoundingClientRect()` gives the size on screen. Their ratio is
|
|
35
|
+
* the scale of any transform on the element or its ancestors, so the pixel ratio is
|
|
36
|
+
* `devicePixelRatio × that scale`: a 220px node scaled to 500px on a 2× screen gets ~4.5 backing
|
|
37
|
+
* pixels per CSS pixel instead of being stretched. `fallback` is the size of an element without
|
|
38
|
+
* layout (default `DEFAULT_CANVAS_VIEWPORT`).
|
|
39
|
+
*/
|
|
40
|
+
export declare function measureCanvasViewport(el: MeasurableElement, devicePixelRatio?: number, fallback?: {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
}): CanvasViewport;
|
|
44
|
+
/** Whether two measurements need different backing stores. */
|
|
45
|
+
export declare function sameCanvasViewport(a: CanvasViewport, b: CanvasViewport): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Calls `onChange` when the element's viewport measurement changes: on resize (a
|
|
48
|
+
* `ResizeObserver`), on window resize (browser zoom, moving to another screen) and after any CSS
|
|
49
|
+
* transition or animation ends (a host scaling the element with a transform, which resizes nothing).
|
|
50
|
+
* Returns a function that stops watching.
|
|
51
|
+
*/
|
|
52
|
+
export declare function watchCanvasViewport(el: MeasurableElement & Partial<Element>, onChange: (viewport: CanvasViewport) => void): () => void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sizing an on-screen editor canvas: its layout size in CSS pixels (what the projection, overlays
|
|
3
|
+
* and pointer mapping use) and how many backing-store pixels each CSS pixel needs to look sharp.
|
|
4
|
+
*/
|
|
5
|
+
/** What `measureCanvasViewport` reads from the element that holds the canvas. */
|
|
6
|
+
export interface MeasurableElement {
|
|
7
|
+
readonly clientWidth: number;
|
|
8
|
+
readonly clientHeight: number;
|
|
9
|
+
/** Layout size including borders, compared with the on-screen box to find the CSS transform scale. */
|
|
10
|
+
readonly offsetWidth?: number;
|
|
11
|
+
readonly offsetHeight?: number;
|
|
12
|
+
getBoundingClientRect(): {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface CanvasViewport {
|
|
18
|
+
/** Layout width in CSS pixels (pass as `RenderOptions.viewportWidth`). */
|
|
19
|
+
width: number;
|
|
20
|
+
/** Layout height in CSS pixels (pass as `RenderOptions.viewportHeight`). */
|
|
21
|
+
height: number;
|
|
22
|
+
/** Backing-store pixels per CSS pixel (pass as `RenderOptions.pixelRatio`). */
|
|
23
|
+
pixelRatio: number;
|
|
24
|
+
}
|
|
25
|
+
/** The size `measureCanvasViewport` gives an element without layout (e.g. before it is shown, or in jsdom). */
|
|
26
|
+
export declare const DEFAULT_CANVAS_VIEWPORT: Readonly<{
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
}>;
|
|
30
|
+
/** The longest side a viewport backing store may reach; the pixel ratio is lowered to fit. */
|
|
31
|
+
export declare const MAX_CANVAS_BACKING_SIDE = 8192;
|
|
32
|
+
/**
|
|
33
|
+
* Measures the element a viewport canvas fills. `clientWidth` / `clientHeight` give the layout size
|
|
34
|
+
* (they ignore CSS transforms); `getBoundingClientRect()` gives the size on screen. Their ratio is
|
|
35
|
+
* the scale of any transform on the element or its ancestors, so the pixel ratio is
|
|
36
|
+
* `devicePixelRatio × that scale`: a 220px node scaled to 500px on a 2× screen gets ~4.5 backing
|
|
37
|
+
* pixels per CSS pixel instead of being stretched. `fallback` is the size of an element without
|
|
38
|
+
* layout (default `DEFAULT_CANVAS_VIEWPORT`).
|
|
39
|
+
*/
|
|
40
|
+
export declare function measureCanvasViewport(el: MeasurableElement, devicePixelRatio?: number, fallback?: {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
}): CanvasViewport;
|
|
44
|
+
/** Whether two measurements need different backing stores. */
|
|
45
|
+
export declare function sameCanvasViewport(a: CanvasViewport, b: CanvasViewport): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Calls `onChange` when the element's viewport measurement changes: on resize (a
|
|
48
|
+
* `ResizeObserver`), on window resize (browser zoom, moving to another screen) and after any CSS
|
|
49
|
+
* transition or animation ends (a host scaling the element with a transform, which resizes nothing).
|
|
50
|
+
* Returns a function that stops watching.
|
|
51
|
+
*/
|
|
52
|
+
export declare function watchCanvasViewport(el: MeasurableElement & Partial<Element>, onChange: (viewport: CanvasViewport) => void): () => void;
|