diff --git a/README.md b/README.md index 20752e2..6737bf1 100644 --- a/README.md +++ b/README.md @@ -149,24 +149,25 @@ To gain access to the image cropper's methods use `@ViewChild(ImageCropperCompon | y2 | number | Y position of second coordinate (in px) | #### ImageTransform -| Property | Type | Description | -|---------------|----------|-----------------------------------------| -| scale | number | Scale image (1=normal, 2=2x zoom...) | -| rotate | number | Rotation in degrees | -| flipH | boolean | Flipped horizontally | -| flipV | boolean | Flipped vertically | -| translateH | number | Move horizontally (in %) | -| translateV | number | Moved vertically (in %) | +| Property | Type | Description | +|---------------|----------|---------------------------------------------------------| +| scale | number | Scale image (1=normal, 2=2x zoom...) | +| rotate | number | Rotation in degrees | +| flipH | boolean | Flipped horizontally | +| flipV | boolean | Flipped vertically | +| translateH | number | Move horizontally (in %) | +| translateV | number | Moved vertically (in %) | +| translateUnit | number | The unit used for the translate (% or px) (default = %) | #### ImageCroppedEvent -| Property | Type | Description | -| -------------------- | ------ | ----------- | -| base64 | string | Base64 string of the cropped image | -| width | number | Width of the cropped image | -| height | number | Height of the cropped image | -| cropperPosition | CropperPosition | Position of the cropper when it was cropped relative to the displayed image size | -| imagePosition | CropperPosition | Position of the cropper when it was cropped relative to the original image size | -| offsetImagePosition | CropperPosition | Position of the cropper when it was cropped relative to the original image size without padding when containWithinAspectRatio is true | +| Property | Type | Description | +|---------------------| ------ | ----------- | +| base64 | string | Base64 string of the cropped image | +| width | number | Width of the cropped image | +| height | number | Height of the cropped image | +| cropperPosition | CropperPosition | Position of the cropper when it was cropped relative to the displayed image size | +| imagePosition | CropperPosition | Position of the cropper when it was cropped relative to the original image size | +| offsetImagePosition | CropperPosition | Position of the cropper when it was cropped relative to the original image size without padding when containWithinAspectRatio is true | #### LoadedImage | Property | Type | Description | diff --git a/projects/demo-app/src/app/app.component.ts b/projects/demo-app/src/app/app.component.ts index 5e725d7..089ea6c 100644 --- a/projects/demo-app/src/app/app.component.ts +++ b/projects/demo-app/src/app/app.component.ts @@ -17,7 +17,9 @@ export class AppComponent { aspectRatio = 4 / 3; showCropper = false; containWithinAspectRatio = false; - transform: ImageTransform = {}; + transform: ImageTransform = { + translateUnit: 'px' + }; imageURL?: string; loading = false; allowMoveImage = false; @@ -120,7 +122,9 @@ export class AppComponent { this.scale = 1; this.rotation = 0; this.canvasRotation = 0; - this.transform = {}; + this.transform = { + translateUnit: 'px' + }; } zoomOut() { @@ -153,8 +157,4 @@ export class AppComponent { toggleAspectRatio() { this.aspectRatio = this.aspectRatio === 4 / 3 ? 16 / 5 : 4 / 3; } - - onImageDragged(transform: ImageTransform) { - this.transform = {...transform}; - } } diff --git a/projects/ngx-image-cropper/package.json b/projects/ngx-image-cropper/package.json index 39fff2a..35e0d18 100644 --- a/projects/ngx-image-cropper/package.json +++ b/projects/ngx-image-cropper/package.json @@ -1,6 +1,6 @@ { "name": "ngx-image-cropper", - "version": "6.2.0", + "version": "6.2.1", "description": "An image cropper for Angular", "author": "Martijn Willekens", "repository": { @@ -14,6 +14,7 @@ "keywords": [ "angular", "angular 13", + "angular 14", "ionic", "ionic-angular", "cropper", diff --git a/projects/ngx-image-cropper/src/index.ts b/projects/ngx-image-cropper/src/index.ts new file mode 100644 index 0000000..9007524 --- /dev/null +++ b/projects/ngx-image-cropper/src/index.ts @@ -0,0 +1,6 @@ +export * from './lib/component/image-cropper.component'; +export * from './lib/services/crop.service'; +export * from './lib/image-cropper.module'; +export * from './lib/interfaces'; +export { base64ToFile } from './lib/utils/blob.utils'; +export { resizeCanvas } from './lib/utils/resize.utils'; diff --git a/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts b/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts index 8df730b..97ef66b 100644 --- a/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts +++ b/projects/ngx-image-cropper/src/lib/component/image-cropper.component.ts @@ -174,11 +174,12 @@ export class ImageCropperComponent implements OnChanges, OnInit { } private setCssTransform() { + const translateUnit = this.transform?.translateUnit || '%'; this.safeTransformStyle = this.sanitizer.bypassSecurityTrustStyle( 'scaleX(' + (this.transform.scale || 1) * (this.transform.flipH ? -1 : 1) + ')' + 'scaleY(' + (this.transform.scale || 1) * (this.transform.flipV ? -1 : 1) + ')' + 'rotate(' + (this.transform.rotate || 0) + 'deg)' + - `translate(${this.transform.translateH || 0}%, ${this.transform.translateV || 0}%)` + `translate(${this.transform.translateH || 0}${translateUnit}, ${this.transform.translateV || 0}${translateUnit})` ); } diff --git a/projects/ngx-image-cropper/src/lib/interfaces/image-transform.interface.ts b/projects/ngx-image-cropper/src/lib/interfaces/image-transform.interface.ts index 2855217..23a10a6 100644 --- a/projects/ngx-image-cropper/src/lib/interfaces/image-transform.interface.ts +++ b/projects/ngx-image-cropper/src/lib/interfaces/image-transform.interface.ts @@ -5,4 +5,5 @@ export interface ImageTransform { flipV?: boolean; translateH?: number; translateV?: number; + translateUnit?: '%' | 'px'; } diff --git a/projects/ngx-image-cropper/src/lib/services/crop.service.ts b/projects/ngx-image-cropper/src/lib/services/crop.service.ts index 87e7390..19c604f 100644 --- a/projects/ngx-image-cropper/src/lib/services/crop.service.ts +++ b/projects/ngx-image-cropper/src/lib/services/crop.service.ts @@ -4,7 +4,7 @@ import { CropperSettings } from '../interfaces/cropper.settings'; import { resizeCanvas } from '../utils/resize.utils'; import { percentage } from '../utils/percentage.utils'; -@Injectable({ providedIn: 'root' }) +@Injectable({providedIn: 'root'}) export class CropService { crop(sourceImage: ElementRef, loadedImage: LoadedImage, cropper: CropperPosition, settings: CropperSettings): ImageCroppedEvent | null { @@ -32,9 +32,7 @@ export class CropService { ctx.translate(-imagePosition.x1 / scaleX, -imagePosition.y1 / scaleY); ctx.rotate((settings.transform.rotate || 0) * Math.PI / 180); - const translateH = settings.transform.translateH ? percentage(settings.transform.translateH, transformedImage.size.width) : 0; - const translateV = settings.transform.translateV ? percentage(settings.transform.translateV, transformedImage.size.height) : 0; - + const {translateH, translateV} = this.getCanvasTranslate(sourceImage, loadedImage, settings); ctx.drawImage( transformedImage.image, translateH - transformedImage.size.width / 2, @@ -44,7 +42,7 @@ export class CropService { const output: ImageCroppedEvent = { width, height, imagePosition, - cropperPosition: { ...cropper } + cropperPosition: {...cropper} }; if (settings.containWithinAspectRatio) { output.offsetImagePosition = this.getOffsetImagePosition(sourceImage, loadedImage, cropper, settings); @@ -61,10 +59,28 @@ export class CropService { return output; } - private getImagePosition(sourceImage: ElementRef, loadedImage: LoadedImage, cropper: CropperPosition, settings: CropperSettings): CropperPosition { + private getCanvasTranslate(sourceImage: ElementRef, loadedImage: LoadedImage, settings: CropperSettings): { translateH: number, translateV: number } { + if (settings.transform.translateUnit === 'px') { + const ratio = this.getRatio(sourceImage, loadedImage); + return { + translateH: (settings.transform.translateH || 0) * ratio, + translateV: (settings.transform.translateV || 0) * ratio + }; + } else { + return { + translateH: settings.transform.translateH ? percentage(settings.transform.translateH, loadedImage.transformed.size.width) : 0, + translateV: settings.transform.translateV ? percentage(settings.transform.translateV, loadedImage.transformed.size.height) : 0 + }; + } + } + + private getRatio(sourceImage: ElementRef, loadedImage: LoadedImage): number { const sourceImageElement = sourceImage.nativeElement; - const ratio = loadedImage.transformed.size.width / sourceImageElement.offsetWidth; + return loadedImage.transformed.size.width / sourceImageElement.offsetWidth; + } + private getImagePosition(sourceImage: ElementRef, loadedImage: LoadedImage, cropper: CropperPosition, settings: CropperSettings): CropperPosition { + const ratio = this.getRatio(sourceImage, loadedImage); const out: CropperPosition = { x1: Math.round(cropper.x1 * ratio), y1: Math.round(cropper.y1 * ratio), diff --git a/projects/ngx-image-cropper/src/public-api.ts b/projects/ngx-image-cropper/src/public-api.ts index eded29e..ea465c2 100644 --- a/projects/ngx-image-cropper/src/public-api.ts +++ b/projects/ngx-image-cropper/src/public-api.ts @@ -1,5 +1 @@ -export * from './lib/component/image-cropper.component'; -export * from './lib/image-cropper.module'; -export * from './lib/interfaces'; -export { base64ToFile } from './lib/utils/blob.utils'; -export { resizeCanvas } from './lib/utils/resize.utils'; +export * from './index';