senangwebs-photobooth 1.0.1 → 2.0.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.
Files changed (44) hide show
  1. package/README.md +219 -235
  2. package/dist/swp.css +884 -344
  3. package/dist/swp.js +1 -1
  4. package/examples/data-attribute.html +69 -0
  5. package/examples/index.html +56 -51
  6. package/examples/studio.html +83 -0
  7. package/package.json +12 -5
  8. package/src/css/swp.css +884 -344
  9. package/src/js/core/Canvas.js +398 -0
  10. package/src/js/core/EventEmitter.js +188 -0
  11. package/src/js/core/History.js +250 -0
  12. package/src/js/core/Keyboard.js +323 -0
  13. package/src/js/filters/FilterManager.js +248 -0
  14. package/src/js/index.js +48 -0
  15. package/src/js/io/Clipboard.js +52 -0
  16. package/src/js/io/FileManager.js +150 -0
  17. package/src/js/layers/BlendModes.js +342 -0
  18. package/src/js/layers/Layer.js +415 -0
  19. package/src/js/layers/LayerManager.js +459 -0
  20. package/src/js/selection/Selection.js +167 -0
  21. package/src/js/swp.js +297 -709
  22. package/src/js/tools/BaseTool.js +264 -0
  23. package/src/js/tools/BrushTool.js +314 -0
  24. package/src/js/tools/CropTool.js +400 -0
  25. package/src/js/tools/EraserTool.js +155 -0
  26. package/src/js/tools/EyedropperTool.js +184 -0
  27. package/src/js/tools/FillTool.js +109 -0
  28. package/src/js/tools/GradientTool.js +141 -0
  29. package/src/js/tools/HandTool.js +51 -0
  30. package/src/js/tools/MarqueeTool.js +103 -0
  31. package/src/js/tools/MoveTool.js +465 -0
  32. package/src/js/tools/ShapeTool.js +285 -0
  33. package/src/js/tools/TextTool.js +253 -0
  34. package/src/js/tools/ToolManager.js +277 -0
  35. package/src/js/tools/ZoomTool.js +68 -0
  36. package/src/js/ui/ColorManager.js +71 -0
  37. package/src/js/ui/UI.js +1211 -0
  38. package/swp_preview1.png +0 -0
  39. package/swp_preview2.png +0 -0
  40. package/webpack.config.js +4 -11
  41. package/dist/styles.js +0 -1
  42. package/examples/customization.html +0 -360
  43. package/spec.md +0 -239
  44. package/swp_preview.png +0 -0
Binary file
Binary file
package/webpack.config.js CHANGED
@@ -2,12 +2,9 @@ const path = require('path');
2
2
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3
3
 
4
4
  module.exports = {
5
- entry: {
6
- swp: './src/js/swp.js',
7
- styles: './src/css/swp.css'
8
- },
5
+ entry: './src/js/swp.js',
9
6
  output: {
10
- filename: '[name].js',
7
+ filename: 'swp.js',
11
8
  path: path.resolve(__dirname, 'dist'),
12
9
  library: {
13
10
  name: 'SWP',
@@ -21,9 +18,7 @@ module.exports = {
21
18
  {
22
19
  test: /\.js$/,
23
20
  exclude: /node_modules/,
24
- use: {
25
- loader: 'babel-loader'
26
- }
21
+ use: { loader: 'babel-loader' }
27
22
  },
28
23
  {
29
24
  test: /\.css$/,
@@ -32,8 +27,6 @@ module.exports = {
32
27
  ]
33
28
  },
34
29
  plugins: [
35
- new MiniCssExtractPlugin({
36
- filename: 'swp.css'
37
- })
30
+ new MiniCssExtractPlugin({ filename: 'swp.css' })
38
31
  ]
39
32
  };
package/dist/styles.js DELETED
@@ -1 +0,0 @@
1
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SWP=t():e.SWP=t()}(this,()=>(()=>{"use strict";var e={};return e.default})());
@@ -1,360 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>SWP - Customization Examples</title>
7
-
8
- <!-- Tailwind CSS -->
9
- <script src="https://cdn.tailwindcss.com"></script>
10
-
11
- <!-- SWP Library -->
12
- <link rel="stylesheet" href="../dist/swp.css" />
13
-
14
- <style>
15
- .example-section {
16
- margin-bottom: 40px;
17
- padding: 30px;
18
- background: white;
19
- border-radius: 12px;
20
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
21
- }
22
- .example-title {
23
- font-size: 20px;
24
- font-weight: 600;
25
- color: #333;
26
- margin-bottom: 10px;
27
- }
28
- .example-desc {
29
- font-size: 14px;
30
- color: #666;
31
- margin-bottom: 20px;
32
- }
33
- .code-block {
34
- background: #f7fafc;
35
- border: 1px solid #e2e8f0;
36
- border-radius: 6px;
37
- padding: 15px;
38
- font-family: "Courier New", monospace;
39
- font-size: 13px;
40
- overflow-x: auto;
41
- margin-bottom: 20px;
42
- }
43
- </style>
44
- </head>
45
- <body class="bg-gray-100 py-8">
46
- <div class="max-w-7xl mx-auto px-4">
47
- <!-- Header -->
48
- <div class="text-center mb-8">
49
- <h1 class="text-4xl font-bold text-gray-800 mb-2">
50
- SWP Customization Examples
51
- </h1>
52
- <p class="text-gray-600">
53
- Explore different ways to customize the photo editor UI
54
- </p>
55
- </div>
56
-
57
- <!-- Example 1: Default (Icons + Labels) -->
58
- <div class="example-section">
59
- <div class="example-title">
60
- 1. Default Configuration (Icons + Labels)
61
- </div>
62
- <div class="example-desc">
63
- Shows both icons and labels for all tools
64
- </div>
65
- <div class="code-block">
66
- <pre>
67
- const swp1 = new SWP(document.getElementById('editor1'), {
68
- width: 800,
69
- height: 500
70
- });</pre
71
- >
72
- </div>
73
- <div id="editor1"></div>
74
- </div>
75
-
76
- <!-- Example 2: Icons Only -->
77
- <div class="example-section">
78
- <div class="example-title">2. Icons Only (Compact View)</div>
79
- <div class="example-desc">
80
- Hides all labels, shows only icons with tooltips
81
- </div>
82
- <div class="code-block">
83
- <pre>
84
- const swp2 = new SWP(document.getElementById('editor2'), {
85
- width: 800,
86
- height: 500,
87
- showLabels: false // Hide all labels
88
- });</pre
89
- >
90
- </div>
91
- <div id="editor2"></div>
92
- </div>
93
-
94
- <!-- Example 3: Labels Only -->
95
- <div class="example-section">
96
- <div class="example-title">3. Labels Only (Text-based)</div>
97
- <div class="example-desc">Hides all icons, shows only text labels</div>
98
- <div class="code-block">
99
- <pre>
100
- const swp3 = new SWP(document.getElementById('editor3'), {
101
- width: 800,
102
- height: 500,
103
- showIcons: false // Hide all icons
104
- labels: {
105
- upload: 'Upload',
106
- rotateLeft: 'Rotate Left',
107
- rotateRight: 'Rotate Right',
108
- flipH: 'Flip Horiz...',
109
- flipV: 'Flip Verti...',
110
- resize: 'Resize',
111
- adjust: 'Adjust',
112
- filters: 'Filters',
113
- reset: 'Reset',
114
- save: 'Save'
115
- }
116
- });</pre
117
- >
118
- </div>
119
- <div id="editor3"></div>
120
- </div>
121
-
122
- <!-- Example 4: Custom Labels -->
123
- <div class="example-section">
124
- <div class="example-title">4. Custom Labels (Multilingual)</div>
125
- <div class="example-desc">
126
- Customize button labels for different languages or preferences
127
- </div>
128
- <div class="code-block">
129
- <pre>
130
- const swp4 = new SWP(document.getElementById('editor4'), {
131
- width: 800,
132
- height: 500,
133
- labels: {
134
- upload: 'Télécharger', // French
135
- resize: 'Redimensionner',
136
- adjust: 'Ajuster',
137
- filters: 'Filtres',
138
- reset: 'Réinitialiser',
139
- save: 'Enregistrer'
140
- }
141
- });</pre
142
- >
143
- </div>
144
- <div id="editor4"></div>
145
- </div>
146
-
147
- <!-- Example 5: Selective Labels -->
148
- <div class="example-section">
149
- <div class="example-title">
150
- 5. Selective Labels (Icons Only for Rotate/Flip)
151
- </div>
152
- <div class="example-desc">
153
- Hide labels for specific tools by setting them to null
154
- </div>
155
- <div class="code-block">
156
- <pre>
157
- const swp5 = new SWP(document.getElementById('editor5'), {
158
- width: 800,
159
- height: 500,
160
- labels: {
161
- rotateLeft: null, // No label for rotate left
162
- rotateRight: null, // No label for rotate right
163
- flipH: null, // No label for flip horizontal
164
- flipV: null // No label for flip vertical
165
- }
166
- });</pre
167
- >
168
- </div>
169
- <div id="editor5"></div>
170
- </div>
171
-
172
- <!-- Example 6: Creative Labels -->
173
- <div class="example-section">
174
- <div class="example-title">6. Creative Custom Labels</div>
175
- <div class="example-desc">Use creative or branded terminology</div>
176
- <div class="code-block">
177
- <pre>
178
- const swp6 = new SWP(document.getElementById('editor6'), {
179
- width: 800,
180
- height: 500,
181
- showIcons: false,
182
- labels: {
183
- upload: '📸',
184
- rotateLeft: '↩️',
185
- rotateRight: '↪️',
186
- flipH: '↔️',
187
- flipV: '↕️',
188
- resize: '📏',
189
- adjust: '🎨',
190
- filters: '✨',
191
- reset: '🔄',
192
- save: '💾'
193
- }
194
- });</pre
195
- >
196
- </div>
197
- <div id="editor6"></div>
198
- </div>
199
-
200
- <!-- Example 7: Minimal UI -->
201
- <div class="example-section">
202
- <div class="example-title">
203
- 7. Minimal UI (Icons Only + Selected Labels)
204
- </div>
205
- <div class="example-desc">
206
- Combine showLabels: false with custom labels for specific buttons
207
- </div>
208
- <div class="code-block">
209
- <pre>
210
- const swp7 = new SWP(document.getElementById('editor7'), {
211
- width: 800,
212
- height: 500,
213
- showIcons: false,
214
- labels: {
215
- upload: null,
216
- rotateLeft: null,
217
- rotateRight: null,
218
- flipH: null,
219
- flipV: null,
220
- resize: null,
221
- adjust: null,
222
- filters: null,
223
- reset: null,
224
- save: 'Save' // Only show Save label
225
- }
226
- });</pre
227
- >
228
- </div>
229
- <div id="editor7"></div>
230
- </div>
231
-
232
- <!-- Footer -->
233
- <div class="text-center mt-12 text-gray-600 text-sm">
234
- <p>
235
- SenangWebs Photobooth v1.0.0 |
236
- <a href="index.html" class="text-blue-600 hover:underline"
237
- >Back to Main Example</a
238
- >
239
- </p>
240
- </div>
241
- </div>
242
-
243
- <!-- SWP Library Script -->
244
- <script src="../dist/swp.js"></script>
245
-
246
- <!-- Initialize Examples -->
247
- <script>
248
- // Example 1: Default
249
- const swp1 = new SWP(document.getElementById("editor1"), {
250
- width: 800,
251
- height: 500,
252
- });
253
-
254
- // Example 2: Icons Only
255
- const swp2 = new SWP(document.getElementById("editor2"), {
256
- width: 800,
257
- height: 500,
258
- showLabels: false,
259
- });
260
-
261
- // Example 3: Labels Only
262
- const swp3 = new SWP(document.getElementById("editor3"), {
263
- width: 800,
264
- height: 500,
265
- showIcons: false,
266
- labels: {
267
- upload: "Upload",
268
- rotateLeft: "Rotate Left",
269
- rotateRight: "Rotate Right",
270
- flipH: "Flip Horiz...",
271
- flipV: "Flip Verti...",
272
- resize: "Resize",
273
- adjust: "Adjust",
274
- filters: "Filters",
275
- reset: "Reset",
276
- save: "Save",
277
- },
278
- });
279
-
280
- // Example 4: French Labels
281
- const swp4 = new SWP(document.getElementById("editor4"), {
282
- width: 800,
283
- height: 500,
284
- labels: {
285
- upload: "Télécharger",
286
- resize: "Redimensionner",
287
- adjust: "Ajuster",
288
- filters: "Filtres",
289
- reset: "Réinitialiser",
290
- save: "Enregistrer",
291
- },
292
- });
293
-
294
- // Example 5: Selective Labels
295
- const swp5 = new SWP(document.getElementById("editor5"), {
296
- width: 800,
297
- height: 500,
298
- labels: {
299
- rotateLeft: null,
300
- rotateRight: null,
301
- flipH: null,
302
- flipV: null,
303
- },
304
- });
305
-
306
- // Example 6: Creative Labels
307
- const swp6 = new SWP(document.getElementById("editor6"), {
308
- width: 800,
309
- height: 500,
310
- showIcons: false,
311
- labels: {
312
- upload: "📸",
313
- rotateLeft: "↩️",
314
- rotateRight: "↪️",
315
- flipH: "↔️",
316
- flipV: "↕️",
317
- resize: "📏",
318
- adjust: "🎨",
319
- filters: "✨",
320
- reset: "🔄",
321
- save: "💾",
322
- },
323
- });
324
-
325
- // Example 7: Minimal UI
326
- const swp7 = new SWP(document.getElementById("editor7"), {
327
- width: 800,
328
- height: 500,
329
- showIcons: true,
330
- labels: {
331
- upload: null,
332
- rotateLeft: null,
333
- rotateRight: null,
334
- flipH: null,
335
- flipV: null,
336
- resize: null,
337
- adjust: null,
338
- filters: null,
339
- reset: null,
340
- save: "Save",
341
- },
342
- });
343
-
344
- // Add console logging for all instances
345
- [swp1, swp2, swp3, swp4, swp5, swp6, swp7].forEach((instance, idx) => {
346
- instance.on("load", () =>
347
- console.log(`Example ${idx + 1}: Image loaded`)
348
- );
349
- instance.on("change", () =>
350
- console.log(`Example ${idx + 1}: Image changed`)
351
- );
352
- instance.on("save", () =>
353
- console.log(`Example ${idx + 1}: Image saved`)
354
- );
355
- });
356
-
357
- console.log("All 7 examples initialized! Upload images to test them.");
358
- </script>
359
- </body>
360
- </html>
package/spec.md DELETED
@@ -1,239 +0,0 @@
1
- # SenangWebs Photobooth (SWP) - Specification
2
-
3
- ## 1. Introduction
4
-
5
- SenangWebs Photobooth (SWP) is a lightweight and easy-to-use JavaScript library for client-side photo editing. It provides a simple and intuitive interface for users to perform basic image manipulations directly in the browser. This document outlines the technical specifications, features, and API of the SWP library.
6
-
7
- The primary goal of SWP is to offer a straightforward solution for developers to integrate photo editing capabilities into their web applications without the need for complex server-side processing.
8
-
9
- ## 2. Features
10
-
11
- SWP will provide the following core photo editing features:
12
-
13
- ### 2.1. Core Manipulations
14
-
15
- * **Cropping:** Users can select an area of the image and crop it to the desired dimensions. This includes options for predefined aspect ratios (e.g., 1:1, 4:3, 16:9) and a freeform selection.
16
- * **Rotating:** Users can rotate the image in 90-degree increments to the left and right.
17
- * **Flipping:** Users can flip the image horizontally and vertically.
18
-
19
- ### 2.2. Adjustments
20
-
21
- Users can fine-tune the appearance of the image with the following adjustments:
22
-
23
- * **Brightness:** Increase or decrease the overall lightness of the image.
24
- * **Contrast:** Adjust the difference between the light and dark areas of the image.
25
- * **Saturation:** Control the intensity of the colors in the image.
26
-
27
- ### 2.3. Filters
28
-
29
- A selection of pre-defined filters will be available to apply one-click effects to the image. These filters will be implemented using CSS `filter` properties. Initial filters will include:
30
-
31
- * **Grayscale:** Converts the image to shades of gray.
32
- * **Sepia:** Gives the image a reddish-brown tone.
33
- * **Invert:** Inverts the colors of the image.
34
- * **Blur:** Applies a Gaussian blur to the image.
35
-
36
- ## 3. Technical Specifications
37
-
38
- ### 3.1. Architecture
39
-
40
- SWP is a client-side JavaScript library with no server-side dependencies. It will utilize the HTML5 Canvas API for image rendering and manipulation. This approach ensures that all image processing is done within the user's browser, providing a fast and responsive experience.
41
-
42
- ### 3.2. Dependencies
43
-
44
- The library will have no external dependencies to keep it lightweight and easy to integrate.
45
-
46
- ### 3.3. Browser Compatibility
47
-
48
- SWP will be compatible with all modern web browsers that support the HTML5 Canvas API and the CSS `filter` property. The target browsers include:
49
-
50
- * Google Chrome (latest 2 versions)
51
- * Mozilla Firefox (latest 2 versions)
52
- * Microsoft Edge (latest 2 versions)
53
- * Safari (latest 2 versions)
54
-
55
- ### 3.4. File Output
56
-
57
- The edited image can be exported in the following formats:
58
-
59
- * JPEG
60
- * PNG
61
-
62
- Users will be able to specify the output format and, for JPEG, the image quality.
63
-
64
- ## 4. API Reference
65
-
66
- The SWP library will be instantiated on a container `div` element in the HTML.
67
-
68
- ### 4.1. Initialization
69
-
70
- To initialize the photo booth, create a new instance of `SenangWebsPhotobooth`:
71
-
72
- ```javascript
73
- const swp = new SWP(container, options);
74
- ```
75
-
76
- **Parameters:**
77
-
78
- * `container` (HTMLElement): The DOM element that will contain the photo booth interface.
79
- * `options` (Object): An optional configuration object.
80
-
81
- **Options:**
82
-
83
- * `imageUrl` (String): The URL of the image to be loaded into the editor.
84
- * `width` (Number): The width of the editor in pixels.
85
- * `height` (Number): The height of the editor in pixels.
86
-
87
- ### 4.2. Methods
88
-
89
- The `swp` instance will expose the following public methods:
90
-
91
- #### `loadImage(imageUrl)`
92
-
93
- Loads a new image into the editor.
94
-
95
- * **`imageUrl`** (String): The URL of the image to load.
96
-
97
- #### `crop(x, y, width, height)`
98
-
99
- Crops the image to the specified dimensions.
100
-
101
- * **`x`** (Number): The x-coordinate of the top-left corner of the crop area.
102
- * **`y`** (Number): The y-coordinate of the top-left corner of the crop area.
103
- * **`width`** (Number): The width of the crop area.
104
- * **`height`** (Number): The height of the crop area.
105
-
106
- #### `rotate(degrees)`
107
-
108
- Rotates the image by the specified degrees.
109
-
110
- * **`degrees`** (Number): The degree of rotation. Positive values rotate clockwise, negative values rotate counter-clockwise. For the initial version, this will be limited to multiples of 90.
111
-
112
- #### `flip(direction)`
113
-
114
- Flips the image.
115
-
116
- * **`direction`** (String): The direction to flip. Can be `'horizontal'` or `'vertical'`.
117
-
118
- #### `setAdjustment(adjustment, value)`
119
-
120
- Applies an adjustment to the image.
121
-
122
- * **`adjustment`** (String): The adjustment to apply. Can be `'brightness'`, `'contrast'`, or `'saturation'`.
123
- * **`value`** (Number): The value of the adjustment. The range will be specific to each adjustment.
124
-
125
- #### `applyFilter(filterName)`
126
-
127
- Applies a pre-defined filter to the image.
128
-
129
- * **`filterName`** (String): The name of the filter to apply (e.g., `'grayscale'`, `'sepia'`).
130
-
131
- #### `reset()`
132
-
133
- Resets all edits and reverts the image to its original state.
134
-
135
- #### `getImageData(format, quality)`
136
-
137
- Exports the edited image data.
138
-
139
- * **`format`** (String): The desired output format (`'jpeg'` or `'png'`). Defaults to `'jpeg'`.
140
- * **`quality`** (Number): For JPEG format, a number between 0 and 1 representing the image quality. Defaults to 0.9.
141
- * **Returns:** A data URL representing the image.
142
-
143
- ### 4.3. Events
144
-
145
- The SWP instance will emit the following events that can be listened to:
146
-
147
- * **`'load'`**: Fired when an image has been successfully loaded into the editor.
148
- * **`'change'`**: Fired whenever an edit is applied to the image.
149
- * **`'save'`**: Fired when the image data has been successfully exported.
150
-
151
- ## 5. User Interface
152
-
153
- The SWP library will generate a user-friendly interface within the specified container element. The UI will consist of:
154
-
155
- * **Canvas Area:** The main area where the image is displayed and manipulated.
156
- * **Toolbar:** A toolbar containing buttons for all the editing features (crop, rotate, flip, adjustments, filters).
157
- * **Adjustment Sliders:** For adjustments like brightness and contrast, sliders will be provided for intuitive control.
158
- * **Filter Thumbnails:** A gallery of thumbnails will display a preview of each filter effect.
159
-
160
- ## 6. Example Usage
161
-
162
- ### HTML/Declarative Approach
163
-
164
- ```html
165
- <!DOCTYPE html>
166
- <html>
167
- <head>
168
- <title>SenangWebs Photobooth</title>
169
- <link rel="stylesheet" href="swp.css">
170
- </head>
171
- <body>
172
- <!-- Basic initialization -->
173
- <div data-swp></div>
174
-
175
- <!-- With configuration -->
176
- <div data-swp
177
- data-swp-width="900"
178
- data-swp-height="600"
179
- data-swp-show-labels="false"></div>
180
-
181
- <!-- With custom labels -->
182
- <div data-swp
183
- data-swp-labels="upload: 'Muat Naik'; resize: 'Tukar Saiz'; save: 'Simpan'"></div>
184
-
185
- <script src="swp.js"></script>
186
- </body>
187
- </html>
188
- ```
189
-
190
- **Supported Data Attributes:**
191
- - `data-swp` - Enables auto-initialization
192
- - `data-swp-width` - Canvas width in pixels
193
- - `data-swp-height` - Canvas height in pixels
194
- - `data-swp-image-url` - URL of image to load on initialization
195
- - `data-swp-show-icons` - Show/hide toolbar icons ("true" or "false")
196
- - `data-swp-show-labels` - Show/hide toolbar labels ("true" or "false")
197
- - `data-swp-labels` - Custom button labels in simple format (`key: 'value'; key2: 'value2'`) or JSON format
198
-
199
- ### JS/Programmatic Approach
200
-
201
- ```html
202
- <!DOCTYPE html>
203
- <html>
204
- <head>
205
- <title>SenangWebs Photobooth</title>
206
- <link rel="stylesheet" href="senangwebs-photobooth.css">
207
- </head>
208
- <body>
209
- <div id="photobooth-container"></div>
210
-
211
- <script src="swp.js"></script>
212
- <script>
213
- const container = document.getElementById('photobooth-container');
214
- const options = {
215
- imageUrl: 'path/to/your/image.jpg',
216
- width: 800,
217
- height: 600
218
- };
219
-
220
- const swp = new SWP(container, options);
221
-
222
- swp.on('change', () => {
223
- console.log('Image has been edited.');
224
- });
225
-
226
- // Example of programmatically applying an edit
227
- // swp.rotate(90);
228
- </script>
229
- </body>
230
- </html>
231
- ```
232
-
233
- ## 7. Future Enhancements
234
-
235
- * **More Filters and Adjustments:** Addition of more advanced filters and adjustments like temperature, tint, and vibrance.
236
- * **Text and Stickers:** Ability to add text overlays and stickers to the image.
237
- * **Redo/Undo Functionality:** A history mechanism to allow users to undo and redo their edits.
238
- * **Touch Support:** Improved support for touch gestures on mobile devices.
239
- * **Framework Integration:** Wrappers for popular JavaScript frameworks like React, Vue, and Angular.
package/swp_preview.png DELETED
Binary file