Я использую этот модал из https://ng-bootstrap.github.io/# / components / modal / examples , где я загружаю это изображение обрезкой из https://github.com/Mawi137/ngx-image-cropper
В настоящее время холст будет будет отображаться во всю ширину и высоту фотографии, после выбора.
Example1
Example2
То, что я хочу, это чтобы фотография была загружена в рамку модального тела и чтобы рамка всегда оставалась неизменной, независимо от того, насколько она мала или велика, и могла перетаскивать саму фотографию в рамке.
Я посмотрел на другие рамки обрезки, где это возможно, один из них: https://fengyuanchen.github.io/cropperjs/, но, к сожалению, мне пока не удалось реализовать его в моем собственном приложении.
cropModalComponent. ts:
import { Component } from '@angular/core';
import { InternationalizationService } from '../internationalization.service';
import { ImageCroppedEvent, ImageTransform } from 'ngx-image-cropper';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-crop-modal',
templateUrl: './cropModal.component.html',
styleUrls: ['./cropModal.component.css']
})
export class CropModalComponent {
i18n = null;
imageChangedEvent: any = '';
croppedImage: any = '';
canvasRotation = 0;
resizeToWidth: boolean = true;
resizeToHeight: boolean = true;
maintainAspectRatio: boolean = true;
transform: ImageTransform = {};
showCropper = false;
modalTitle: string = 'Change profile picture';
preview: string = 'Preview';
page1: boolean = true;
page2: boolean = false;
page3: boolean = false;
closeResult = '';
scale = 1;
constructor(
private i18nService: InternationalizationService,
private modalService: NgbModal) {
this.i18nService.getTranslations().subscribe(
response => {
this.i18n = response;
}
);
this.i18n = this.i18nService.geti18n();
}
open(content) {
this.modalService.open(content).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
console.log(this.closeResult);
}, () => {
this.resetCropperState();
});
}
cropPreview() {
this.page2 = false;
this.page3 = true;
this.modalTitle = 'Preview';
}
resetToPage2() {
this.page2 = true;
this.page3 = false;
this.modalTitle = 'Crop framework'
}
public resetCropperState() {
this.page2 = false;
this.page3 = false;
this.croppedImage = null;
this.modalTitle = 'Change profile picture';
this.imageChangedEvent = null;
}
fileChangeEvent(event: any): void {
this.imageChangedEvent = event;
}
imageCropped(event: ImageCroppedEvent) {
this.croppedImage = event.base64;
}
cropperReady() {
}
loadImageFailed() {
}
rotateLeft() {
this.canvasRotation--;
this.flipAfterRotate();
}
imageLoaded() {
this.modalTitle = "Crop framework";
this.page2 = true;
}
rotateRight() {
this.canvasRotation++;
this.flipAfterRotate();
}
private flipAfterRotate() {
const flippedH = this.transform.flipH;
const flippedV = this.transform.flipV;
this.transform = {
...this.transform,
flipH: flippedV,
flipV: flippedH
};
}
saveButton() {
this.resetCropperState();
}
zoomOut() {
this.scale -= .1;
this.transform = {
...this.transform,
scale: this.scale
};
}
zoomIn() {
this.scale += .1;
this.transform = {
...this.transform,
scale: this.scale
};
}
}
cropModal.component. html:
<button class="btn btn-light" (click)="open(content)"><i class="fa fa-edit"></i></button>
<ng-template #content let-modal>
<div class="modal-header">
<button *ngIf="page2 || page3" type="button" class="btn btn-outline-primary" aria-label="Back"
(click)="page2 ? resetCropperState() : resetToPage2()">
<i class="fa fa-arrow-left"></i>
</button>
<h4 class="modal-title" id="modal-basic-title">{{modalTitle}}</h4>
<button type="button" class="btn btn-outline-danger" aria-label="Close" (click)="modal.dismiss('Cross click')">
<i class="fa fa-times"></i>
</button>
</div>
<div class="modal-body mx-auto">
<image-cropper [imageChangedEvent]="imageChangedEvent" [maintainAspectRatio]="true"
[style.display]="page2 ? null : 'none'" [aspectRatio]="1 / 1" [resizeToWidth]="256" [cropperMinWidth]="128"
[onlyScaleDown]="true" [roundCropper]="true" [canvasRotation]="canvasRotation" [transform]="transform"
[alignImage]="'center'" format="png" (imageCropped)="imageCropped($event)" (imageLoaded)="imageLoaded()"
(cropperReady)="cropperReady($event)" (loadImageFailed)="loadImageFailed()">
</image-cropper>
<ng-container *ngIf="page3 && croppedImage">
<img [src]="croppedImage" />
</ng-container>
</div>
<div class="modal-footer mx-auto">
<input type="file" *ngIf="!page2 && !page3" (change)="fileChangeEvent($event)" />
<button type="button" *ngIf="page2" class="btn btn-primary" (click)="rotateLeft()"><i
class="fa fa-undo"></i></button>
<button type="button" *ngIf="page2" class="btn btn-primary" (click)="rotateRight()"><i
class="fa fa-repeat"></i></button>
<button type="button" *ngIf="page2" class="btn btn-primary" (click)="zoomOut()"><i
class="fa fa-search-minus"></i></button>
<button type="button" *ngIf="page2" class="btn btn-primary" (click)="zoomIn()"><i
class="fa fa-search-plus"></i></button>
<button type="button" *ngIf="page2" class="btn btn-primary" (click)="cropPreview()"><i
class="fa fa-crop"></i></button>
<button type="button" *ngIf="page3" class="btn btn-success" (click)="saveButton(); modal.close()"><i
class="fa fa-check"></i></button>
</div>
</ng-template>
cropModal.component. css:
img {
border-radius: 100%;
border: 1px solid #000000;
}
image-cropper {
height: 50vh;
}
Как описано выше, я ожидайте, что фотография будет загружена в рамку в модальном теле, и что размер рамки всегда будет оставаться неизменным. мне, независимо от того, насколько мала или велика фотография, и я могу перетащить саму фотографию в рамку.
Заранее спасибо.