Как сделать фотографию перетаскиваемой в кадре? - PullRequest
1 голос
/ 09 апреля 2020

Я использую этот модал из 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;
}

Как описано выше, я ожидайте, что фотография будет загружена в рамку в модальном теле, и что размер рамки всегда будет оставаться неизменным. мне, независимо от того, насколько мала или велика фотография, и я могу перетащить саму фотографию в рамку.

Заранее спасибо.

...