html - Hur man visar en uppladdad bild som en canvasbakgrund direkt?


Jag använder TypeScript för att sätta en bild uppladdad av användare som bakgrund på en canvas. Men, och jag antar på grund av något bindningsproblem, fungerar det bara när användaren laddar upp filen två gånger. Hur kan jag vänta på att bilden laddas innan jag försöker sätta den som bakgrund på en canvas?

Jag har försökt köra canvas-koden endast när variabeln selectedFile inte är null (se nedan) men jag får samma fel.

<input type="file" (change)="onFileChanged($event)">
<canvas id="canvas"></canvas>
private selectedFile: File = null;
private imgURL: any;

onFileChanged(event){
    if(event.target.files.length == 0)  return;
    this.selectedFile = <File> event.target.files[0];
    var reader = new FileReader();
    reader.readAsDataURL(this.selectedFile);
    reader.onload = (_event) => {this.imgURL = reader.result;}

    var canvas : any = document.getElementById("canvas");
    var ctxt = canvas.getContext("2d");
    var background = new Image();
    background.src = this.imgURL;
    background.onload = function () {
      ctxt.drawImage(background, 0, 0, canvas.width, canvas.height);
    };
}

Jag förväntar mig att duken visar den valda bilden som bakgrund. Men första gången användaren laddar upp en bild, blir resultatet GET http://localhost:4200/undefined 404 (Not Found) Image (async). När användaren laddar upp en annan bild uppdateras bakgrunden till den första valda bilden.

Svar #1

Jag tror att allt du behöver göra är att lägga din canvas-kod inne i reader.onload-callbacken.

onFileChanged(event) {
  if (event.target.files.length == 0) return;
    this.selectedFile = < File > event.target.files[0];
    var reader = new FileReader();
    reader.readAsDataURL(this.selectedFile);

    reader.onload = (_event) => {
      this.imgURL = reader.result;
      var canvas: any = document.getElementById("canvas");
      var ctxt = canvas.getContext("2d");
      var background = new Image();
      background.src = this.imgURL;
      background.onload = function() {
      ctxt.drawImage(background, 0, 0, canvas.width, canvas.height);
    };
  }
}

Du fick troligen ditt fel eftersom din .onload asynkrona callback inte hade triggat än och this.imgURL skulle vara undefined när du försökte använda det. Nu väntar det tills vi har ett värde för imgURL innan det försöker använda det.