angular - آرگومان از نوع 'HTMLElement' قابل انتساب به پارامتر از نوع 'CanvasImageSource' نیست


من دارم تلاش میکنم که همان تصویر در تمام بومهای صفحه HTML من بارگذاری شود. قبلاً کل وبسایتم را با جاوااسکریپت نوشته بودم اما حالا دارم انگولار و تایپاسکریپت یاد میگیرم.

من این خطا را که در ویژوال استودیو کد برجسته شده است، دریافت میکنم:

آرگومان از نوع 'HTMLElement' قابل اختصاص به پارامتر از نوع 'CanvasImageSource' نیست. نوع 'HTMLElement' خواص زیر را از نوع 'HTMLVideoElement' ندارد: height، msHorizontalMirror، msIsLayoutOptimalForPlayback، msIsStereo3D، و 80 مورد دیگر. ts(2345)

اما هیچ خطایی در کنسول نمایش داده نمیشود. من میتوانم تصویر را در HTML داخل بوم بارگذاری کنم (پس کار میکند).

این 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 خطا را در این خط ctx.drawImage(img,0,0,106,50); //(image, offsetx, offsety, x, y) نشان میدهد، img را برجسته میکند و خطا را نمایش میدهد.

من سعی کردهام این را جستجو کنم اما تنها راهحلهایی که پیدا کردهام برای زمانی است که شما شناسهی تگ را داشته باشید (من ندارم چون همه آنها در صفحه، بوم هستند) یا اگر ورودی وجود داشته باشد.

هر کمکی قابل تقدیر است.

پاسخ شماره ۱

شما باید به کامپایلر بگویید که متغیر img به عنوان یک HTMLImageElement تنظیم شده است.

متد ctx.drawImage انتظار دارد یک :

HTMLOrSVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap;

اگر P43 شما یک بوم است، باید انجام دهید:

const img = document.getElementById("P43") as HTMLCanvasElement;

اگر این یک عنصر تصویر باشد:

const img = document.getElementById("P43") as HTMLImageElement;

حتی بهتر است که در واقع بررسی کنید که عنصر در واقع نوع درست Element است. شما میتوانید این کار را با instanceof انجام دهید. کامپایلر TypeScript همچنین if statement را تشخیص خواهد داد، و داخل if statement متغیر img برای کامپایلر یک HTMLCanvasElement خواهد بود، بنابراین دیگر نیازی به تبدیل صریح نیست:

const img = document.getElementById("P43");

if (img instanceof HTMLImageElement) {
  ctx.drawImage(img,0,0,106,50);
} else {
  // wrong element!
}

پاسخ شماره ۲

شما نیاز دارید به کامپایلر TS نوع دقیق عناصر HTML که در کامپوننت خود استفاده میکنید را بگویید.

در اینجا شما در حال پرسوجو از شیء سند هستید و برخی عناصر را دریافت کرده و برخی متدها را روی آن عناصر فراخوانی میکنید. از آنجا که تایپاسکریپت قادر به استنتاج نوع این عناصر نیست و در نتیجه خطاهای کامپایلر ایجاد میکند، نوع باید بهطور صریح اعلام شود.

این را امتحان کن:

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);
    });
  }
}