Typescript / JavaScript:为什么即使初始化了画布,我的画布和画布上下文仍未定义?

问题描述 投票:0回答:1

我正在Angular的Typescript中使用网格。我将画布和上下文定义为全局变量,并在ngOnInit()中对其进行了初始化。然后,我调用一个使用画布和上下文的函数。在控制台中,出现以下错误:ERROR TypeError: Cannot read property 'ctxGrid' of undefined at resetGrid (grid-draw.component.ts:69)

我不知道我在做什么错,因为我已经初始化了两个变量。这可能是我不知道的。谢谢。这是我的代码:

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';

@Component({
  selector: 'app-grid-draw',
  templateUrl: './grid-draw.component.html',
  styleUrls: ['./grid-draw.component.css']
})
export class GridDrawComponent implements OnInit {

  constructor() { }

  @ViewChild('canvas', { static: true })



  shapes;
  canvas;
  ctxGrid;
  ngOnInit(): void {
    const animDelay = 5;
    const startNodeColor = "#FF3600";
    const endNodeColor = "#00AB5C";

    //initialize array an grid
    this.shapes = new Array(100);
    for (let i = 0; i < this.shapes.length; i++) { this.shapes[i] = new Array(100) };
    this.canvas = <HTMLCanvasElement>document.getElementById('myCanvas');
    this.ctxGrid = this.canvas.getContext('2d');
    resetGrid();

    //walls
    this.canvas.addEventListener('mousemove', function (e) {
      const rect = this.canvas.getBoundingClientRect();

      let cx = e.clientX - rect.left;
      let cy = e.clientY - rect.top;
      //draw_erase_walls(e, cx, cy);
    })

    //single click for start and end nodes
    this.canvas.addEventListener('mousedown', function (e) {
      const rect = this.canvas.getBoundingClientRect();
      let cx = e.clientX - rect.left;
      let cy = e.clientY - rect.top;
      //changeStart(cx, cy);
      //changeEnd(cx, cy);
    })

    function resetGrid() {
      this.ctxGrid.lineWidth = 0.05;
      //grid with rectangles
      for (let i = 0; i < this.shapes.length; i++) {
        for (let j = 0; j < this.shapes[i].length; j++) {
          //variables
          let x = i * 20;
          let y = j * 20;
          let l = 20, w = 20;
          let type = ""

          //a* algorithm info
          let F = 0;
          let G = 0;
          let H = 0;
          if (i == 4 && j == 4) {    
            this.ctxGrid.fillStyle = startNodeColor;
            type = "Start"
            //draw it
            this.ctxGrid.strokeRect(x, y, l, w);
            this.ctxGrid.fillRect(x, y, l, w);
          }

          else if (i == (this.canvas.width / 20 - 5) && j == (this.canvas.height / 20 - 5)) {
            this.ctxGrid.fillStyle = endNodeColor;

            type = "End"
            //draw it
            this.ctxGrid.strokeRect(x, y, l, w);
            this.ctxGrid.fillRect(x, y, l, w);
          }

          else {
            //push the default square info
            this.ctxGrid.fillStyle = "#000000"
            //draw it
            this.ctxGrid.strokeRect(x, y, l, w);
          }
          this.shapes[i][j] = { x, y, l, w, i, j, type, F, G, H };  //x and y are grid coordinates, and i j is the index in array the square object is in
        }
      }
      //a_star_search();
    }
  }
}
javascript typescript html5-canvas global-variables undefined
1个回答
1
投票

是的,我的朋友,也是我决定在这里让我尝试为您修复这些问题的相同原因。

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';

@Component({
    selector: 'app-grid-draw',
    templateUrl: './grid-draw.component.html',
    styleUrls: ['./grid-draw.component.css']
})
export class GridDrawComponent implements OnInit {

    constructor() { }

    @ViewChild('canvas', { static: true })



    shapes;
    canvas;
    ctxGrid;
    ngOnInit(): void {
        const animDelay = 5;
        const startNodeColor = "#FF3600";
        const endNodeColor = "#00AB5C";

        //initialize array an grid
        this.shapes = new Array(100);
        for (let i = 0; i < this.shapes.length; i++) { this.shapes[i] = new Array(100) };
        this.canvas = <HTMLCanvasElement>document.getElementById('myCanvas');
        this.ctxGrid = this.canvas.getContext('2d');
        resetGrid();
        //walls
        this.canvas.addEventListener('mousemove', (e) => {
            const rect = this.canvas.getBoundingClientRect();

            let cx = e.clientX - rect.left;
            let cy = e.clientY - rect.top;
            //draw_erase_walls(e, cx, cy);
        })

        //single click for start and end nodes
        this.canvas.addEventListener('mousedown', (e) => {
            const rect = this.canvas.getBoundingClientRect();
            let cx = e.clientX - rect.left;
            let cy = e.clientY - rect.top;
            //changeStart(cx, cy);
            //changeEnd(cx, cy);
        })

    }

    resetGrid(): void {
        this.ctxGrid.lineWidth = 0.05;
        //grid with rectangles
        for (let i = 0; i < this.shapes.length; i++) {
            for (let j = 0; j < this.shapes[i].length; j++) {
                //variables
                let x = i * 20;
                let y = j * 20;
                let l = 20, w = 20;
                let type = ""

                //a* algorithm info
                let F = 0;
                let G = 0;
                let H = 0;
                if (i == 4 && j == 4) {
                    this.ctxGrid.fillStyle = startNodeColor;
                    type = "Start"
                    //draw it
                    this.ctxGrid.strokeRect(x, y, l, w);
                    this.ctxGrid.fillRect(x, y, l, w);
                }

                else if (i == (this.canvas.width / 20 - 5) && j == (this.canvas.height / 20 - 5)) {
                    this.ctxGrid.fillStyle = endNodeColor;

                    type = "End"
                    //draw it
                    this.ctxGrid.strokeRect(x, y, l, w);
                    this.ctxGrid.fillRect(x, y, l, w);
                }

                else {
                    //push the default square info
                    this.ctxGrid.fillStyle = "#000000"
                    //draw it
                    this.ctxGrid.strokeRect(x, y, l, w);
                }
                this.shapes[i][j] = { x, y, l, w, i, j, type, F, G, H };  //x and y are grid coordinates, and i j is the index in array the square object is in
            }
        }
        //a_star_search();
    }
}

希望它能这样工作。原因箭头函数没有上下文,它使用移动或向下函数内部的组件上下文=)(至少应该是:)

© www.soinside.com 2019 - 2024. All rights reserved.