@bensitu/image-editor 1.1.2 → 1.2.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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Ben Situ
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ben Situ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,207 +1,234 @@
1
- # ImageEditor
2
- [![npm](https://img.shields.io/npm/l/image-editor.svg)](https://github.com/bensitu/image-editor)
3
- [![npm](https://img.shields.io/npm/v/@bensitu/image-editor.svg)](https://www.npmjs.com/package/@bensitu/image-editor)
4
- [![](https://data.jsdelivr.com/v1/package/npm/@bensitu/image-editor/badge)](https://www.jsdelivr.com/package/npm/@bensitu/image-editor)
5
-
6
- A lightweight JavaScript wrapper around fabric.js that provides comprehensive image editing capabilities including loading, zooming, rotation, and mask management.
7
-
8
- ## Overview
9
-
10
- ImageEditor offers:
11
-
12
- - Image loading from base64 or file input
13
- - Zoom in/out and reset scale functionality
14
- - Rotation (with custom degrees or step-based)
15
- - Mask creation, selection, and removal
16
- - Optional mask labels
17
- - Merge/export helpers
18
- - Basic UI element binding
19
-
20
- **Note**: This library requires fabric.js v5.x to be loaded before instantiating the editor.
21
-
22
- ## Demo
23
-
24
- [https://bensitu.github.io/image-editor/](https://bensitu.github.io/image-editor/)
25
-
26
- ## Features
27
-
28
- - **Fabric.js-powered canvas** - Built on top of the robust fabric.js library
29
- - **Image scaling** - Configurable min/max limits with smooth animation
30
- - **Image rotation** - Step control and animated transitions
31
- - **Auto-resizing** - Optional canvas resizing to match image or container size
32
- - **Image crop** - Enter a crop mode to crop image
33
- - **Mask management** - Add, remove, remove all, with draggable/resizable masks
34
- - **Mask labels** - Auto-sync with mask movement/scaling
35
- - **Performance optimization** - Downsampling on load to prevent large image performance issues
36
- - **Export & Download** - Base64 output or direct file save support
37
- - **DOM/UI binding** - Easy integration with buttons, inputs, and placeholders
38
-
39
- ## Installation
40
-
41
- Include fabric.js and the ImageEditor class script in your HTML:
42
-
43
- ```html
44
- <!-- Fabric.js (required) -->
45
- <script src="https://cdn.jsdelivr.net/npm/fabric@5.5.2/dist/fabric.min.js"></script>
46
-
47
- <!-- ImageEditor -->
48
- <script src="path/to/ImageEditor.js"></script>
49
- <!-- or -->
50
- <script src="https://cdn.jsdelivr.net/npm/@bensitu/image-editor/dist/image-editor.min.js"></script>
51
- ```
52
-
53
- ## Quick Start
54
-
55
- ### HTML Structure
56
-
57
- ```html
58
- <!-- Canvas -->
59
- <canvas id="fabricCanvas"></canvas>
60
-
61
- <!-- Optional Controls -->
62
- <button id="zoomInBtn">Zoom In</button>
63
- <button id="zoomOutBtn">Zoom Out</button>
64
- <button id="rotateLeftBtn">Rotate Left</button>
65
- <input id="rotationLeftInput" type="number" value="90">
66
- <button id="rotateRightBtn">Rotate Right</button>
67
- <input id="rotationRightInput" type="number" value="90">
68
-
69
- <button id="addMaskBtn">Add Mask</button>
70
- <button id="removeMaskBtn">Remove Mask</button>
71
-
72
- <button id="mergeBtn">Merge</button>
73
- <button id="downloadBtn">Download</button>
74
-
75
- <input id="imageInput" type="file" accept="image/*">
76
- ```
77
-
78
- ### JavaScript Implementation
79
-
80
- ```javascript
81
- // Create instance
82
- const editor = new ImageEditor({
83
- canvasWidth: 800,
84
- canvasHeight: 600,
85
- backgroundColor: '#ffffff',
86
- initialImageBase64: null // optional
87
- });
88
-
89
- // Initialize (binds to DOM elements)
90
- editor.init({
91
- canvas: 'fabricCanvas',
92
- zoomInBtn: 'zoomInBtn',
93
- zoomOutBtn: 'zoomOutBtn',
94
- rotateLeftBtn: 'rotateLeftBtn',
95
- rotationLeftInput: 'rotationLeftInput',
96
- rotateRightBtn: 'rotateRightBtn',
97
- rotationRightInput: 'rotationRightInput',
98
- addMaskBtn: 'addMaskBtn',
99
- mergeBtn: 'mergeBtn',
100
- downloadBtn: 'downloadBtn',
101
- imageInput: 'imageInput'
102
- });
103
-
104
- // Load an image manually (base64 string)
105
- // editor.loadImage('data:image/jpeg;base64,...');
106
- ```
107
-
108
- ## Configuration Options
109
-
110
- When creating the editor instance, you can pass an options object to override defaults:
111
-
112
- | Option | Default | Description |
113
- |--------|---------|-------------|
114
- | `canvasWidth` | `800` | Initial canvas width (px) |
115
- | `canvasHeight` | `600` | Initial canvas height (px) |
116
- | `backgroundColor` | `#ffffff` | Canvas background color |
117
- | `animationDuration` | `300` | Animation duration for scale/rotation (ms) |
118
- | `minScale` | `0.1` | Minimum scale factor |
119
- | `maxScale` | `5.0` | Maximum scale factor |
120
- | `scaleStep` | `0.05` | Scale step for zoom buttons |
121
- | `rotationStep` | `90` | Default rotation step in degrees |
122
- | `expandCanvasToImage` | `true` | Expand canvas to image size on load |
123
- | `fitImageToCanvas` | `false` | Fit image to current canvas size |
124
- | `downsampleOnLoad` | `true` | Downsample large images before rendering |
125
- | `downsampleMaxWidth` | `4000` | Max width count before downsampling |
126
- | `downsampleMaxHeight` | `3000` | Max height count before downsampling |
127
- | `downsampleQuality` | `0.92` | JPEG quality when downsampling |
128
- | `exportMultiplier` | `1` | Scale factor for export |
129
- | `exportImageAreaByDefault` | `true` | Export only the image area (clipped to masks) |
130
- | `defaultMaskWidth` | `50` | Default mask width (px) |
131
- | `defaultMaskHeight` | `80` | Default mask height (px) |
132
- | `maskRotatable` | `false` | Whether masks can be rotated |
133
- | `maskLabelOnSelect` | `true` | Show label when mask is selected |
134
- | `maskLabelOffset` | `3` | Offset for mask labels from top-left corner |
135
- | `maskName` | `mask` | Prefix for mask names/labels |
136
- | `showPlaceholder` | `true` | Shows placeholder when no image is loaded |
137
- | `initialImageBase64` | `null` | Base64 string to auto-load as initial image |
138
- | `defaultDownloadFileName` | `edited_image.jpg` | Default file name for downloads |
139
-
140
- ## API Methods
141
-
142
- | Method | Description |
143
- |--------|-------------|
144
- | `init(idMap)` | Bind the editor to DOM elements. Pass IDs in an object (optional). |
145
- | `loadImage(base64)` | Load an image from a base64 data string. |
146
- | `scaleImage(factor)` | Scale image to the given factor (relative to base scale). |
147
- | `rotateImage(degrees)` | Rotate image to the given angle in degrees. |
148
- | `reset()` | Reset scale to 1 and rotation to 0. |
149
- | `undo()` | Undo the last state change. |
150
- | `redo()` | Redo the next state change. |
151
- | `addMask(config)` | Add a mask to the canvas. Config can include width, height, color. |
152
- | `removeSelectedMask()` | Remove the currently selected mask. |
153
- | `removeAllMasks()` | Remove all masks from the canvas. |
154
- | `enterCropMode()` | Create a resizable/movable selection rect on top of the image. |
155
- | `cancelCrop()` | Cancel crop mode and remove the temporary selection rect. |
156
- | `applyCrop()` | Apply the current crop rectangle in the canvas. |
157
- | `merge()` | Merge masks with the base image in the canvas. |
158
- | `downloadImage()` | Download the merged image as a file. |
159
- | `exportImageFile(options)` | Exports the current canvas (with or without masks) as a `File` object. |
160
-
161
- ## Example Workflow
162
-
163
- 1. **Load an image** - Via file input or base64 string
164
- 2. **Adjust positioning** - Zoom in/out or rotate as needed
165
- 3. **Add masks** - Highlight or cover specific areas (drag, resize)
166
- 4. **Merge result** - Create a flattened export (optional)
167
- 5. **Download / export** - Save the final image
168
-
169
- ## Installing
170
-
171
- ### npm / pnpm / yarn
172
- ```bash
173
- npm i @bensitu/image-editor fabric
174
- # or
175
- pnpm add @bensitu/image-editor fabric
176
- # or
177
- yarn add @bensitu/image-editor fabric
178
- ```
179
-
180
- ### Local build
181
- ```bash
182
- npm run build
183
- ```
184
-
185
- ### Load UMD js file:
186
- You can download image-editor from the dist folder.
187
-
188
- ## Browser Support
189
-
190
- * Chrome 100+
191
- * Firefox 100+
192
- * Safari 15+
193
- * Edge 100+
194
-
195
- The class uses modern DOM & ES2022 features (optional chaining, class, async/await).
196
-
197
- If you need IE11 or old mobile Safari you will have to transpile.
198
-
199
- ## Dependencies
200
-
201
- - **fabric.js v5.x** — Must be loaded before ImageEditor
202
-
203
- ## License
204
-
205
- MIT © 2026 Ben Situ
206
-
207
- Fabric.js is licensed under its own MIT license.
1
+ # ImageEditor
2
+ [![npm](https://img.shields.io/npm/l/image-editor.svg)](https://github.com/bensitu/image-editor)
3
+ [![npm](https://img.shields.io/npm/v/@bensitu/image-editor.svg)](https://www.npmjs.com/package/@bensitu/image-editor)
4
+ [![](https://data.jsdelivr.com/v1/package/npm/@bensitu/image-editor/badge)](https://www.jsdelivr.com/package/npm/@bensitu/image-editor)
5
+
6
+ A lightweight JavaScript wrapper around fabric.js that provides comprehensive image editing capabilities including loading, zooming, rotation, and mask management.
7
+
8
+ ## Overview
9
+
10
+ ImageEditor offers:
11
+
12
+ - Image loading from base64 or file input
13
+ - Zoom in/out and reset scale functionality
14
+ - Rotation (with custom degrees or step-based)
15
+ - Mask creation, selection, and removal
16
+ - Optional mask labels
17
+ - Merge/export helpers
18
+ - Basic UI element binding
19
+
20
+ **Note**: This library requires fabric.js v5.x to be loaded before instantiating the editor.
21
+
22
+ ## Demo
23
+
24
+ [https://bensitu.github.io/image-editor/](https://bensitu.github.io/image-editor/)
25
+
26
+ ## Features
27
+
28
+ - **Fabric.js-powered canvas** - Built on top of the robust fabric.js library
29
+ - **Image scaling** - Configurable min/max limits with smooth animation
30
+ - **Image rotation** - Step control and animated transitions
31
+ - **Auto-resizing** - Optional canvas resizing to match image or container size
32
+ - **Image crop** - Enter a crop mode to crop image
33
+ - **Mask management** - Add, remove, remove all, with draggable/resizable masks
34
+ - **Mask labels** - Auto-sync with mask movement/scaling
35
+ - **Performance optimization** - Downsampling on load to prevent large image performance issues
36
+ - **Export & Download** - Base64 output or direct file save support
37
+ - **DOM/UI binding** - Easy integration with buttons, inputs, and placeholders
38
+
39
+ ## Installation
40
+
41
+ Include fabric.js and the ImageEditor class script in your HTML:
42
+
43
+ ```html
44
+ <!-- Fabric.js (required) -->
45
+ <script src="https://cdn.jsdelivr.net/npm/fabric@5.5.2/dist/fabric.min.js"></script>
46
+
47
+ <!-- ImageEditor -->
48
+ <script src="path/to/dist/image-editor.min.js"></script>
49
+ <!-- or -->
50
+ <script src="https://cdn.jsdelivr.net/npm/@bensitu/image-editor/dist/image-editor.min.js"></script>
51
+ ```
52
+
53
+ For ESM/bundler usage:
54
+
55
+ ```javascript
56
+ import ImageEditor, { ImageEditor as NamedImageEditor } from '@bensitu/image-editor';
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ ### HTML Structure
62
+
63
+ ```html
64
+ <!-- Canvas -->
65
+ <canvas id="fabricCanvas"></canvas>
66
+
67
+ <!-- Optional Controls -->
68
+ <button id="zoomInBtn">Zoom In</button>
69
+ <button id="zoomOutBtn">Zoom Out</button>
70
+ <button id="rotateLeftBtn">Rotate Left</button>
71
+ <input id="rotationLeftInput" type="number" value="90">
72
+ <button id="rotateRightBtn">Rotate Right</button>
73
+ <input id="rotationRightInput" type="number" value="90">
74
+
75
+ <button id="addMaskBtn">Add Mask</button>
76
+ <button id="removeMaskBtn">Remove Mask</button>
77
+
78
+ <button id="mergeBtn">Merge</button>
79
+ <button id="downloadBtn">Download</button>
80
+
81
+ <input id="imageInput" type="file" accept="image/*">
82
+ ```
83
+
84
+ ### JavaScript Implementation
85
+
86
+ ```javascript
87
+ // Create instance
88
+ const editor = new ImageEditor({
89
+ canvasWidth: 800,
90
+ canvasHeight: 600,
91
+ backgroundColor: '#ffffff',
92
+ initialImageBase64: null // optional
93
+ });
94
+
95
+ // Initialize (binds to DOM elements)
96
+ editor.init({
97
+ canvas: 'fabricCanvas',
98
+ zoomInBtn: 'zoomInBtn',
99
+ zoomOutBtn: 'zoomOutBtn',
100
+ rotateLeftBtn: 'rotateLeftBtn',
101
+ rotationLeftInput: 'rotationLeftInput',
102
+ rotateRightBtn: 'rotateRightBtn',
103
+ rotationRightInput: 'rotationRightInput',
104
+ addMaskBtn: 'addMaskBtn',
105
+ mergeBtn: 'mergeBtn',
106
+ downloadBtn: 'downloadBtn',
107
+ imageInput: 'imageInput'
108
+ });
109
+
110
+ // Load an image manually (base64 string)
111
+ // editor.loadImage('data:image/jpeg;base64,...');
112
+ ```
113
+
114
+ ## Configuration Options
115
+
116
+ When creating the editor instance, you can pass an options object to override defaults:
117
+
118
+ | Option | Default | Description |
119
+ |--------|---------|-------------|
120
+ | `canvasWidth` | `800` | Initial canvas width (px) |
121
+ | `canvasHeight` | `600` | Initial canvas height (px) |
122
+ | `backgroundColor` | `transparent` | Canvas background color |
123
+ | `animationDuration` | `300` | Animation duration for scale/rotation (ms) |
124
+ | `minScale` | `0.1` | Minimum scale factor |
125
+ | `maxScale` | `5.0` | Maximum scale factor |
126
+ | `scaleStep` | `0.05` | Scale step for zoom buttons |
127
+ | `rotationStep` | `90` | Default rotation step in degrees |
128
+ | `expandCanvasToImage` | `true` | Expand canvas to image size on load |
129
+ | `fitImageToCanvas` | `false` | Fit image to current canvas size |
130
+ | `coverImageToCanvas` | `false` | Fit image to cover canvas (at least one side fits, allowing overflow). |
131
+ | `downsampleOnLoad` | `true` | Downsample large images before rendering |
132
+ | `downsampleMaxWidth` | `4000` | Max width count before downsampling |
133
+ | `downsampleMaxHeight` | `3000` | Max height count before downsampling |
134
+ | `downsampleQuality` | `0.92` | JPEG quality when downsampling |
135
+ | `exportMultiplier` | `1` | Scale factor for export |
136
+ | `exportImageAreaByDefault` | `true` | Export only the image area (clipped to masks) |
137
+ | `defaultMaskWidth` | `50` | Default mask width (px) |
138
+ | `defaultMaskHeight` | `80` | Default mask height (px) |
139
+ | `maskRotatable` | `false` | Whether masks can be rotated |
140
+ | `maskLabelOnSelect` | `true` | Show label when mask is selected |
141
+ | `maskLabelOffset` | `3` | Offset for mask labels from top-left corner |
142
+ | `maskName` | `mask` | Prefix for mask names/labels |
143
+ | `showPlaceholder` | `true` | Shows placeholder when no image is loaded |
144
+ | `initialImageBase64` | `null` | Base64 string to auto-load as initial image |
145
+ | `defaultDownloadFileName` | `edited_image.jpg` | Default file name for downloads |
146
+ | `crop.preserveMasksAfterCrop` | `false` | Applying crop removes unmerged masks. Merge masks first if they should be baked into the cropped image. |
147
+
148
+ ## API Methods
149
+
150
+ | Method | Description |
151
+ |--------|-------------|
152
+ | `init(idMap)` | Bind the editor to DOM elements. Pass IDs in an object (optional). |
153
+ | `loadImage(base64)` | Load an image from a base64 data string. Resolves after the Fabric image is on the canvas. |
154
+ | `scaleImage(factor)` | Scale image to the given factor (relative to base scale). |
155
+ | `rotateImage(degrees)` | Rotate image to the given angle in degrees. |
156
+ | `reset()` | Reset scale to 1 and rotation to 0. |
157
+ | `undo()` | Undo the last state change. |
158
+ | `redo()` | Redo the next state change. |
159
+ | `addMask(config)` | Add a mask to the canvas. Config can include width, height, color. |
160
+ | `removeSelectedMask()` | Remove the currently selected mask. |
161
+ | `removeAllMasks()` | Remove all masks from the canvas. |
162
+ | `enterCropMode()` | Create a resizable/movable selection rect on top of the image. |
163
+ | `cancelCrop()` | Cancel crop mode and remove the temporary selection rect. |
164
+ | `applyCrop()` | Apply the current crop rectangle in the canvas. |
165
+ | `merge()` | Merge masks with the base image in the canvas. |
166
+ | `downloadImage()` | Download the merged image as a file. |
167
+ | `exportImageFile(options)` | Exports the current canvas (with or without masks) as a `File` object. |
168
+
169
+ Applying crop removes unmerged masks. Use `merge()` before cropping when masks should become part of the image pixels.
170
+
171
+ ## Example Workflow
172
+
173
+ 1. **Load an image** - Via file input or base64 string
174
+ 2. **Adjust positioning** - Zoom in/out or rotate as needed
175
+ 3. **Add masks** - Highlight or cover specific areas (drag, resize)
176
+ 4. **Merge result** - Create a flattened export (optional)
177
+ 5. **Download / export** - Save the final image
178
+
179
+ ## Installing
180
+
181
+ ### npm / pnpm / yarn
182
+ ```bash
183
+ npm i @bensitu/image-editor fabric
184
+ # or
185
+ pnpm add @bensitu/image-editor fabric
186
+ # or
187
+ yarn add @bensitu/image-editor fabric
188
+ ```
189
+
190
+ ### Local build
191
+ ```bash
192
+ npm run build
193
+ ```
194
+
195
+ ### Load UMD js file:
196
+ Use `dist/image-editor.js` or `dist/image-editor.min.js` for browser global script usage. Use `dist/image-editor.esm.mjs` or `dist/image-editor.esm.min.mjs` for standards-compliant ESM imports. Matching `.js` ESM builds are also generated for browser and bundler compatibility.
197
+
198
+ ## Browser Support
199
+
200
+ * Chrome 100+
201
+ * Firefox 100+
202
+ * Safari 15+
203
+ * Edge 100+
204
+
205
+ The package build targets these modern browsers and uses modern DOM and JavaScript features.
206
+
207
+ IE11 and old mobile Safari are not supported by the distributed build. If you need them, transpile the package and provide any required DOM or JavaScript polyfills in your application.
208
+
209
+ ## Automated npm Publishing
210
+
211
+ This repository publishes to npm through GitHub Actions when a matching version tag is pushed. The workflow uses npm Trusted Publishing with GitHub Actions OIDC, so no long-lived npm token is required.
212
+
213
+ Setup:
214
+
215
+ 1. Configure npm Trusted Publishing for this repository and the `publish-npm.yml` workflow.
216
+ 2. Commit the version bump, changelog, source, and generated `dist/` files.
217
+ 3. Push a tag that matches the package version:
218
+
219
+ ```bash
220
+ git tag v<package-version>
221
+ git push origin v<package-version>
222
+ ```
223
+
224
+ The workflow validates the tag, runs checks, verifies package contents, and publishes to npm.
225
+
226
+ ## Dependencies
227
+
228
+ - **fabric.js v5.x** — Must be loaded before ImageEditor
229
+
230
+ ## License
231
+
232
+ MIT © 2026 Ben Situ
233
+
234
+ Fabric.js is licensed under its own MIT license.