@magicpages/kalotyp-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas/bake-canvas.d.ts +25 -0
- package/dist/canvas/bake-canvas.d.ts.map +1 -0
- package/dist/canvas/load-image.d.ts +16 -0
- package/dist/canvas/load-image.d.ts.map +1 -0
- package/dist/canvas/viewport-controller.d.ts +46 -0
- package/dist/canvas/viewport-controller.d.ts.map +1 -0
- package/dist/canvas/viewport.d.ts +43 -0
- package/dist/canvas/viewport.d.ts.map +1 -0
- package/dist/events/event-bus.d.ts +10 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/geometry/rect.d.ts +35 -0
- package/dist/geometry/rect.d.ts.map +1 -0
- package/dist/history/history.d.ts +38 -0
- package/dist/history/history.d.ts.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1976 -0
- package/dist/index.js.map +1 -0
- package/dist/output/state.d.ts +27 -0
- package/dist/output/state.d.ts.map +1 -0
- package/dist/pipeline/encode.d.ts +27 -0
- package/dist/pipeline/encode.d.ts.map +1 -0
- package/dist/pipeline/exif.d.ts +16 -0
- package/dist/pipeline/exif.d.ts.map +1 -0
- package/dist/pipeline/run-chain.d.ts +10 -0
- package/dist/pipeline/run-chain.d.ts.map +1 -0
- package/dist/plugins/annotate/bake.d.ts +16 -0
- package/dist/plugins/annotate/bake.d.ts.map +1 -0
- package/dist/plugins/annotate/geometry.d.ts +36 -0
- package/dist/plugins/annotate/geometry.d.ts.map +1 -0
- package/dist/plugins/annotate/hit-test.d.ts +8 -0
- package/dist/plugins/annotate/hit-test.d.ts.map +1 -0
- package/dist/plugins/annotate/smooth.d.ts +16 -0
- package/dist/plugins/annotate/smooth.d.ts.map +1 -0
- package/dist/plugins/annotate/state.d.ts +176 -0
- package/dist/plugins/annotate/state.d.ts.map +1 -0
- package/dist/plugins/crop/aspect-ratio.d.ts +15 -0
- package/dist/plugins/crop/aspect-ratio.d.ts.map +1 -0
- package/dist/plugins/crop/bake.d.ts +13 -0
- package/dist/plugins/crop/bake.d.ts.map +1 -0
- package/dist/plugins/crop/preset-filter.d.ts +10 -0
- package/dist/plugins/crop/preset-filter.d.ts.map +1 -0
- package/dist/plugins/crop/resize.d.ts +19 -0
- package/dist/plugins/crop/resize.d.ts.map +1 -0
- package/dist/plugins/crop/state.d.ts +23 -0
- package/dist/plugins/crop/state.d.ts.map +1 -0
- package/dist/plugins/filter/presets.d.ts +19 -0
- package/dist/plugins/filter/presets.d.ts.map +1 -0
- package/dist/plugins/finetune/bake.d.ts +5 -0
- package/dist/plugins/finetune/bake.d.ts.map +1 -0
- package/dist/plugins/finetune/math.d.ts +32 -0
- package/dist/plugins/finetune/math.d.ts.map +1 -0
- package/dist/plugins/finetune/state.d.ts +31 -0
- package/dist/plugins/finetune/state.d.ts.map +1 -0
- package/dist/plugins/flip/bake.d.ts +5 -0
- package/dist/plugins/flip/bake.d.ts.map +1 -0
- package/dist/plugins/flip/state.d.ts +9 -0
- package/dist/plugins/flip/state.d.ts.map +1 -0
- package/dist/plugins/frame/bake.d.ts +16 -0
- package/dist/plugins/frame/bake.d.ts.map +1 -0
- package/dist/plugins/frame/state.d.ts +29 -0
- package/dist/plugins/frame/state.d.ts.map +1 -0
- package/dist/plugins/redact/bake.d.ts +13 -0
- package/dist/plugins/redact/bake.d.ts.map +1 -0
- package/dist/plugins/redact/state.d.ts +112 -0
- package/dist/plugins/redact/state.d.ts.map +1 -0
- package/dist/plugins/resize/bake.d.ts +9 -0
- package/dist/plugins/resize/bake.d.ts.map +1 -0
- package/dist/plugins/resize/state.d.ts +37 -0
- package/dist/plugins/resize/state.d.ts.map +1 -0
- package/dist/plugins/rotate/bake.d.ts +9 -0
- package/dist/plugins/rotate/bake.d.ts.map +1 -0
- package/dist/plugins/rotate/inscribe.d.ts +14 -0
- package/dist/plugins/rotate/inscribe.d.ts.map +1 -0
- package/dist/plugins/rotate/state.d.ts +21 -0
- package/dist/plugins/rotate/state.d.ts.map +1 -0
- package/dist/plugins/utility.d.ts +59 -0
- package/dist/plugins/utility.d.ts.map +1 -0
- package/dist/state/store.d.ts +14 -0
- package/dist/state/store.d.ts.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bake.d.ts","sourceRoot":"","sources":["../../../src/plugins/redact/bake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CAC/C;AAED,8EAA8E;AAC9E,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAoBtB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,wBAAwB,GAAG,iCAAiC,EACjE,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,WAAW,GAClB,IAAI,CAmBN"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redact state and mutators. Mirrors the annotate plugin's vocabulary
|
|
3
|
+
* (id + kind, monotonic mint, replace/delete) so the selection layer
|
|
4
|
+
* can be reused.
|
|
5
|
+
*/
|
|
6
|
+
import type { Rect } from '../../geometry/rect.js';
|
|
7
|
+
/** `pixelate`, `blur`, or `solid` (flat fill). */
|
|
8
|
+
export type RedactMode = 'pixelate' | 'blur' | 'solid';
|
|
9
|
+
export declare const REDACT_MODES: readonly RedactMode[];
|
|
10
|
+
export interface RedactRegion {
|
|
11
|
+
/** Stable per-session id; survives undo/redo. */
|
|
12
|
+
readonly id: string;
|
|
13
|
+
/** Image-space rectangle. May be temporarily negative-extent mid-drag. */
|
|
14
|
+
readonly x: number;
|
|
15
|
+
readonly y: number;
|
|
16
|
+
readonly width: number;
|
|
17
|
+
readonly height: number;
|
|
18
|
+
readonly mode: RedactMode;
|
|
19
|
+
/** Used only when `mode === 'solid'`. CSS hex string. */
|
|
20
|
+
readonly color: string;
|
|
21
|
+
}
|
|
22
|
+
export interface RedactState {
|
|
23
|
+
readonly regions: ReadonlyArray<RedactRegion>;
|
|
24
|
+
/** Monotonic id source for new regions. Never decreases. */
|
|
25
|
+
readonly nextRegionNumber: number;
|
|
26
|
+
/** The currently-selected region id, or `null` when none. */
|
|
27
|
+
readonly selectedId: string | null;
|
|
28
|
+
/** The mode new regions are created with. Persists across selections. */
|
|
29
|
+
readonly currentMode: RedactMode;
|
|
30
|
+
/** Default fill colour for the `solid` mode. */
|
|
31
|
+
readonly currentColor: string;
|
|
32
|
+
/** Image-space dimensions of the upstream-baked source the plugin was mounted on. */
|
|
33
|
+
readonly imageSize: {
|
|
34
|
+
readonly width: number;
|
|
35
|
+
readonly height: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export declare const DEFAULT_REDACT_COLOR = "#000000";
|
|
39
|
+
export declare const DEFAULT_REDACT_MODE: RedactMode;
|
|
40
|
+
export interface InitialRedactStateInput {
|
|
41
|
+
readonly imageSize: {
|
|
42
|
+
readonly width: number;
|
|
43
|
+
readonly height: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare function initialRedactState(input: InitialRedactStateInput): RedactState;
|
|
47
|
+
/** Allocate a new region id; caller threads `nextRegionNumber` back into state. */
|
|
48
|
+
export declare function mintRegionId(state: RedactState): {
|
|
49
|
+
id: string;
|
|
50
|
+
nextRegionNumber: number;
|
|
51
|
+
};
|
|
52
|
+
export declare function addRegion(state: RedactState, region: RedactRegion): RedactState;
|
|
53
|
+
export declare function replaceRegion(state: RedactState, region: RedactRegion): RedactState;
|
|
54
|
+
export declare function deleteRegion(state: RedactState, id: string): RedactState;
|
|
55
|
+
/** Mirror every region across an axis of `dims`. */
|
|
56
|
+
export declare function mirrorRegions(state: RedactState, axis: 'horizontal' | 'vertical', dims: {
|
|
57
|
+
readonly width: number;
|
|
58
|
+
readonly height: number;
|
|
59
|
+
}): RedactState;
|
|
60
|
+
/** Translate every region by `(dx, dy)`. Out-of-bounds regions are kept (bake clips on Save). */
|
|
61
|
+
export declare function translateRegions(state: RedactState, dx: number, dy: number, dims: {
|
|
62
|
+
readonly width: number;
|
|
63
|
+
readonly height: number;
|
|
64
|
+
}): RedactState;
|
|
65
|
+
/**
|
|
66
|
+
* Rotate every region `turns × 90°` CW around the image centre. Caller
|
|
67
|
+
* passes post-rotation dims as `newDims`; pre-rotation dims come from
|
|
68
|
+
* `state.imageSize`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function rotateRegions(state: RedactState, turns: 0 | 1 | 2 | 3, newDims: {
|
|
71
|
+
readonly width: number;
|
|
72
|
+
readonly height: number;
|
|
73
|
+
}): RedactState;
|
|
74
|
+
export declare function selectRegion(state: RedactState, id: string | null): RedactState;
|
|
75
|
+
export declare function setCurrentMode(state: RedactState, mode: RedactMode): RedactState;
|
|
76
|
+
export declare function setCurrentColor(state: RedactState, color: string): RedactState;
|
|
77
|
+
/** Update the mode of a region; `color` is preserved across mode flips. */
|
|
78
|
+
export declare function setRegionMode(state: RedactState, id: string, mode: RedactMode): RedactState;
|
|
79
|
+
export declare function setRegionColor(state: RedactState, id: string, color: string): RedactState;
|
|
80
|
+
export declare function findRegion(state: RedactState, id: string | null): RedactRegion | undefined;
|
|
81
|
+
export declare function selectedRegionOf(state: RedactState): RedactRegion | null;
|
|
82
|
+
/** Normalise a region's rect so `width` / `height` are non-negative. */
|
|
83
|
+
export declare function normaliseRegionExtent(extent: {
|
|
84
|
+
x: number;
|
|
85
|
+
y: number;
|
|
86
|
+
width: number;
|
|
87
|
+
height: number;
|
|
88
|
+
}): {
|
|
89
|
+
x: number;
|
|
90
|
+
y: number;
|
|
91
|
+
width: number;
|
|
92
|
+
height: number;
|
|
93
|
+
};
|
|
94
|
+
/** Default-sized region centred on the image. Used by the keyboard "Insert" path. */
|
|
95
|
+
export interface CreateCenteredRegionContext {
|
|
96
|
+
readonly imageSize: {
|
|
97
|
+
readonly width: number;
|
|
98
|
+
readonly height: number;
|
|
99
|
+
};
|
|
100
|
+
readonly mode: RedactMode;
|
|
101
|
+
readonly color: string;
|
|
102
|
+
readonly id: string;
|
|
103
|
+
}
|
|
104
|
+
export declare function createCenteredRegion(ctx: CreateCenteredRegionContext): RedactRegion;
|
|
105
|
+
/** Clamp regions against new bounds; drop regions fully outside. "Clamp, don't reset". */
|
|
106
|
+
export declare function revalidateAgainstBounds(state: RedactState, bounds: {
|
|
107
|
+
width: number;
|
|
108
|
+
height: number;
|
|
109
|
+
}): RedactState;
|
|
110
|
+
/** Bounding-box shape used by the selection layer; matches `Rect`. */
|
|
111
|
+
export declare function regionBoundingBox(region: RedactRegion): Rect;
|
|
112
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/redact/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SourceImage } from '../utility.js';
|
|
2
|
+
import { type ResizeState } from './state.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resize `source` to the dimensions implied by `state`. Downscales > 2×
|
|
5
|
+
* run a halving pyramid first so the bilinear-ish `drawImage` scaler
|
|
6
|
+
* doesn't alias.
|
|
7
|
+
*/
|
|
8
|
+
export declare function bakeResize(state: ResizeState, source: SourceImage): Promise<SourceImage>;
|
|
9
|
+
//# sourceMappingURL=bake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bake.d.ts","sourceRoot":"","sources":["../../../src/plugins/resize/bake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,WAAW,EAAmC,MAAM,YAAY,CAAC;AAE/E;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAiC9F"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-axis scale factors. `lockAspect` makes the editor keep `scaleX === scaleY`.
|
|
3
|
+
* Output pixels are computed at bake time as `round(upstream * scale)`,
|
|
4
|
+
* clamped to `[MIN_DIMENSION, MAX_DIMENSION]`.
|
|
5
|
+
*/
|
|
6
|
+
export interface ResizeState {
|
|
7
|
+
readonly scaleX: number;
|
|
8
|
+
readonly scaleY: number;
|
|
9
|
+
readonly lockAspect: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const MAX_DIMENSION = 8000;
|
|
12
|
+
export declare const MIN_DIMENSION = 1;
|
|
13
|
+
export declare function initialResizeState(): ResizeState;
|
|
14
|
+
export declare function isResizeNoOp(state: ResizeState): boolean;
|
|
15
|
+
/** Integer output dimensions for an upstream image, clamped per axis. */
|
|
16
|
+
export declare function resolveOutputSize(state: ResizeState, upstream: {
|
|
17
|
+
readonly width: number;
|
|
18
|
+
readonly height: number;
|
|
19
|
+
}): {
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
/** Set width via a pixel value; with `lockAspect` the vertical scale follows. */
|
|
24
|
+
export declare function setWidthPx(state: ResizeState, widthPx: number, upstream: {
|
|
25
|
+
readonly width: number;
|
|
26
|
+
readonly height: number;
|
|
27
|
+
}): ResizeState;
|
|
28
|
+
export declare function setHeightPx(state: ResizeState, heightPx: number, upstream: {
|
|
29
|
+
readonly width: number;
|
|
30
|
+
readonly height: number;
|
|
31
|
+
}): ResizeState;
|
|
32
|
+
/** Uniform percentage change; always touches both axes regardless of `lockAspect`. */
|
|
33
|
+
export declare function setPercent(state: ResizeState, percent: number): ResizeState;
|
|
34
|
+
export declare function setLockAspect(state: ResizeState, locked: boolean): ResizeState;
|
|
35
|
+
/** Percent display value; when axes differ, returns the larger scale. */
|
|
36
|
+
export declare function effectivePercent(state: ResizeState): number;
|
|
37
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/resize/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAExD;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAInC;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CACxB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5D,WAAW,CAMb;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5D,WAAW,CAMb;AAED,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW,CAG3E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,WAAW,CAM9E;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAG3D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SourceImage } from '../utility.js';
|
|
2
|
+
import { type RotateState } from './state.js';
|
|
3
|
+
/**
|
|
4
|
+
* Apply rotation = quarter-turns + free-angle in one `drawImage`. Free
|
|
5
|
+
* angles auto-crop to the largest same-aspect rect inside the rotated
|
|
6
|
+
* bounding box so transparent corners stay out of the output.
|
|
7
|
+
*/
|
|
8
|
+
export declare function bakeRotate(state: RotateState, source: SourceImage): Promise<SourceImage>;
|
|
9
|
+
//# sourceMappingURL=bake.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bake.d.ts","sourceRoot":"","sources":["../../../src/plugins/rotate/bake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,KAAK,WAAW,EAAmC,MAAM,YAAY,CAAC;AAE/E;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CA0C9F"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Size } from '../../geometry/rect.js';
|
|
2
|
+
/**
|
|
3
|
+
* Largest axis-aligned rect of the source's aspect ratio that fits
|
|
4
|
+
* inside the source rotated by `angleRad`. Used by free-angle rotation
|
|
5
|
+
* to avoid transparent corners.
|
|
6
|
+
*
|
|
7
|
+
* The two binding constraints reduce to
|
|
8
|
+
* `2x ≤ W² / (W|cosθ| + H|sinθ|)`
|
|
9
|
+
* `2x ≤ W·H / (W|sinθ| + H|cosθ|)`
|
|
10
|
+
* — the inscribed half-width is the smaller bound. Works on absolute
|
|
11
|
+
* sin/cos so the result is symmetric in the sign of the angle.
|
|
12
|
+
*/
|
|
13
|
+
export declare function largestInscribedRect(source: Size, angleRad: number): Size;
|
|
14
|
+
//# sourceMappingURL=inscribe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inscribe.d.ts","sourceRoot":"","sources":["../../../src/plugins/rotate/inscribe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAgBzE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Independent quarter-turns (lossless 90° CW) and free angle (±45°).
|
|
3
|
+
* Bake applies `quarterTurns * 90° + freeAngle` so a press of "rotate 90°"
|
|
4
|
+
* doesn't reset a straighten correction and vice versa.
|
|
5
|
+
*/
|
|
6
|
+
export interface RotateState {
|
|
7
|
+
readonly quarterTurns: 0 | 1 | 2 | 3;
|
|
8
|
+
/** Free-angle offset in degrees. Range: [-45, 45]. */
|
|
9
|
+
readonly freeAngle: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const FREE_ANGLE_MIN = -45;
|
|
12
|
+
export declare const FREE_ANGLE_MAX = 45;
|
|
13
|
+
export declare const FREE_ANGLE_STEP = 0.1;
|
|
14
|
+
export declare function initialRotateState(): RotateState;
|
|
15
|
+
export declare function rotateClockwise(state: RotateState): RotateState;
|
|
16
|
+
export declare function rotateCounterClockwise(state: RotateState): RotateState;
|
|
17
|
+
export declare function setFreeAngle(state: RotateState, angleDeg: number): RotateState;
|
|
18
|
+
export declare function isRotateNoOp(state: RotateState): boolean;
|
|
19
|
+
/** Effective rotation applied during bake, in degrees clockwise. */
|
|
20
|
+
export declare function effectiveAngleDeg(state: RotateState): number;
|
|
21
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/plugins/rotate/state.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,wBAAgB,kBAAkB,IAAI,WAAW,CAEhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAE/D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAEtE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAK9E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAExD;AAED,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ViewportController } from '../canvas/viewport-controller.js';
|
|
2
|
+
import type { EventBus } from '../events/event-bus.js';
|
|
3
|
+
import type { Store } from '../state/store.js';
|
|
4
|
+
/**
|
|
5
|
+
* Internal utility id taxonomy. Includes the ids Ghost enumerates in
|
|
6
|
+
* `options.utils` plus `'rotate'` and `'flip'`, which Kalotyp ships as
|
|
7
|
+
* separate utilities (Ghost's array is the set it wants exposed, not the
|
|
8
|
+
* upper bound on what the editor may render).
|
|
9
|
+
*/
|
|
10
|
+
export type UtilityId = 'crop' | 'rotate' | 'flip' | 'filter' | 'finetune' | 'redact' | 'annotate' | 'trim' | 'frame' | 'resize';
|
|
11
|
+
/** Normalised wrapper around an image inside the bake chain. `bitmap` is anything `drawImage` accepts. */
|
|
12
|
+
export interface SourceImage {
|
|
13
|
+
readonly bitmap: ImageBitmap | HTMLImageElement | HTMLCanvasElement | OffscreenCanvas;
|
|
14
|
+
readonly width: number;
|
|
15
|
+
readonly height: number;
|
|
16
|
+
readonly mimeType: string;
|
|
17
|
+
}
|
|
18
|
+
export interface UtilityHandle {
|
|
19
|
+
destroy(): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Editor → plugin / plugin → editor channel. `commit` signals a state
|
|
23
|
+
* change worth re-rendering; `announce` requests a polite-live-region
|
|
24
|
+
* announcement forwarded to the shell's screen-reader announcer.
|
|
25
|
+
*/
|
|
26
|
+
export type EditorEvents = {
|
|
27
|
+
commit: {
|
|
28
|
+
readonly utility: UtilityId;
|
|
29
|
+
};
|
|
30
|
+
announce: {
|
|
31
|
+
readonly message: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export interface UtilityContext {
|
|
35
|
+
readonly source: SourceImage;
|
|
36
|
+
readonly bus: EventBus<EditorEvents>;
|
|
37
|
+
/**
|
|
38
|
+
* Editor-level zoom + pan controller. Plugins read viewports via
|
|
39
|
+
* `viewport.computeViewport(stage, image)` and subscribe for repaint;
|
|
40
|
+
* the editor's gesture detector owns mutation.
|
|
41
|
+
*/
|
|
42
|
+
readonly viewport: ViewportController;
|
|
43
|
+
}
|
|
44
|
+
export interface UtilityPlugin<TState extends object> {
|
|
45
|
+
readonly id: UtilityId;
|
|
46
|
+
/** Synchronous default state for the plugin given the loaded image. */
|
|
47
|
+
init(ctx: UtilityContext): TState;
|
|
48
|
+
/**
|
|
49
|
+
* Mount the plugin's interactive UI under `host`. The returned handle's
|
|
50
|
+
* `destroy()` is called when the editor closes.
|
|
51
|
+
*/
|
|
52
|
+
mount(host: HTMLElement, ctx: UtilityContext, store: Store<TState>): UtilityHandle;
|
|
53
|
+
/**
|
|
54
|
+
* Apply this utility's transformation to the image and return the result.
|
|
55
|
+
* The chain runner feeds this output as the next utility's input.
|
|
56
|
+
*/
|
|
57
|
+
bake(state: TState, source: SourceImage): Promise<SourceImage>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=utility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utility.d.ts","sourceRoot":"","sources":["../../src/plugins/utility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,UAAU,GACV,MAAM,GACN,OAAO,GACP,QAAQ,CAAC;AAEb,0GAA0G;AAC1G,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,eAAe,CAAC;IACtF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;KAAE,CAAC;IACxC,QAAQ,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CACvC;AAED,MAAM,WAAW,aAAa,CAAC,MAAM,SAAS,MAAM;IAClD,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,uEAAuE;IACvE,IAAI,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAAC;IAClC;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;IACnF;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAChE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal observable store. Subscribers fire after every `set`/`update`;
|
|
3
|
+
* the store does no equality check — subscribers diff if they care.
|
|
4
|
+
*/
|
|
5
|
+
export type StoreListener<T> = (state: T, previous: T) => void;
|
|
6
|
+
export type Unsubscribe = () => void;
|
|
7
|
+
export interface Store<T> {
|
|
8
|
+
get(): T;
|
|
9
|
+
set(next: Partial<T>): void;
|
|
10
|
+
update(updater: (state: T) => Partial<T>): void;
|
|
11
|
+
subscribe(listener: StoreListener<T>): Unsubscribe;
|
|
12
|
+
}
|
|
13
|
+
export declare function createStore<T extends object>(initial: T): Store<T>;
|
|
14
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/state/store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;AAC/D,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,MAAM,WAAW,KAAK,CAAC,CAAC;IACtB,GAAG,IAAI,CAAC,CAAC;IACT,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CACpD;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAmClE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@magicpages/kalotyp-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-agnostic editor engine for Kalotyp — an open-source image editor for Ghost CMS.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Jannis Fedoruk-Betschki <jannis@magicpages.co>",
|
|
7
|
+
"homepage": "https://github.com/magicpages/kalotyp#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/magicpages/kalotyp.git",
|
|
11
|
+
"directory": "packages/core"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/magicpages/kalotyp/issues",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"ghost",
|
|
16
|
+
"image-editor",
|
|
17
|
+
"canvas",
|
|
18
|
+
"editor-engine"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"provenance": true
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
40
|
+
"dev": "vite build --watch",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"typecheck": "tsc --noEmit"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "5.6.3",
|
|
47
|
+
"vite": "5.4.10",
|
|
48
|
+
"vite-plugin-dts": "4.3.0",
|
|
49
|
+
"vitest": "2.1.5",
|
|
50
|
+
"jsdom": "25.0.1"
|
|
51
|
+
}
|
|
52
|
+
}
|