Typescript/JavaScript:为什么我的 canvas 和 canvas 上下文未定义,即使我已经初始化了它们?
Typescript/JavaScript: Why is my canvas and canvas context undefined, even though I initialized them?
我正在 Angular 的 Typescript 中玩弄网格。我将 canvas 和上下文定义为全局变量,并在 ngOnInit() 中初始化它们。之后,我调用了一个使用 canvas 和上下文的函数。在控制台中,我收到以下错误: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();
}
}
}
是的,我的朋友,这也是我决定在这里的原因,让我试着为你解决这些问题..
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();
}
}
希望它能这样工作。因为箭头函数没有上下文,它在移动或向下函数中使用你的组件上下文=)(至少它应该:)
我正在 Angular 的 Typescript 中玩弄网格。我将 canvas 和上下文定义为全局变量,并在 ngOnInit() 中初始化它们。之后,我调用了一个使用 canvas 和上下文的函数。在控制台中,我收到以下错误: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();
}
}
}
是的,我的朋友,这也是我决定在这里的原因,让我试着为你解决这些问题..
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();
}
}
希望它能这样工作。因为箭头函数没有上下文,它在移动或向下函数中使用你的组件上下文=)(至少它应该:)