@rageshpikalmunde/rp-image-editor-angular 1.5.12 → 1.6.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/LICENSE +21 -0
- package/README.md +76 -0
- package/esm2020/index.mjs +11 -0
- package/esm2020/lib/rp-image-editor.component.mjs +113 -0
- package/esm2020/lib/rp-image-editor.module.mjs +30 -0
- package/esm2020/lib/rp-image-editor.service.mjs +57 -0
- package/esm2020/rageshpikalmunde-rp-image-editor-angular.mjs +5 -0
- package/fesm2015/rageshpikalmunde-rp-image-editor-angular.mjs +225 -0
- package/fesm2015/rageshpikalmunde-rp-image-editor-angular.mjs.map +1 -0
- package/fesm2020/rageshpikalmunde-rp-image-editor-angular.mjs +205 -0
- package/fesm2020/rageshpikalmunde-rp-image-editor-angular.mjs.map +1 -0
- package/{dist/types/index.d.ts → index.d.ts} +1 -1
- package/{dist/types/lib → lib}/rp-image-editor.component.d.ts +6 -0
- package/lib/rp-image-editor.module.d.ts +14 -0
- package/{dist/types/lib → lib}/rp-image-editor.service.d.ts +13 -1
- package/package.json +25 -27
- package/dist/cjs/index.js +0 -17
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/lib/rp-image-editor.component.js +0 -132
- package/dist/cjs/lib/rp-image-editor.component.js.map +0 -1
- package/dist/cjs/lib/rp-image-editor.module.js +0 -36
- package/dist/cjs/lib/rp-image-editor.module.js.map +0 -1
- package/dist/cjs/lib/rp-image-editor.service.js +0 -52
- package/dist/cjs/lib/rp-image-editor.service.js.map +0 -1
- package/dist/esm/index.js +0 -11
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/lib/rp-image-editor.component.js +0 -129
- package/dist/esm/lib/rp-image-editor.component.js.map +0 -1
- package/dist/esm/lib/rp-image-editor.module.js +0 -33
- package/dist/esm/lib/rp-image-editor.module.js.map +0 -1
- package/dist/esm/lib/rp-image-editor.service.js +0 -49
- package/dist/esm/lib/rp-image-editor.service.js.map +0 -1
- package/dist/types/lib/rp-image-editor.module.d.ts +0 -8
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 rpragesh
|
|
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
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @rageshpikalmunde/rp-image-editor-angular
|
|
2
|
+
|
|
3
|
+
Angular wrapper for [`@rageshpikalmunde/rp-image-editor`](https://www.npmjs.com/package/@rageshpikalmunde/rp-image-editor), a browser image editor and annotator (crop, rotate, draw, text, shapes, callouts, filters, undo/redo, native-resolution export).
|
|
4
|
+
|
|
5
|
+
[Live demo](https://rpragesh.github.io/image-editor/) · [Angular example on StackBlitz](https://stackblitz.com/github/rpragesh/image-editor/tree/main/examples/angular) · [API reference](https://rpragesh.github.io/image-editor/api/) · [Full docs](https://github.com/rpragesh/image-editor#readme)
|
|
6
|
+
|
|
7
|
+
Requires **Angular 15 or newer**. Works with NgModules and standalone components, and with Ionic (optional).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @rageshpikalmunde/rp-image-editor @rageshpikalmunde/rp-image-editor-angular
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Angular 17+ with the default `application` builder:** add this to `architect.build.options` in `angular.json`. Fabric.js 5 has a Node-only code path that the esbuild builder otherwise tries to bundle; it never runs in the browser.
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
"externalDependencies": ["jsdom", "canvas"]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Modal: `RpImageEditorService`
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { RpImageEditorService } from '@rageshpikalmunde/rp-image-editor-angular';
|
|
25
|
+
|
|
26
|
+
export class UploadComponent {
|
|
27
|
+
constructor(private rpEditor: RpImageEditorService) {}
|
|
28
|
+
|
|
29
|
+
async edit(file: File) {
|
|
30
|
+
const result = await this.rpEditor.openEditor(file, {
|
|
31
|
+
exportFormat: 'jpeg',
|
|
32
|
+
theme: { headerTitle: 'Edit photo' },
|
|
33
|
+
});
|
|
34
|
+
if (result) {
|
|
35
|
+
// result.file (upload via FormData), result.base64, result.blob
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The service is `providedIn: 'root'`, so it needs no module import.
|
|
42
|
+
|
|
43
|
+
## Inline: `<rp-image-editor>`
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { Component, ViewChild } from '@angular/core';
|
|
47
|
+
import { RpImageEditorComponent, RpImageEditorModule } from '@rageshpikalmunde/rp-image-editor-angular';
|
|
48
|
+
|
|
49
|
+
@Component({
|
|
50
|
+
standalone: true,
|
|
51
|
+
imports: [RpImageEditorModule], // or add RpImageEditorModule to your NgModule
|
|
52
|
+
template: `
|
|
53
|
+
<div style="height: 520px">
|
|
54
|
+
<rp-image-editor [image]="file" [config]="{ exportFormat: 'png' }"
|
|
55
|
+
(imageEdited)="onEdited($event)" (editorError)="onError($event)"></rp-image-editor>
|
|
56
|
+
</div>
|
|
57
|
+
<button (click)="editor.apply()">Apply</button>
|
|
58
|
+
`,
|
|
59
|
+
})
|
|
60
|
+
export class InlineEditorComponent {
|
|
61
|
+
@ViewChild(RpImageEditorComponent) editor!: RpImageEditorComponent;
|
|
62
|
+
file: File | string = 'assets/photo.jpg';
|
|
63
|
+
onEdited(result: unknown) { /* ... */ }
|
|
64
|
+
onError(error: Error) { console.error(error); }
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Component API: inputs `image`, `config`; outputs `imageEdited`, `editorClosed`, `editorError`; methods `apply()`, `getResult()`, `loadImage()`, `reset()`, `close()`.
|
|
69
|
+
|
|
70
|
+
## Server-side rendering
|
|
71
|
+
|
|
72
|
+
`<rp-image-editor>` does nothing on the server and creates the editor in the browser. Call `openEditor()` from user actions such as clicks.
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rageshpikalmunde/rp-image-editor-angular
|
|
3
|
+
* Angular wrapper for the rp-image-editor plugin
|
|
4
|
+
*/
|
|
5
|
+
// Module
|
|
6
|
+
export { RpImageEditorModule } from './lib/rp-image-editor.module';
|
|
7
|
+
// Component
|
|
8
|
+
export { RpImageEditorComponent } from './lib/rp-image-editor.component';
|
|
9
|
+
// Service
|
|
10
|
+
export { RpImageEditorService } from './lib/rp-image-editor.service';
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsU0FBUztBQUNULE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRW5FLFlBQVk7QUFDWixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6RSxVQUFVO0FBQ1YsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sK0JBQStCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEByYWdlc2hwaWthbG11bmRlL3JwLWltYWdlLWVkaXRvci1hbmd1bGFyXG4gKiBBbmd1bGFyIHdyYXBwZXIgZm9yIHRoZSBycC1pbWFnZS1lZGl0b3IgcGx1Z2luXG4gKi9cblxuLy8gTW9kdWxlXG5leHBvcnQgeyBScEltYWdlRWRpdG9yTW9kdWxlIH0gZnJvbSAnLi9saWIvcnAtaW1hZ2UtZWRpdG9yLm1vZHVsZSc7XG5cbi8vIENvbXBvbmVudFxuZXhwb3J0IHsgUnBJbWFnZUVkaXRvckNvbXBvbmVudCB9IGZyb20gJy4vbGliL3JwLWltYWdlLWVkaXRvci5jb21wb25lbnQnO1xuXG4vLyBTZXJ2aWNlXG5leHBvcnQgeyBScEltYWdlRWRpdG9yU2VydmljZSB9IGZyb20gJy4vbGliL3JwLWltYWdlLWVkaXRvci5zZXJ2aWNlJztcblxuLy8gUmUtZXhwb3J0IHR5cGVzIGZyb20gY29yZVxuZXhwb3J0IHR5cGUge1xuICBScEVkaXRvckNvbmZpZyxcbiAgUnBFZGl0b3JUaGVtZSxcbiAgUnBFZGl0b3JSZXN1bHQsXG4gIFJwTXVsdGlFZGl0b3JJdGVtUmVzdWx0LFxuICBDcm9wQXNwZWN0UmF0aW8sXG4gIEVkaXRvck1vZGUsXG59IGZyb20gJ0ByYWdlc2hwaWthbG11bmRlL3JwLWltYWdlLWVkaXRvcic7XG4iXX0=
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Component, EventEmitter, Inject, Input, Output, PLATFORM_ID, ViewChild } from '@angular/core';
|
|
2
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
3
|
+
import { RpImageEditor } from '@rageshpikalmunde/rp-image-editor';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class RpImageEditorComponent {
|
|
6
|
+
constructor(platformId) {
|
|
7
|
+
/** Image source — File, Blob, or URL string */
|
|
8
|
+
this.image = null;
|
|
9
|
+
/** Editor configuration */
|
|
10
|
+
this.config = {};
|
|
11
|
+
/** Emitted when user clicks Apply — contains the edited image result */
|
|
12
|
+
this.imageEdited = new EventEmitter();
|
|
13
|
+
/** Emitted when user clicks Close/Cancel */
|
|
14
|
+
this.editorClosed = new EventEmitter();
|
|
15
|
+
/** Emitted when an error occurs */
|
|
16
|
+
this.editorError = new EventEmitter();
|
|
17
|
+
this.editor = null;
|
|
18
|
+
this.isBrowser = isPlatformBrowser(platformId);
|
|
19
|
+
}
|
|
20
|
+
ngAfterViewInit() {
|
|
21
|
+
if (this.image) {
|
|
22
|
+
this.initEditor();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
ngOnDestroy() {
|
|
26
|
+
this.destroyEditor();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Programmatically load an image (can be called after component init)
|
|
30
|
+
*/
|
|
31
|
+
async loadImage(source) {
|
|
32
|
+
this.image = source;
|
|
33
|
+
await this.initEditor();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the edited result programmatically
|
|
37
|
+
*/
|
|
38
|
+
async getResult() {
|
|
39
|
+
try {
|
|
40
|
+
return await this.editor?.getResult() ?? null;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
this.editorError.emit(err);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Apply and emit result
|
|
49
|
+
*/
|
|
50
|
+
async apply() {
|
|
51
|
+
const result = await this.getResult();
|
|
52
|
+
if (result) {
|
|
53
|
+
this.imageEdited.emit(result);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Close the editor
|
|
58
|
+
*/
|
|
59
|
+
close() {
|
|
60
|
+
this.destroyEditor();
|
|
61
|
+
this.editorClosed.emit();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reset to original image
|
|
65
|
+
*/
|
|
66
|
+
async reset() {
|
|
67
|
+
await this.editor?.reset();
|
|
68
|
+
}
|
|
69
|
+
async initEditor() {
|
|
70
|
+
this.destroyEditor();
|
|
71
|
+
if (!this.isBrowser || !this.image || !this.containerRef?.nativeElement)
|
|
72
|
+
return;
|
|
73
|
+
this.editor = new RpImageEditor(this.containerRef.nativeElement, this.config);
|
|
74
|
+
this.editor.on('error', (err) => {
|
|
75
|
+
this.editorError.emit(err);
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
await this.editor.loadImage(this.image);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
this.editorError.emit(err);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
destroyEditor() {
|
|
85
|
+
if (this.editor) {
|
|
86
|
+
this.editor.destroy();
|
|
87
|
+
this.editor = null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
RpImageEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorComponent, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
|
|
92
|
+
RpImageEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RpImageEditorComponent, selector: "rp-image-editor", inputs: { image: "image", config: "config" }, outputs: { imageEdited: "imageEdited", editorClosed: "editorClosed", editorError: "editorError" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["editorContainer"], descendants: true, static: true }], ngImport: i0, template: `<div #editorContainer class="rp-image-editor-host" [style.width]="'100%'" [style.height]="'100%'" [style.display]="'flex'" [style.flexDirection]="'column'"></div>`, isInline: true, styles: [":host{display:block;width:100%;height:100%}.rp-image-editor-host{min-height:300px}\n"] });
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorComponent, decorators: [{
|
|
94
|
+
type: Component,
|
|
95
|
+
args: [{ selector: 'rp-image-editor', template: `<div #editorContainer class="rp-image-editor-host" [style.width]="'100%'" [style.height]="'100%'" [style.display]="'flex'" [style.flexDirection]="'column'"></div>`, styles: [":host{display:block;width:100%;height:100%}.rp-image-editor-host{min-height:300px}\n"] }]
|
|
96
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
97
|
+
type: Inject,
|
|
98
|
+
args: [PLATFORM_ID]
|
|
99
|
+
}] }]; }, propDecorators: { containerRef: [{
|
|
100
|
+
type: ViewChild,
|
|
101
|
+
args: ['editorContainer', { static: true }]
|
|
102
|
+
}], image: [{
|
|
103
|
+
type: Input
|
|
104
|
+
}], config: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], imageEdited: [{
|
|
107
|
+
type: Output
|
|
108
|
+
}], editorClosed: [{
|
|
109
|
+
type: Output
|
|
110
|
+
}], editorError: [{
|
|
111
|
+
type: Output
|
|
112
|
+
}] } });
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnAtaW1hZ2UtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvcnAtaW1hZ2UtZWRpdG9yLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUM3SSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFrQyxNQUFNLG1DQUFtQyxDQUFDOztBQU9sRyxNQUFNLE9BQU8sc0JBQXNCO0lBdUJqQyxZQUFpQyxVQUFrQjtRQXBCbkQsK0NBQStDO1FBQ3RDLFVBQUssR0FBZ0MsSUFBSSxDQUFDO1FBRW5ELDJCQUEyQjtRQUNsQixXQUFNLEdBQTRCLEVBQUUsQ0FBQztRQUU5Qyx3RUFBd0U7UUFDOUQsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBa0IsQ0FBQztRQUUzRCw0Q0FBNEM7UUFDbEMsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRWxELG1DQUFtQztRQUN6QixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7UUFFMUMsV0FBTSxHQUF5QixJQUFJLENBQUM7UUFNMUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsZUFBZTtRQUNiLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNkLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNuQjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBNEI7UUFDMUMsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7UUFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFNBQVM7UUFDYixJQUFJO1lBQ0YsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksSUFBSSxDQUFDO1NBQy9DO1FBQUMsT0FBTyxHQUFHLEVBQUU7WUFDWixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFZLENBQUMsQ0FBQztZQUNwQyxPQUFPLElBQUksQ0FBQztTQUNiO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEtBQUs7UUFDVCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN0QyxJQUFJLE1BQU0sRUFBRTtZQUNWLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQy9CO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSztRQUNILElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFTyxLQUFLLENBQUMsVUFBVTtRQUN0QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFckIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxhQUFhO1lBQUUsT0FBTztRQUVoRixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUU5RSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM5QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUVILElBQUk7WUFDRixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN6QztRQUFDLE9BQU8sR0FBRyxFQUFFO1lBQ1osSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBWSxDQUFDLENBQUM7U0FDckM7SUFDSCxDQUFDO0lBRU8sYUFBYTtRQUNuQixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1NBQ3BCO0lBQ0gsQ0FBQzs7b0hBekdVLHNCQUFzQixrQkF1QmIsV0FBVzt3R0F2QnBCLHNCQUFzQix1VUFIdkIsb0tBQW9LOzRGQUduSyxzQkFBc0I7a0JBTGxDLFNBQVM7K0JBQ0UsaUJBQWlCLFlBQ2pCLG9LQUFvSzs7MEJBMEJqSyxNQUFNOzJCQUFDLFdBQVc7NENBdEJpQixZQUFZO3NCQUEzRCxTQUFTO3VCQUFDLGlCQUFpQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFHckMsS0FBSztzQkFBYixLQUFLO2dCQUdHLE1BQU07c0JBQWQsS0FBSztnQkFHSSxXQUFXO3NCQUFwQixNQUFNO2dCQUdHLFlBQVk7c0JBQXJCLE1BQU07Z0JBR0csV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBPbkRlc3Ryb3ksIE91dHB1dCwgUExBVEZPUk1fSUQsIFZpZXdDaGlsZCwgQWZ0ZXJWaWV3SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgUnBJbWFnZUVkaXRvciwgUnBFZGl0b3JDb25maWcsIFJwRWRpdG9yUmVzdWx0IH0gZnJvbSAnQHJhZ2VzaHBpa2FsbXVuZGUvcnAtaW1hZ2UtZWRpdG9yJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncnAtaW1hZ2UtZWRpdG9yJyxcbiAgdGVtcGxhdGU6IGA8ZGl2ICNlZGl0b3JDb250YWluZXIgY2xhc3M9XCJycC1pbWFnZS1lZGl0b3ItaG9zdFwiIFtzdHlsZS53aWR0aF09XCInMTAwJSdcIiBbc3R5bGUuaGVpZ2h0XT1cIicxMDAlJ1wiIFtzdHlsZS5kaXNwbGF5XT1cIidmbGV4J1wiIFtzdHlsZS5mbGV4RGlyZWN0aW9uXT1cIidjb2x1bW4nXCI+PC9kaXY+YCxcbiAgc3R5bGVzOiBbYDpob3N0IHsgZGlzcGxheTogYmxvY2s7IHdpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCU7IH0gLnJwLWltYWdlLWVkaXRvci1ob3N0IHsgbWluLWhlaWdodDogMzAwcHg7IH1gXVxufSlcbmV4cG9ydCBjbGFzcyBScEltYWdlRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgQFZpZXdDaGlsZCgnZWRpdG9yQ29udGFpbmVyJywgeyBzdGF0aWM6IHRydWUgfSkgY29udGFpbmVyUmVmITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgLyoqIEltYWdlIHNvdXJjZSDigJQgRmlsZSwgQmxvYiwgb3IgVVJMIHN0cmluZyAqL1xuICBASW5wdXQoKSBpbWFnZTogRmlsZSB8IEJsb2IgfCBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiogRWRpdG9yIGNvbmZpZ3VyYXRpb24gKi9cbiAgQElucHV0KCkgY29uZmlnOiBQYXJ0aWFsPFJwRWRpdG9yQ29uZmlnPiA9IHt9O1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gdXNlciBjbGlja3MgQXBwbHkg4oCUIGNvbnRhaW5zIHRoZSBlZGl0ZWQgaW1hZ2UgcmVzdWx0ICovXG4gIEBPdXRwdXQoKSBpbWFnZUVkaXRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8UnBFZGl0b3JSZXN1bHQ+KCk7XG5cbiAgLyoqIEVtaXR0ZWQgd2hlbiB1c2VyIGNsaWNrcyBDbG9zZS9DYW5jZWwgKi9cbiAgQE91dHB1dCgpIGVkaXRvckNsb3NlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGFuIGVycm9yIG9jY3VycyAqL1xuICBAT3V0cHV0KCkgZWRpdG9yRXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPEVycm9yPigpO1xuXG4gIHByaXZhdGUgZWRpdG9yOiBScEltYWdlRWRpdG9yIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIEZhbHNlIGR1cmluZyBzZXJ2ZXItc2lkZSByZW5kZXJpbmcsIHdoZXJlIHRoZXJlIGlzIG5vIERPTS9jYW52YXMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgaXNCcm93c2VyOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoUExBVEZPUk1fSUQpIHBsYXRmb3JtSWQ6IG9iamVjdCkge1xuICAgIHRoaXMuaXNCcm93c2VyID0gaXNQbGF0Zm9ybUJyb3dzZXIocGxhdGZvcm1JZCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW1hZ2UpIHtcbiAgICAgIHRoaXMuaW5pdEVkaXRvcigpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveUVkaXRvcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2dyYW1tYXRpY2FsbHkgbG9hZCBhbiBpbWFnZSAoY2FuIGJlIGNhbGxlZCBhZnRlciBjb21wb25lbnQgaW5pdClcbiAgICovXG4gIGFzeW5jIGxvYWRJbWFnZShzb3VyY2U6IEZpbGUgfCBCbG9iIHwgc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5pbWFnZSA9IHNvdXJjZTtcbiAgICBhd2FpdCB0aGlzLmluaXRFZGl0b3IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGVkaXRlZCByZXN1bHQgcHJvZ3JhbW1hdGljYWxseVxuICAgKi9cbiAgYXN5bmMgZ2V0UmVzdWx0KCk6IFByb21pc2U8UnBFZGl0b3JSZXN1bHQgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmVkaXRvcj8uZ2V0UmVzdWx0KCkgPz8gbnVsbDtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuZWRpdG9yRXJyb3IuZW1pdChlcnIgYXMgRXJyb3IpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IGFuZCBlbWl0IHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgYXBwbHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5nZXRSZXN1bHQoKTtcbiAgICBpZiAocmVzdWx0KSB7XG4gICAgICB0aGlzLmltYWdlRWRpdGVkLmVtaXQocmVzdWx0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgdGhlIGVkaXRvclxuICAgKi9cbiAgY2xvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95RWRpdG9yKCk7XG4gICAgdGhpcy5lZGl0b3JDbG9zZWQuZW1pdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRvIG9yaWdpbmFsIGltYWdlXG4gICAqL1xuICBhc3luYyByZXNldCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmVkaXRvcj8ucmVzZXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdEVkaXRvcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmRlc3Ryb3lFZGl0b3IoKTtcblxuICAgIGlmICghdGhpcy5pc0Jyb3dzZXIgfHwgIXRoaXMuaW1hZ2UgfHwgIXRoaXMuY29udGFpbmVyUmVmPy5uYXRpdmVFbGVtZW50KSByZXR1cm47XG5cbiAgICB0aGlzLmVkaXRvciA9IG5ldyBScEltYWdlRWRpdG9yKHRoaXMuY29udGFpbmVyUmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuY29uZmlnKTtcblxuICAgIHRoaXMuZWRpdG9yLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgIHRoaXMuZWRpdG9yRXJyb3IuZW1pdChlcnIpO1xuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuZWRpdG9yLmxvYWRJbWFnZSh0aGlzLmltYWdlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuZWRpdG9yRXJyb3IuZW1pdChlcnIgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUVkaXRvcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lZGl0b3IpIHtcbiAgICAgIHRoaXMuZWRpdG9yLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuZWRpdG9yID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { RpImageEditorComponent } from './rp-image-editor.component';
|
|
4
|
+
import { RpImageEditorService } from './rp-image-editor.service';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export class RpImageEditorModule {
|
|
7
|
+
/**
|
|
8
|
+
* Use forRoot() if you want to provide the service at root level
|
|
9
|
+
* (optional — service is already providedIn: 'root')
|
|
10
|
+
*/
|
|
11
|
+
static forRoot() {
|
|
12
|
+
return {
|
|
13
|
+
ngModule: RpImageEditorModule,
|
|
14
|
+
providers: [RpImageEditorService],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
RpImageEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
19
|
+
RpImageEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, declarations: [RpImageEditorComponent], imports: [CommonModule], exports: [RpImageEditorComponent] });
|
|
20
|
+
RpImageEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, providers: [RpImageEditorService], imports: [CommonModule] });
|
|
21
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, decorators: [{
|
|
22
|
+
type: NgModule,
|
|
23
|
+
args: [{
|
|
24
|
+
declarations: [RpImageEditorComponent],
|
|
25
|
+
imports: [CommonModule],
|
|
26
|
+
exports: [RpImageEditorComponent],
|
|
27
|
+
providers: [RpImageEditorService],
|
|
28
|
+
}]
|
|
29
|
+
}] });
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnAtaW1hZ2UtZWRpdG9yLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvcnAtaW1hZ2UtZWRpdG9yLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUF1QixNQUFNLGVBQWUsQ0FBQztBQUM5RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDckUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7O0FBUWpFLE1BQU0sT0FBTyxtQkFBbUI7SUFDOUI7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLE9BQU87UUFDWixPQUFPO1lBQ0wsUUFBUSxFQUFFLG1CQUFtQjtZQUM3QixTQUFTLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztTQUNsQyxDQUFDO0lBQ0osQ0FBQzs7aUhBVlUsbUJBQW1CO2tIQUFuQixtQkFBbUIsaUJBTGYsc0JBQXNCLGFBQzNCLFlBQVksYUFDWixzQkFBc0I7a0hBR3JCLG1CQUFtQixhQUZuQixDQUFDLG9CQUFvQixDQUFDLFlBRnZCLFlBQVk7NEZBSVgsbUJBQW1CO2tCQU4vQixRQUFRO21CQUFDO29CQUNSLFlBQVksRUFBRSxDQUFDLHNCQUFzQixDQUFDO29CQUN0QyxPQUFPLEVBQUUsQ0FBQyxZQUFZLENBQUM7b0JBQ3ZCLE9BQU8sRUFBRSxDQUFDLHNCQUFzQixDQUFDO29CQUNqQyxTQUFTLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQztpQkFDbEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSwgTW9kdWxlV2l0aFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFJwSW1hZ2VFZGl0b3JDb21wb25lbnQgfSBmcm9tICcuL3JwLWltYWdlLWVkaXRvci5jb21wb25lbnQnO1xuaW1wb3J0IHsgUnBJbWFnZUVkaXRvclNlcnZpY2UgfSBmcm9tICcuL3JwLWltYWdlLWVkaXRvci5zZXJ2aWNlJztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbUnBJbWFnZUVkaXRvckNvbXBvbmVudF0sXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICBleHBvcnRzOiBbUnBJbWFnZUVkaXRvckNvbXBvbmVudF0sXG4gIHByb3ZpZGVyczogW1JwSW1hZ2VFZGl0b3JTZXJ2aWNlXSxcbn0pXG5leHBvcnQgY2xhc3MgUnBJbWFnZUVkaXRvck1vZHVsZSB7XG4gIC8qKlxuICAgKiBVc2UgZm9yUm9vdCgpIGlmIHlvdSB3YW50IHRvIHByb3ZpZGUgdGhlIHNlcnZpY2UgYXQgcm9vdCBsZXZlbFxuICAgKiAob3B0aW9uYWwg4oCUIHNlcnZpY2UgaXMgYWxyZWFkeSBwcm92aWRlZEluOiAncm9vdCcpXG4gICAqL1xuICBzdGF0aWMgZm9yUm9vdCgpOiBNb2R1bGVXaXRoUHJvdmlkZXJzPFJwSW1hZ2VFZGl0b3JNb2R1bGU+IHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IFJwSW1hZ2VFZGl0b3JNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtScEltYWdlRWRpdG9yU2VydmljZV0sXG4gICAgfTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { openEditorModal, openMultiEditorModal, } from '@rageshpikalmunde/rp-image-editor';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Service to open the image editor as a modal overlay.
|
|
6
|
+
* Works with or without Ionic — uses the core modal implementation.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* ```ts
|
|
10
|
+
* constructor(private rpEditor: RpImageEditorService) {}
|
|
11
|
+
*
|
|
12
|
+
* async editImage(file: File) {
|
|
13
|
+
* const result = await this.rpEditor.openEditor(file, {
|
|
14
|
+
* theme: { applyButtonBackground: '#28a745' }
|
|
15
|
+
* });
|
|
16
|
+
* if (result) {
|
|
17
|
+
* // result.file — upload to server
|
|
18
|
+
* // result.base64 — preview
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class RpImageEditorService {
|
|
24
|
+
/**
|
|
25
|
+
* Open the image editor in a modal popup.
|
|
26
|
+
*
|
|
27
|
+
* @param image - File, Blob, or URL string to edit
|
|
28
|
+
* @param config - Optional editor configuration (theme, crop ratios, etc.)
|
|
29
|
+
* @returns Promise resolving to RpEditorResult if applied, or null if cancelled
|
|
30
|
+
*/
|
|
31
|
+
async openEditor(image, config) {
|
|
32
|
+
return openEditorModal({
|
|
33
|
+
image,
|
|
34
|
+
config,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Edit several images in one modal with a thumbnail strip.
|
|
39
|
+
*
|
|
40
|
+
* @param images - Files, Blobs or URL strings, in strip order
|
|
41
|
+
* @param config - Editor configuration shared by every image
|
|
42
|
+
* @param startIndex - 0-based index of the image to open first
|
|
43
|
+
* @returns One `{ index, edited, result }` per image on Apply, or null if closed
|
|
44
|
+
*/
|
|
45
|
+
async openMultiEditor(images, config, startIndex) {
|
|
46
|
+
return openMultiEditorModal({ images, config, startIndex });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
RpImageEditorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
50
|
+
RpImageEditorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorService, providedIn: 'root' });
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorService, decorators: [{
|
|
52
|
+
type: Injectable,
|
|
53
|
+
args: [{
|
|
54
|
+
providedIn: 'root',
|
|
55
|
+
}]
|
|
56
|
+
}] });
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnAtaW1hZ2UtZWRpdG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3JwLWltYWdlLWVkaXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUlMLGVBQWUsRUFDZixvQkFBb0IsR0FDckIsTUFBTSxtQ0FBbUMsQ0FBQzs7QUFFM0M7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUlILE1BQU0sT0FBTyxvQkFBb0I7SUFDL0I7Ozs7OztPQU1HO0lBQ0gsS0FBSyxDQUFDLFVBQVUsQ0FDZCxLQUEyQixFQUMzQixNQUFnQztRQUVoQyxPQUFPLGVBQWUsQ0FBQztZQUNyQixLQUFLO1lBQ0wsTUFBTTtTQUNQLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FDbkIsTUFBbUMsRUFDbkMsTUFBZ0MsRUFDaEMsVUFBbUI7UUFFbkIsT0FBTyxvQkFBb0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUM5RCxDQUFDOztrSEFoQ1Usb0JBQW9CO3NIQUFwQixvQkFBb0IsY0FGbkIsTUFBTTs0RkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgUnBFZGl0b3JDb25maWcsXG4gIFJwRWRpdG9yUmVzdWx0LFxuICBScE11bHRpRWRpdG9ySXRlbVJlc3VsdCxcbiAgb3BlbkVkaXRvck1vZGFsLFxuICBvcGVuTXVsdGlFZGl0b3JNb2RhbCxcbn0gZnJvbSAnQHJhZ2VzaHBpa2FsbXVuZGUvcnAtaW1hZ2UtZWRpdG9yJztcblxuLyoqXG4gKiBTZXJ2aWNlIHRvIG9wZW4gdGhlIGltYWdlIGVkaXRvciBhcyBhIG1vZGFsIG92ZXJsYXkuXG4gKiBXb3JrcyB3aXRoIG9yIHdpdGhvdXQgSW9uaWMg4oCUIHVzZXMgdGhlIGNvcmUgbW9kYWwgaW1wbGVtZW50YXRpb24uXG4gKlxuICogVXNhZ2U6XG4gKiBgYGB0c1xuICogY29uc3RydWN0b3IocHJpdmF0ZSBycEVkaXRvcjogUnBJbWFnZUVkaXRvclNlcnZpY2UpIHt9XG4gKlxuICogYXN5bmMgZWRpdEltYWdlKGZpbGU6IEZpbGUpIHtcbiAqICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ycEVkaXRvci5vcGVuRWRpdG9yKGZpbGUsIHtcbiAqICAgICB0aGVtZTogeyBhcHBseUJ1dHRvbkJhY2tncm91bmQ6ICcjMjhhNzQ1JyB9XG4gKiAgIH0pO1xuICogICBpZiAocmVzdWx0KSB7XG4gKiAgICAgLy8gcmVzdWx0LmZpbGUg4oCUIHVwbG9hZCB0byBzZXJ2ZXJcbiAqICAgICAvLyByZXN1bHQuYmFzZTY0IOKAlCBwcmV2aWV3XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICovXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgUnBJbWFnZUVkaXRvclNlcnZpY2Uge1xuICAvKipcbiAgICogT3BlbiB0aGUgaW1hZ2UgZWRpdG9yIGluIGEgbW9kYWwgcG9wdXAuXG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZSAtIEZpbGUsIEJsb2IsIG9yIFVSTCBzdHJpbmcgdG8gZWRpdFxuICAgKiBAcGFyYW0gY29uZmlnIC0gT3B0aW9uYWwgZWRpdG9yIGNvbmZpZ3VyYXRpb24gKHRoZW1lLCBjcm9wIHJhdGlvcywgZXRjLilcbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gUnBFZGl0b3JSZXN1bHQgaWYgYXBwbGllZCwgb3IgbnVsbCBpZiBjYW5jZWxsZWRcbiAgICovXG4gIGFzeW5jIG9wZW5FZGl0b3IoXG4gICAgaW1hZ2U6IEZpbGUgfCBCbG9iIHwgc3RyaW5nLFxuICAgIGNvbmZpZz86IFBhcnRpYWw8UnBFZGl0b3JDb25maWc+XG4gICk6IFByb21pc2U8UnBFZGl0b3JSZXN1bHQgfCBudWxsPiB7XG4gICAgcmV0dXJuIG9wZW5FZGl0b3JNb2RhbCh7XG4gICAgICBpbWFnZSxcbiAgICAgIGNvbmZpZyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFZGl0IHNldmVyYWwgaW1hZ2VzIGluIG9uZSBtb2RhbCB3aXRoIGEgdGh1bWJuYWlsIHN0cmlwLlxuICAgKlxuICAgKiBAcGFyYW0gaW1hZ2VzIC0gRmlsZXMsIEJsb2JzIG9yIFVSTCBzdHJpbmdzLCBpbiBzdHJpcCBvcmRlclxuICAgKiBAcGFyYW0gY29uZmlnIC0gRWRpdG9yIGNvbmZpZ3VyYXRpb24gc2hhcmVkIGJ5IGV2ZXJ5IGltYWdlXG4gICAqIEBwYXJhbSBzdGFydEluZGV4IC0gMC1iYXNlZCBpbmRleCBvZiB0aGUgaW1hZ2UgdG8gb3BlbiBmaXJzdFxuICAgKiBAcmV0dXJucyBPbmUgYHsgaW5kZXgsIGVkaXRlZCwgcmVzdWx0IH1gIHBlciBpbWFnZSBvbiBBcHBseSwgb3IgbnVsbCBpZiBjbG9zZWRcbiAgICovXG4gIGFzeW5jIG9wZW5NdWx0aUVkaXRvcihcbiAgICBpbWFnZXM6IEFycmF5PEZpbGUgfCBCbG9iIHwgc3RyaW5nPixcbiAgICBjb25maWc/OiBQYXJ0aWFsPFJwRWRpdG9yQ29uZmlnPixcbiAgICBzdGFydEluZGV4PzogbnVtYmVyXG4gICk6IFByb21pc2U8UnBNdWx0aUVkaXRvckl0ZW1SZXN1bHRbXSB8IG51bGw+IHtcbiAgICByZXR1cm4gb3Blbk11bHRpRWRpdG9yTW9kYWwoeyBpbWFnZXMsIGNvbmZpZywgc3RhcnRJbmRleCB9KTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFnZXNocGlrYWxtdW5kZS1ycC1pbWFnZS1lZGl0b3ItYW5ndWxhci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yYWdlc2hwaWthbG11bmRlLXJwLWltYWdlLWVkaXRvci1hbmd1bGFyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, PLATFORM_ID, Component, Inject, ViewChild, Input, Output, Injectable, NgModule } from '@angular/core';
|
|
3
|
+
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
4
|
+
import { __awaiter } from 'tslib';
|
|
5
|
+
import { RpImageEditor, openEditorModal, openMultiEditorModal } from '@rageshpikalmunde/rp-image-editor';
|
|
6
|
+
|
|
7
|
+
class RpImageEditorComponent {
|
|
8
|
+
constructor(platformId) {
|
|
9
|
+
/** Image source — File, Blob, or URL string */
|
|
10
|
+
this.image = null;
|
|
11
|
+
/** Editor configuration */
|
|
12
|
+
this.config = {};
|
|
13
|
+
/** Emitted when user clicks Apply — contains the edited image result */
|
|
14
|
+
this.imageEdited = new EventEmitter();
|
|
15
|
+
/** Emitted when user clicks Close/Cancel */
|
|
16
|
+
this.editorClosed = new EventEmitter();
|
|
17
|
+
/** Emitted when an error occurs */
|
|
18
|
+
this.editorError = new EventEmitter();
|
|
19
|
+
this.editor = null;
|
|
20
|
+
this.isBrowser = isPlatformBrowser(platformId);
|
|
21
|
+
}
|
|
22
|
+
ngAfterViewInit() {
|
|
23
|
+
if (this.image) {
|
|
24
|
+
this.initEditor();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
ngOnDestroy() {
|
|
28
|
+
this.destroyEditor();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Programmatically load an image (can be called after component init)
|
|
32
|
+
*/
|
|
33
|
+
loadImage(source) {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
this.image = source;
|
|
36
|
+
yield this.initEditor();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the edited result programmatically
|
|
41
|
+
*/
|
|
42
|
+
getResult() {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
try {
|
|
46
|
+
return (_b = yield ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.getResult())) !== null && _b !== void 0 ? _b : null;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
this.editorError.emit(err);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Apply and emit result
|
|
56
|
+
*/
|
|
57
|
+
apply() {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const result = yield this.getResult();
|
|
60
|
+
if (result) {
|
|
61
|
+
this.imageEdited.emit(result);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Close the editor
|
|
67
|
+
*/
|
|
68
|
+
close() {
|
|
69
|
+
this.destroyEditor();
|
|
70
|
+
this.editorClosed.emit();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Reset to original image
|
|
74
|
+
*/
|
|
75
|
+
reset() {
|
|
76
|
+
var _a;
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
yield ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.reset());
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
initEditor() {
|
|
82
|
+
var _a;
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
this.destroyEditor();
|
|
85
|
+
if (!this.isBrowser || !this.image || !((_a = this.containerRef) === null || _a === void 0 ? void 0 : _a.nativeElement))
|
|
86
|
+
return;
|
|
87
|
+
this.editor = new RpImageEditor(this.containerRef.nativeElement, this.config);
|
|
88
|
+
this.editor.on('error', (err) => {
|
|
89
|
+
this.editorError.emit(err);
|
|
90
|
+
});
|
|
91
|
+
try {
|
|
92
|
+
yield this.editor.loadImage(this.image);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
this.editorError.emit(err);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
destroyEditor() {
|
|
100
|
+
if (this.editor) {
|
|
101
|
+
this.editor.destroy();
|
|
102
|
+
this.editor = null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
RpImageEditorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorComponent, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
|
|
107
|
+
RpImageEditorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: RpImageEditorComponent, selector: "rp-image-editor", inputs: { image: "image", config: "config" }, outputs: { imageEdited: "imageEdited", editorClosed: "editorClosed", editorError: "editorError" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["editorContainer"], descendants: true, static: true }], ngImport: i0, template: `<div #editorContainer class="rp-image-editor-host" [style.width]="'100%'" [style.height]="'100%'" [style.display]="'flex'" [style.flexDirection]="'column'"></div>`, isInline: true, styles: [":host{display:block;width:100%;height:100%}.rp-image-editor-host{min-height:300px}\n"] });
|
|
108
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorComponent, decorators: [{
|
|
109
|
+
type: Component,
|
|
110
|
+
args: [{ selector: 'rp-image-editor', template: `<div #editorContainer class="rp-image-editor-host" [style.width]="'100%'" [style.height]="'100%'" [style.display]="'flex'" [style.flexDirection]="'column'"></div>`, styles: [":host{display:block;width:100%;height:100%}.rp-image-editor-host{min-height:300px}\n"] }]
|
|
111
|
+
}], ctorParameters: function () {
|
|
112
|
+
return [{ type: undefined, decorators: [{
|
|
113
|
+
type: Inject,
|
|
114
|
+
args: [PLATFORM_ID]
|
|
115
|
+
}] }];
|
|
116
|
+
}, propDecorators: { containerRef: [{
|
|
117
|
+
type: ViewChild,
|
|
118
|
+
args: ['editorContainer', { static: true }]
|
|
119
|
+
}], image: [{
|
|
120
|
+
type: Input
|
|
121
|
+
}], config: [{
|
|
122
|
+
type: Input
|
|
123
|
+
}], imageEdited: [{
|
|
124
|
+
type: Output
|
|
125
|
+
}], editorClosed: [{
|
|
126
|
+
type: Output
|
|
127
|
+
}], editorError: [{
|
|
128
|
+
type: Output
|
|
129
|
+
}] } });
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Service to open the image editor as a modal overlay.
|
|
133
|
+
* Works with or without Ionic — uses the core modal implementation.
|
|
134
|
+
*
|
|
135
|
+
* Usage:
|
|
136
|
+
* ```ts
|
|
137
|
+
* constructor(private rpEditor: RpImageEditorService) {}
|
|
138
|
+
*
|
|
139
|
+
* async editImage(file: File) {
|
|
140
|
+
* const result = await this.rpEditor.openEditor(file, {
|
|
141
|
+
* theme: { applyButtonBackground: '#28a745' }
|
|
142
|
+
* });
|
|
143
|
+
* if (result) {
|
|
144
|
+
* // result.file — upload to server
|
|
145
|
+
* // result.base64 — preview
|
|
146
|
+
* }
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
class RpImageEditorService {
|
|
151
|
+
/**
|
|
152
|
+
* Open the image editor in a modal popup.
|
|
153
|
+
*
|
|
154
|
+
* @param image - File, Blob, or URL string to edit
|
|
155
|
+
* @param config - Optional editor configuration (theme, crop ratios, etc.)
|
|
156
|
+
* @returns Promise resolving to RpEditorResult if applied, or null if cancelled
|
|
157
|
+
*/
|
|
158
|
+
openEditor(image, config) {
|
|
159
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
160
|
+
return openEditorModal({
|
|
161
|
+
image,
|
|
162
|
+
config,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Edit several images in one modal with a thumbnail strip.
|
|
168
|
+
*
|
|
169
|
+
* @param images - Files, Blobs or URL strings, in strip order
|
|
170
|
+
* @param config - Editor configuration shared by every image
|
|
171
|
+
* @param startIndex - 0-based index of the image to open first
|
|
172
|
+
* @returns One `{ index, edited, result }` per image on Apply, or null if closed
|
|
173
|
+
*/
|
|
174
|
+
openMultiEditor(images, config, startIndex) {
|
|
175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
return openMultiEditorModal({ images, config, startIndex });
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
RpImageEditorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
181
|
+
RpImageEditorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorService, providedIn: 'root' });
|
|
182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorService, decorators: [{
|
|
183
|
+
type: Injectable,
|
|
184
|
+
args: [{
|
|
185
|
+
providedIn: 'root',
|
|
186
|
+
}]
|
|
187
|
+
}] });
|
|
188
|
+
|
|
189
|
+
class RpImageEditorModule {
|
|
190
|
+
/**
|
|
191
|
+
* Use forRoot() if you want to provide the service at root level
|
|
192
|
+
* (optional — service is already providedIn: 'root')
|
|
193
|
+
*/
|
|
194
|
+
static forRoot() {
|
|
195
|
+
return {
|
|
196
|
+
ngModule: RpImageEditorModule,
|
|
197
|
+
providers: [RpImageEditorService],
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
RpImageEditorModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
202
|
+
RpImageEditorModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, declarations: [RpImageEditorComponent], imports: [CommonModule], exports: [RpImageEditorComponent] });
|
|
203
|
+
RpImageEditorModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, providers: [RpImageEditorService], imports: [CommonModule] });
|
|
204
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: RpImageEditorModule, decorators: [{
|
|
205
|
+
type: NgModule,
|
|
206
|
+
args: [{
|
|
207
|
+
declarations: [RpImageEditorComponent],
|
|
208
|
+
imports: [CommonModule],
|
|
209
|
+
exports: [RpImageEditorComponent],
|
|
210
|
+
providers: [RpImageEditorService],
|
|
211
|
+
}]
|
|
212
|
+
}] });
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @rageshpikalmunde/rp-image-editor-angular
|
|
216
|
+
* Angular wrapper for the rp-image-editor plugin
|
|
217
|
+
*/
|
|
218
|
+
// Module
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Generated bundle index. Do not edit.
|
|
222
|
+
*/
|
|
223
|
+
|
|
224
|
+
export { RpImageEditorComponent, RpImageEditorModule, RpImageEditorService };
|
|
225
|
+
//# sourceMappingURL=rageshpikalmunde-rp-image-editor-angular.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rageshpikalmunde-rp-image-editor-angular.mjs","sources":["../../src/lib/rp-image-editor.component.ts","../../src/lib/rp-image-editor.service.ts","../../src/lib/rp-image-editor.module.ts","../../src/index.ts","../../src/rageshpikalmunde-rp-image-editor-angular.ts"],"sourcesContent":["import { Component, ElementRef, EventEmitter, Inject, Input, OnDestroy, Output, PLATFORM_ID, ViewChild, AfterViewInit } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { RpImageEditor, RpEditorConfig, RpEditorResult } from '@rageshpikalmunde/rp-image-editor';\n\n@Component({\n selector: 'rp-image-editor',\n template: `<div #editorContainer class=\"rp-image-editor-host\" [style.width]=\"'100%'\" [style.height]=\"'100%'\" [style.display]=\"'flex'\" [style.flexDirection]=\"'column'\"></div>`,\n styles: [`:host { display: block; width: 100%; height: 100%; } .rp-image-editor-host { min-height: 300px; }`]\n})\nexport class RpImageEditorComponent implements AfterViewInit, OnDestroy {\n @ViewChild('editorContainer', { static: true }) containerRef!: ElementRef<HTMLElement>;\n\n /** Image source — File, Blob, or URL string */\n @Input() image: File | Blob | string | null = null;\n\n /** Editor configuration */\n @Input() config: Partial<RpEditorConfig> = {};\n\n /** Emitted when user clicks Apply — contains the edited image result */\n @Output() imageEdited = new EventEmitter<RpEditorResult>();\n\n /** Emitted when user clicks Close/Cancel */\n @Output() editorClosed = new EventEmitter<void>();\n\n /** Emitted when an error occurs */\n @Output() editorError = new EventEmitter<Error>();\n\n private editor: RpImageEditor | null = null;\n\n /** False during server-side rendering, where there is no DOM/canvas. */\n private readonly isBrowser: boolean;\n\n constructor(@Inject(PLATFORM_ID) platformId: object) {\n this.isBrowser = isPlatformBrowser(platformId);\n }\n\n ngAfterViewInit(): void {\n if (this.image) {\n this.initEditor();\n }\n }\n\n ngOnDestroy(): void {\n this.destroyEditor();\n }\n\n /**\n * Programmatically load an image (can be called after component init)\n */\n async loadImage(source: File | Blob | string): Promise<void> {\n this.image = source;\n await this.initEditor();\n }\n\n /**\n * Get the edited result programmatically\n */\n async getResult(): Promise<RpEditorResult | null> {\n try {\n return await this.editor?.getResult() ?? null;\n } catch (err) {\n this.editorError.emit(err as Error);\n return null;\n }\n }\n\n /**\n * Apply and emit result\n */\n async apply(): Promise<void> {\n const result = await this.getResult();\n if (result) {\n this.imageEdited.emit(result);\n }\n }\n\n /**\n * Close the editor\n */\n close(): void {\n this.destroyEditor();\n this.editorClosed.emit();\n }\n\n /**\n * Reset to original image\n */\n async reset(): Promise<void> {\n await this.editor?.reset();\n }\n\n private async initEditor(): Promise<void> {\n this.destroyEditor();\n\n if (!this.isBrowser || !this.image || !this.containerRef?.nativeElement) return;\n\n this.editor = new RpImageEditor(this.containerRef.nativeElement, this.config);\n\n this.editor.on('error', (err) => {\n this.editorError.emit(err);\n });\n\n try {\n await this.editor.loadImage(this.image);\n } catch (err) {\n this.editorError.emit(err as Error);\n }\n }\n\n private destroyEditor(): void {\n if (this.editor) {\n this.editor.destroy();\n this.editor = null;\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n RpEditorConfig,\n RpEditorResult,\n RpMultiEditorItemResult,\n openEditorModal,\n openMultiEditorModal,\n} from '@rageshpikalmunde/rp-image-editor';\n\n/**\n * Service to open the image editor as a modal overlay.\n * Works with or without Ionic — uses the core modal implementation.\n *\n * Usage:\n * ```ts\n * constructor(private rpEditor: RpImageEditorService) {}\n *\n * async editImage(file: File) {\n * const result = await this.rpEditor.openEditor(file, {\n * theme: { applyButtonBackground: '#28a745' }\n * });\n * if (result) {\n * // result.file — upload to server\n * // result.base64 — preview\n * }\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class RpImageEditorService {\n /**\n * Open the image editor in a modal popup.\n *\n * @param image - File, Blob, or URL string to edit\n * @param config - Optional editor configuration (theme, crop ratios, etc.)\n * @returns Promise resolving to RpEditorResult if applied, or null if cancelled\n */\n async openEditor(\n image: File | Blob | string,\n config?: Partial<RpEditorConfig>\n ): Promise<RpEditorResult | null> {\n return openEditorModal({\n image,\n config,\n });\n }\n\n /**\n * Edit several images in one modal with a thumbnail strip.\n *\n * @param images - Files, Blobs or URL strings, in strip order\n * @param config - Editor configuration shared by every image\n * @param startIndex - 0-based index of the image to open first\n * @returns One `{ index, edited, result }` per image on Apply, or null if closed\n */\n async openMultiEditor(\n images: Array<File | Blob | string>,\n config?: Partial<RpEditorConfig>,\n startIndex?: number\n ): Promise<RpMultiEditorItemResult[] | null> {\n return openMultiEditorModal({ images, config, startIndex });\n }\n}\n","import { NgModule, ModuleWithProviders } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { RpImageEditorComponent } from './rp-image-editor.component';\nimport { RpImageEditorService } from './rp-image-editor.service';\n\n@NgModule({\n declarations: [RpImageEditorComponent],\n imports: [CommonModule],\n exports: [RpImageEditorComponent],\n providers: [RpImageEditorService],\n})\nexport class RpImageEditorModule {\n /**\n * Use forRoot() if you want to provide the service at root level\n * (optional — service is already providedIn: 'root')\n */\n static forRoot(): ModuleWithProviders<RpImageEditorModule> {\n return {\n ngModule: RpImageEditorModule,\n providers: [RpImageEditorService],\n };\n }\n}\n","/**\n * @rageshpikalmunde/rp-image-editor-angular\n * Angular wrapper for the rp-image-editor plugin\n */\n\n// Module\nexport { RpImageEditorModule } from './lib/rp-image-editor.module';\n\n// Component\nexport { RpImageEditorComponent } from './lib/rp-image-editor.component';\n\n// Service\nexport { RpImageEditorService } from './lib/rp-image-editor.service';\n\n// Re-export types from core\nexport type {\n RpEditorConfig,\n RpEditorTheme,\n RpEditorResult,\n RpMultiEditorItemResult,\n CropAspectRatio,\n EditorMode,\n} from '@rageshpikalmunde/rp-image-editor';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|