我有一个带有画布的Angular组件,正在使用GraphDrawer
辅助类在其上进行绘制。
我已经设置了组件来在调整窗口大小时调整画布的大小,但是我无法在调整大小上进行任何绘制。
画布在加载时绘制,但是一旦我调整窗口大小,就可以看到画布正确调整了大小(我看到了其边框的变化),但是绘图消失了。
我在做什么错了?
import {Component, ElementRef, OnInit, ViewChild, AfterViewInit, HostListener} from '@angular/core';
import GraphDrawer from './GraphDrawer';
@Component({
selector: 'app-tuz-graph',
template: '<canvas #canvas height={{height}} width={{width}}></canvas>',
styleUrls: ['./tuz-graph.component.css']
})
export class TuzGraphComponent implements AfterViewInit {
@ViewChild('canvas', {static: true}) public canvas: ElementRef<HTMLCanvasElement>;
@HostListener('window:resize', ['$event'])
onResize(event) {
this.width = window.innerWidth / 2;
this.height = window.innerWidth / 2;
this.draw()
}
private ctx: CanvasRenderingContext2D;
drawer: GraphDrawer;
height = window.innerHeight / 2;
width = window.innerHeight / 2;
ngAfterViewInit() {
this.draw();
}
private draw() {
this.ctx = this.canvas.nativeElement.getContext('2d');
this.drawer = new GraphDrawer(this.ctx);
this.drawer.draw();
}
constructor() {}
}
GraphDrawer.ts
(节选)const defaultAxisMarginMultiplier = .07;
const defaultDimension = 600;
export default class GraphDrawer {
constructor(context?: CanvasRenderingContext2D) {
if (!context) return;
this.context = context;
this.height = context.canvas ? context.canvas.height : defaultDimension;
this.width = context.canvas ? context.canvas.width : defaultDimension;
this.marginHorizontal = this.width * defaultAxisMarginMultiplier;
this.marginVertical = this.height * defaultAxisMarginMultiplier;
this.origin = {x: this.marginHorizontal, y: this.height - this.marginVertical};
this.top = 0;
this.left = 0;
this.bottom = this.height;
this.right = this.width;
this.graphWidth = this.width - this.marginHorizontal;
this.graphHeight = this.height - this.marginVertical;
this.rangeX = this.endingValueX - this.startingValueX;
this.rangeY = this.endingValueY - this.startingValueY;
}
setContext(context: CanvasRenderingContext2D) {
this.context = context;
}
// General canvas config
context: CanvasRenderingContext2D;
height: number;
width: number;
origin: { x: number, y: number };
top: number;
left: number;
bottom: number;
right: number;
graphWidth: number;
graphHeight: number;
rangeX: number;
rangeY: number;
marginHorizontal: number;
marginVertical: number;
gridColor = 'lightgrey';
intervalCount = 10;
xAxisToText = 20;
yAxisToText = 10;
hashLength = 5;
startingValueX = 0;
endingValueX = 1000;
decimalPlacesX = 0;
startingValueY = 0;
endingValueY = 1000;
decimalPlacesY = 0;
lastValueXMargin = 20;
lastValueYMargin = 20;
drawAxes() {
const {right, top, origin} = this;
const xAxis = new Path2D();
const yAxis = new Path2D();
xAxis.moveTo(origin.x, origin.y);
xAxis.lineTo(right, origin.y);
this.context.stroke(xAxis);
console.log('drawing x axis to', right);
yAxis.moveTo(origin.x, origin.y);
yAxis.lineTo(origin.x, top);
this.context.stroke(yAxis);
}
draw() {
this.drawAxes();
}
}
我以为从this.draw()
调用onResize()
时,画布或其上下文可能还没有准备好,所以我尝试用this.draw
替换setTimeout(this.draw.bind(this), 100)
,起作用了。
但是,将超时设置为0
也可以工作(setTimeout(this.draw.bind(this), 0)
),所以我想知道是否有人知道为什么“不等待”不起作用时“等待0ms”起作用。调整窗口大小会稍微使图形闪烁,因此我想知道如果不使用timeout
就能解决此问题。
我尝试通过draw
方法记录上下文,但是从来没有null
(我想这就是我需要等待的时间)。