angular - Argument typu 'HTMLElement' nemožno priradiť k parametru typu 'CanvasImageSource'
Snažím sa načítať ten istý obrázok do všetkých plátien (canvas) v mojom HTML. Predtým som celý svoj web napísal v JavaScripte, ale teraz sa učím Angular a TypeScript.
Túto chybu vidím zvýraznenú vo Visual Studio Code:
Argument typu 'HTMLElement' nie je priraditeľný k parametru typu 'CanvasImageSource'. Typ 'HTMLElement' postráda nasledujúce vlastnosti typu 'HTMLVideoElement': height, msHorizontalMirror, msIsLayoutOptimalForPlayback, msIsStereo3D a ďalších 80.ts(2345)
Ale v konzole sa nezobrazuje žiadna chyba. Dokážem načítať obrázok na HTML v rámci plátna (takže to funguje).
Toto je môj ts:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
constructor() { }
ngOnInit() {
document.querySelectorAll("canvas").forEach(c=>{
var ctx = c.getContext("2d");
var img = document.getElementById("P43");
ctx.drawImage(img,0,0,106,50); //(image, offsetx, offsety, x, y)
});
}
}
VS Code zvýrazní chybu na tomto riadku ctx.drawImage(img,0,0,106,50); //(image, offsetx, offsety, x, y), zvýrazní img a zobrazí chybu.
Snažil som sa to vyhľadať, ale jediné riešenia, ktoré som našiel, sú pre prípad, keď máte ID tagu (ja ho nemám, pretože na stránke sú len canvasy) alebo ak je tam vstupný prvok.
Akákoľvek pomoc je ocenená.
Odpoveď č. 1
Musíte kompilátoru povedať, že premenná img je nastavená ako HTMLImageElement.
Metóda ctx.drawImage očakáva :
HTMLOrSVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap;
Ak je váš P43 plátno, musíte urobiť:
const img = document.getElementById("P43") as HTMLCanvasElement;
ak ide o prvok obrázka:
const img = document.getElementById("P43") as HTMLImageElement;
Bolo by ešte lepšie skutočne skontrolovať, či je prvok skutočne správneho typu Element. Môžete to urobiť pomocou instanceof. Kompilátor TypeScriptu si tiež všimne if podmienku, a vo vnútri tejto if podmienky bude pre kompilátor premenná img typu HTMLCanvasElement, takže explicitné typovanie už nie je potrebné:
const img = document.getElementById("P43");
if (img instanceof HTMLImageElement) {
ctx.drawImage(img,0,0,106,50);
} else {
// wrong element!
}
Odpoveď č. 2
Musíte kompilátoru TS povedať konkrétne typy HTML elementov, ktoré vo vašej komponente používate.
Tu si dotazujete objekt dokumentu a získavate nejaký element a voláte na týchto elementoch niektoré metódy. Keďže TypeScript nedokáže odvodiť typy týchto elementov a preto produkuje chyby kompilátora, typ je potrebné explicitne uviesť.
Skús toto:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit {
constructor() { }
ngOnInit() {
document.querySelectorAll('canvas').forEach((c: HTMLCanvasElement) => {
const ctx = <CanvasRenderingContext2D> c.getContext('2d');
const img = <HTMLImageElement> document.getElementById('P43');
ctx.drawImage(img, 0, 0, 106, 50);
});
}
}
