@bensitu/image-editor 1.2.0 → 1.2.2
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/LICENSE +20 -20
- package/README.md +220 -208
- package/dist/image-editor.esm.js +2566 -0
- package/dist/image-editor.esm.js.map +7 -0
- package/dist/image-editor.esm.min.js +3 -8
- package/dist/image-editor.esm.min.js.map +4 -4
- package/dist/image-editor.esm.min.mjs +9 -0
- package/dist/image-editor.esm.min.mjs.map +7 -0
- package/dist/image-editor.esm.mjs +2566 -0
- package/dist/image-editor.esm.mjs.map +7 -0
- package/dist/image-editor.js +2563 -0
- package/dist/image-editor.js.map +7 -0
- package/dist/image-editor.min.js +3 -8
- package/dist/image-editor.min.js.map +4 -4
- package/image-editor.d.ts +203 -0
- package/package.json +84 -71
- package/src/browser.js +11 -0
- package/src/esm.js +9 -0
- package/src/image-editor.js +1518 -804
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// image-editor.d.ts - TypeScript declarations for @bensitu/image-editor
|
|
2
|
+
|
|
3
|
+
declare module '@bensitu/image-editor' {
|
|
4
|
+
import { Canvas, Image as FabricImage, Object as FabricObject } from 'fabric';
|
|
5
|
+
|
|
6
|
+
export interface LabelOptions {
|
|
7
|
+
getText?: (mask: MaskObject, maskIndex: number) => string;
|
|
8
|
+
create?: (mask: MaskObject, fabric: any) => FabricObject;
|
|
9
|
+
textOptions?: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CropOptions {
|
|
13
|
+
minWidth?: number;
|
|
14
|
+
minHeight?: number;
|
|
15
|
+
padding?: number;
|
|
16
|
+
hideMasksDuringCrop?: boolean;
|
|
17
|
+
preserveMasksAfterCrop?: boolean;
|
|
18
|
+
allowRotationOfCropRect?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ImageEditorOptions {
|
|
22
|
+
canvasWidth?: number;
|
|
23
|
+
canvasHeight?: number;
|
|
24
|
+
backgroundColor?: string;
|
|
25
|
+
animationDuration?: number;
|
|
26
|
+
minScale?: number;
|
|
27
|
+
maxScale?: number;
|
|
28
|
+
scaleStep?: number;
|
|
29
|
+
rotationStep?: number;
|
|
30
|
+
|
|
31
|
+
expandCanvasToImage?: boolean;
|
|
32
|
+
fitImageToCanvas?: boolean;
|
|
33
|
+
coverImageToCanvas?: boolean;
|
|
34
|
+
|
|
35
|
+
downsampleOnLoad?: boolean;
|
|
36
|
+
downsampleMaxWidth?: number;
|
|
37
|
+
downsampleMaxHeight?: number;
|
|
38
|
+
downsampleQuality?: number;
|
|
39
|
+
|
|
40
|
+
exportMultiplier?: number;
|
|
41
|
+
exportImageAreaByDefault?: boolean;
|
|
42
|
+
|
|
43
|
+
defaultMaskWidth?: number;
|
|
44
|
+
defaultMaskHeight?: number;
|
|
45
|
+
maskRotatable?: boolean;
|
|
46
|
+
maskLabelOnSelect?: boolean;
|
|
47
|
+
maskLabelOffset?: number;
|
|
48
|
+
maskName?: string;
|
|
49
|
+
|
|
50
|
+
groupSelection?: boolean;
|
|
51
|
+
|
|
52
|
+
showPlaceholder?: boolean;
|
|
53
|
+
initialImageBase64?: string | null;
|
|
54
|
+
defaultDownloadFileName?: string;
|
|
55
|
+
|
|
56
|
+
label?: LabelOptions;
|
|
57
|
+
crop?: CropOptions;
|
|
58
|
+
|
|
59
|
+
onImageLoaded?: () => void;
|
|
60
|
+
onError?: (error: unknown, message: string) => void;
|
|
61
|
+
onWarning?: (error: unknown, message: string) => void;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface ElementIdMap {
|
|
65
|
+
canvas?: string;
|
|
66
|
+
canvasContainer?: string | null;
|
|
67
|
+
imgPlaceholder?: string;
|
|
68
|
+
scaleRate?: string;
|
|
69
|
+
rotationLeftInput?: string;
|
|
70
|
+
rotationRightInput?: string;
|
|
71
|
+
rotateLeftBtn?: string;
|
|
72
|
+
rotateRightBtn?: string;
|
|
73
|
+
addMaskBtn?: string;
|
|
74
|
+
removeMaskBtn?: string;
|
|
75
|
+
removeAllMasksBtn?: string;
|
|
76
|
+
mergeBtn?: string;
|
|
77
|
+
downloadBtn?: string;
|
|
78
|
+
maskList?: string;
|
|
79
|
+
zoomInBtn?: string;
|
|
80
|
+
zoomOutBtn?: string;
|
|
81
|
+
resetBtn?: string;
|
|
82
|
+
undoBtn?: string;
|
|
83
|
+
redoBtn?: string;
|
|
84
|
+
imageInput?: string;
|
|
85
|
+
uploadArea?: string;
|
|
86
|
+
cropBtn?: string;
|
|
87
|
+
applyCropBtn?: string;
|
|
88
|
+
cancelCropBtn?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface MaskConfig {
|
|
92
|
+
shape?: 'rect' | 'circle' | 'ellipse' | 'polygon' | string;
|
|
93
|
+
width?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
94
|
+
height?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
95
|
+
radius?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
96
|
+
rx?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
97
|
+
ry?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
98
|
+
points?: Array<{ x: number; y: number }>;
|
|
99
|
+
color?: string;
|
|
100
|
+
alpha?: number;
|
|
101
|
+
gap?: number;
|
|
102
|
+
left?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
103
|
+
top?: number | string | ((canvas: Canvas, options: ImageEditorOptions) => number);
|
|
104
|
+
angle?: number;
|
|
105
|
+
selectable?: boolean;
|
|
106
|
+
hasControls?: boolean;
|
|
107
|
+
borderColor?: string;
|
|
108
|
+
cornerColor?: string;
|
|
109
|
+
cornerSize?: number;
|
|
110
|
+
transparentCorners?: boolean;
|
|
111
|
+
strokeUniform?: boolean;
|
|
112
|
+
styles?: Record<string, any>;
|
|
113
|
+
fabricGenerator?: (config: MaskConfig, canvas: Canvas, options: ImageEditorOptions) => FabricObject;
|
|
114
|
+
onCreate?: (mask: MaskObject, canvas: Canvas) => void;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface MaskObject extends FabricObject {
|
|
118
|
+
maskId: number;
|
|
119
|
+
maskName: string;
|
|
120
|
+
originalAlpha: number;
|
|
121
|
+
__label?: FabricObject;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface Base64ExportOptions {
|
|
125
|
+
exportImageArea?: boolean;
|
|
126
|
+
multiplier?: number;
|
|
127
|
+
quality?: number;
|
|
128
|
+
fileType?: 'jpeg' | 'jpg' | 'png' | 'webp' | 'image/jpeg' | 'image/png' | 'image/webp';
|
|
129
|
+
format?: 'jpeg' | 'jpg' | 'png' | 'webp' | 'image/jpeg' | 'image/png' | 'image/webp';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface ImageFileExportOptions {
|
|
133
|
+
mergeMask?: boolean;
|
|
134
|
+
fileType?: 'jpeg' | 'jpg' | 'png' | 'webp' | 'image/jpeg' | 'image/png' | 'image/webp';
|
|
135
|
+
quality?: number;
|
|
136
|
+
multiplier?: number;
|
|
137
|
+
fileName?: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface RemoveAllMasksOptions {
|
|
141
|
+
saveHistory?: boolean;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export class ImageEditor {
|
|
145
|
+
readonly options: ImageEditorOptions;
|
|
146
|
+
readonly canvas: Canvas | null;
|
|
147
|
+
readonly canvasElement: HTMLCanvasElement | null;
|
|
148
|
+
readonly containerElement: HTMLElement | null;
|
|
149
|
+
readonly placeholderElement: HTMLElement | null;
|
|
150
|
+
/** @deprecated Use canvasElement instead. */
|
|
151
|
+
readonly canvasEl: HTMLCanvasElement | null;
|
|
152
|
+
/** @deprecated Use containerElement instead. */
|
|
153
|
+
readonly containerEl: HTMLElement | null;
|
|
154
|
+
/** @deprecated Use placeholderElement instead. */
|
|
155
|
+
readonly placeholderEl: HTMLElement | null;
|
|
156
|
+
readonly originalImage: FabricImage | null;
|
|
157
|
+
readonly currentScale: number;
|
|
158
|
+
readonly currentRotation: number;
|
|
159
|
+
readonly maskCounter: number;
|
|
160
|
+
readonly isAnimating: boolean;
|
|
161
|
+
readonly isImageLoadedToCanvas: boolean;
|
|
162
|
+
|
|
163
|
+
constructor(options?: ImageEditorOptions);
|
|
164
|
+
|
|
165
|
+
init(idMap?: ElementIdMap): void;
|
|
166
|
+
loadImage(imageBase64: string): Promise<void>;
|
|
167
|
+
isImageLoaded(): boolean;
|
|
168
|
+
|
|
169
|
+
scaleImage(factor: number): Promise<void>;
|
|
170
|
+
rotateImage(degrees: number): Promise<void>;
|
|
171
|
+
resetImageTransform(): Promise<void>;
|
|
172
|
+
/** @deprecated Use resetImageTransform() instead. */
|
|
173
|
+
reset(): Promise<void>;
|
|
174
|
+
|
|
175
|
+
createMask(config?: MaskConfig): MaskObject | null;
|
|
176
|
+
/** @deprecated Use createMask() instead. */
|
|
177
|
+
addMask(config?: MaskConfig): MaskObject | null;
|
|
178
|
+
removeSelectedMask(): void;
|
|
179
|
+
removeAllMasks(options?: RemoveAllMasksOptions): void;
|
|
180
|
+
|
|
181
|
+
mergeMasks(): Promise<void>;
|
|
182
|
+
/** @deprecated Use mergeMasks() instead. */
|
|
183
|
+
merge(): Promise<void>;
|
|
184
|
+
downloadImage(fileName?: string): void;
|
|
185
|
+
exportImageBase64(options?: Base64ExportOptions): Promise<string>;
|
|
186
|
+
/** @deprecated Use exportImageBase64() instead. */
|
|
187
|
+
getImageBase64(options?: Base64ExportOptions): Promise<string>;
|
|
188
|
+
exportImageFile(options?: ImageFileExportOptions): Promise<File>;
|
|
189
|
+
|
|
190
|
+
enterCropMode(): void;
|
|
191
|
+
cancelCrop(): void;
|
|
192
|
+
applyCrop(): Promise<void>;
|
|
193
|
+
|
|
194
|
+
undo(): Promise<void>;
|
|
195
|
+
redo(): Promise<void>;
|
|
196
|
+
saveState(): void;
|
|
197
|
+
loadFromState(jsonString: string | object): Promise<void>;
|
|
198
|
+
|
|
199
|
+
dispose(): void;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export default ImageEditor;
|
|
203
|
+
}
|
package/package.json
CHANGED
|
@@ -1,71 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@bensitu/image-editor",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "Lightweight canvas-based image editor",
|
|
5
|
-
"main": "dist/image-editor.js",
|
|
6
|
-
"module": "dist/image-editor.esm.
|
|
7
|
-
"types": "image-editor.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
},
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
},
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@bensitu/image-editor",
|
|
3
|
+
"version": "1.2.2",
|
|
4
|
+
"description": "Lightweight canvas-based image editor",
|
|
5
|
+
"main": "./dist/image-editor.js",
|
|
6
|
+
"module": "./dist/image-editor.esm.mjs",
|
|
7
|
+
"types": "./image-editor.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./image-editor.d.ts",
|
|
11
|
+
"import": "./dist/image-editor.esm.mjs",
|
|
12
|
+
"default": "./dist/image-editor.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"dev": "node esbuild.config.mjs --watch",
|
|
17
|
+
"build": "node esbuild.config.mjs",
|
|
18
|
+
"build:babel": "babel src --out-dir dist --copy-files",
|
|
19
|
+
"lint": "eslint src --ext .js",
|
|
20
|
+
"test": "npm run build && node --test tests/image-editor.test.mjs tests/package.test.mjs"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/bensitu/image-editor.git"
|
|
25
|
+
},
|
|
26
|
+
"author": "Ben Situ",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"src",
|
|
31
|
+
"image-editor.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"fabric": "^5.5.2"
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@babel/cli": "^7.22.9",
|
|
41
|
+
"@babel/core": "^7.22.9",
|
|
42
|
+
"@babel/preset-env": "^7.22.9",
|
|
43
|
+
"esbuild": "^0.19.12",
|
|
44
|
+
"esbuild-plugin-babel": "^0.2.3",
|
|
45
|
+
"eslint": "^8.49.0"
|
|
46
|
+
},
|
|
47
|
+
"browserslist": [
|
|
48
|
+
"Chrome >= 100",
|
|
49
|
+
"Firefox >= 100",
|
|
50
|
+
"Safari >= 15",
|
|
51
|
+
"Edge >= 100"
|
|
52
|
+
],
|
|
53
|
+
"keywords": [
|
|
54
|
+
"fabricjs",
|
|
55
|
+
"image-editor",
|
|
56
|
+
"javascript",
|
|
57
|
+
"mask",
|
|
58
|
+
"open-source"
|
|
59
|
+
],
|
|
60
|
+
"directories": {
|
|
61
|
+
"doc": "docs"
|
|
62
|
+
},
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://github.com/bensitu/image-editor/issues"
|
|
65
|
+
},
|
|
66
|
+
"homepage": "https://github.com/bensitu/image-editor#readme",
|
|
67
|
+
"babel": {
|
|
68
|
+
"presets": [
|
|
69
|
+
[
|
|
70
|
+
"@babel/preset-env",
|
|
71
|
+
{
|
|
72
|
+
"targets": {
|
|
73
|
+
"chrome": "100",
|
|
74
|
+
"firefox": "100",
|
|
75
|
+
"safari": "15",
|
|
76
|
+
"edge": "100"
|
|
77
|
+
},
|
|
78
|
+
"useBuiltIns": false,
|
|
79
|
+
"modules": false
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
}
|
package/src/browser.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import ImageEditor, { setFabric } from './image-editor.js';
|
|
2
|
+
|
|
3
|
+
const scope = typeof globalThis !== 'undefined'
|
|
4
|
+
? globalThis
|
|
5
|
+
: (typeof self !== 'undefined' ? self : (typeof window !== 'undefined' ? window : null));
|
|
6
|
+
|
|
7
|
+
setFabric(scope && scope.fabric);
|
|
8
|
+
|
|
9
|
+
if (scope) {
|
|
10
|
+
scope.ImageEditor = ImageEditor;
|
|
11
|
+
}
|
package/src/esm.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import fabricModule from 'fabric';
|
|
2
|
+
import ImageEditor, { setFabric } from './image-editor.js';
|
|
3
|
+
|
|
4
|
+
const fabricInstance = fabricModule && (fabricModule.fabric || fabricModule.default || fabricModule);
|
|
5
|
+
|
|
6
|
+
setFabric(fabricInstance);
|
|
7
|
+
|
|
8
|
+
export { ImageEditor };
|
|
9
|
+
export default ImageEditor;
|