Почему мой холст не всегда отображает нарисованное изображение? - PullRequest
0 голосов
/ 28 сентября 2019

В моем ионном приложении я пытаюсь масштабировать фотографию и нарисовать ее на холсте.Вот мой код:

HTML:

<ion-header>
  <ion-toolbar>
      <ion-icon name="camera" slot="start" style="padding-left: 8px; font-size: x-large"></ion-icon>
      <ion-title>Photo</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <canvas id="mainCanvas" #mainCanvas style="display: block; padding-top: 20px; margin: 10px auto; height: 90%;"></canvas>
</ion-content>

<ion-footer>
  <ion-item lines="none">
    <ion-tabs tabsPlacement="bottom">
      <ion-tab-bar slot="bottom">
        <ion-tab-button size="small" (click)="openCamera()">
          <ion-icon name="camera"></ion-icon>
          <ion-label>Add Photo</ion-label>
        </ion-tab-button>
      </ion-tab-bar>
    </ion-tabs>
  </ion-item>
</ion-footer>

.ts:

private updateCanvas() {
    const img = new Image();
    const ctx = this._CONTEXT;
    const canvas = this._CANVAS;

    // set final size of image to be displayed (half the size of the screen, to allow for other controls to be shown)
    const displayWidth = this.plt.width() / 1.60;
    const displayHeight = this.plt.height() / 1.60;

    canvas.width = displayWidth;
    canvas.height = displayHeight;

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "#ff0000";

    if (this.photo == null) {
      console.log("updateCanvas: photo object is null");
      return;
    }      

    // Create an offscreen buffer to draw the full-sized photo onto
    const bufferCanvas = document.createElement('canvas');
    const bufferCtx = bufferCanvas.getContext('2d');

    const path = this.file.dataDirectory + this.photo.id + "." + this.photo.file_extension;

    img.onload = (() => {
      console.log("updateCanvas > img.onload > photo: ", this.photo);
      // Scale the buffer canvas to match original size of photo
      bufferCanvas.width = img.width;
      bufferCanvas.height = img.height;

      if (bufferCtx && ctx) {
        // Draw photo to buffer canvas
        console.log("updateCanvas > drawing onto buffer...");
        bufferCtx.drawImage(img, 0, 0);

        // Get the photo and main canvas aspect ratios
        const imgAspect = img.height / img.width;
        const mainAspect = canvas.height / canvas.width;

        // Should the image fill the canvas width, or height?
        const fillWidth = true; // imgAspect > mainAspect;

        // Determine the new scale of the image so that it covers the main canvas
        // This would need adjusting if we wanted it contained within the main canvas (no overhang)
        const scaledWidth = fillWidth ? displayWidth : displayHeight / imgAspect;
        const scaledHeight = fillWidth ? displayWidth * imgAspect : displayHeight;

        // Translate to the center of the main canvas
        ctx.translate(displayWidth / 2, displayHeight / 2);

        // Draw the buffer to the main canvas
        // Take off half the scaled dimensions so that it doesn't draw in the bottom right corner
        ctx.drawImage(bufferCanvas, -scaledWidth / 2, -scaledHeight / 2, scaledWidth, scaledHeight);        
      }
    });

    console.log("updateCanvas > path: ", path);
    img.src = (<any>window).Ionic.WebView.convertFileSrc(path);
}

Тем не менее, мой метод updateCanvas работает только случайным образом при вызове.Это совершенно случайно, иногда он будет рисовать после двух звонков, иногда только после 7 звонков.Кто-нибудь может определить, что мешает рисованию холста?Я проверил, что файл фотографии существует в папке, указанной переменной пути.Если я рисую на холсте без масштабирования, изображение рисуется на холсте без проблем.

edit1: заметил что-то странное - когда я отображаю предупреждение перед обновлением холста, на холсте отображается правильно масштабированная фотография.Например,

this.presentAlert("test", "test")
.then(() => this.updateCanvas());
...