I am using a canvas with clickable elements that was added using for loop, I added a resizing event that redrawing the canvas after user window was resized, When the window is loading for the first time the canvas and click listeners works great, My problem starts after the window resizing, I getting wrong click coordinates and bad behavior, It looks the click event have sort of a backlog for all the times that the screen was resized
Here is the full code on stackblitz
The resize function
@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);
}
The draw function
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()
The click event function
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
}})
}
The reason is that each time you resize, renderer.listen
is called again, so for one click there are many events being fired.
You need to make sure that you clear the listener before creating a new one
// 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) => {
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.