用角度6中的画布调整窗口大小后,单击侦听器不正确的数据



我使用的是一个带有可点击元素的画布,它是使用for循环添加的,我添加了一个调整大小事件,在用户窗口调整大小后重新绘制画布。当窗口第一次加载时,画布和点击侦听器工作得很好,我的问题在窗口调整大小之后开始,我得到了错误的点击坐标和不良行为,看起来点击事件在调整屏幕大小的所有时间都有某种积压。

这是stackblitz 的完整代码

调整大小功能

@HostListener('window:resize', ['$event'])
onResize(event) {
this.innerWidth = window.innerWidth;
this.innerHeight = window.innerHeight;
this.canvas.width = this.innerWidth;
this.canvas.height = this.innerHeight 
this.cleardraw()
this.draw()         
}
cleardraw(){
var ctx = this.canvas.getContext('2d');
ctx.clearRect(0, 0, this.innerWidth, this.innerHeight);
}

绘图功能

draw() {
var ctx = this.canvas.getContext('2d');
ctx.font = "15px Arial";
var seats = []                               
var tempOrderArrey = []                        
var orderSeatsClinet = []                        
var selectedSeatsClient = []                      
var numberOfSeats = 10
var numberOfRows = 10
var canvasWidth = this.innerWidth
var canvasHight = this.innerHeight

function Seat(x, y, w, h, id, line, seatNum, color) {
this.x = x - 160
this.y = y ;
this.w = w;
this.h = h;
this.id = id;
this.line = line
this.seatNo = seatNum + 1 ;
this.color = color
}

Seat.prototype.draw = function () {
ctx.fillStyle = this.color
ctx.fillRect(this.x, this.y, this.w, this.h)

}

function drawAll() {
for (var i = 0; i < seats.length; i++) {
seats[i].draw();
}
}
var id = 1;
var xPad = canvasWidth / 30

function addSeats(value, ch) {
for (let i = 0; i <= 15; i++)
seats.push(new Seat( (canvasWidth / 3) + (i * xPad), value, canvasWidth/ 37, canvasWidth/ 37, id++, ch, i, "#998515"));
}
var start = 60, diff = canvasWidth/30, ch = 0;
for (let i = 0; i < 2; i++) {
//60 + (40 * i)
addSeats(start + (diff * i), ch++);
}     
drawAll()

点击事件功能

this.renderer.listen(this.canvasRef.nativeElement, 'click', (event) => {
let cX = event.layerX;
let cY = event.layerY;
const offsetLeft = this.canvasRef.nativeElement.offsetLeft;
const offsetTop = this.canvasRef.nativeElement.offsetTop;
this.cX = cX - offsetLeft;
this.cY = cY - offsetTop;
for (var i = 0; i < seats.length; i++) {
var s = seats[i];
if (cX >= s.x && cX < s.x + s.w && cY >= s.y && cY < s.y + s.h) {
if (s.color == '#998515') {      // If green
tempOrderArrey.push({ "id": s.id, "seatNum": s.seatNo, "rowNum": s.line })
s.color = '#ff0000'
ctx.fillStyle = '#ff0000'
ctx.fillRect(s.x, s.y, s.w, s.h)
}
else if (s.color == '#ff0000') {  // If red
tempOrderArrey = tempOrderArrey.filter(seat => seat.id != s.id);
ctx.fillStyle = '#998515'
s.color = '#998515'
ctx.fillRect(s.x, s.y, s.w, s.h)                                   
}
}
this.tempOrderArrey =   tempOrderArrey
}})

}

原因是每次调整大小时,都会再次调用renderer.listen,因此一次单击就会触发许多事件。

在创建新的之前,您需要确保清除侦听器

// Check if the reference exists
if (this.reference != null) {
this.reference; // Clear the listener
}
// Store a reference to the listener
this.reference = this.renderer.listen(this.canvasRef.nativeElement, 'click', (event) => {

这是StackBlitz的分叉

最新更新