rg/naloga_3/engine/systems/ResizeSystem.js
Gašper Dobrovoljc a20a45ebd0
Naloga 3 WIP
2024-12-28 19:58:17 +01:00

85 lines
2.2 KiB
JavaScript

export class ResizeSystem {
constructor({
canvas,
resize,
resolutionFactor = 1,
minWidth = 1,
minHeight = 1,
maxWidth = Infinity,
maxHeight = Infinity,
} = {}) {
this._resize = this._resize.bind(this);
this.canvas = canvas;
this.resize = resize;
this.resolutionFactor = resolutionFactor;
this.minCanvasSize = {
width: minWidth,
height: minHeight,
};
this.maxCanvasSize = {
width: maxWidth,
height: maxHeight,
};
this.lastSize = {
width: null,
height: null,
};
}
start() {
if (this._resizeFrame) {
return;
}
this._resizeFrame = requestAnimationFrame(this._resize);
}
stop() {
if (!this._resizeFrame) {
return;
}
this._resizeFrame = cancelAnimationFrame(this._resizeFrame);
}
_resize() {
this._resizeFrame = requestAnimationFrame(this._resize);
const displayRect = this.canvas.getBoundingClientRect();
if (displayRect.width === this.lastSize.width && displayRect.height === this.lastSize.height) {
return;
}
this.lastSize = {
width: displayRect.width,
height: displayRect.height,
};
const displaySize = {
width: displayRect.width * devicePixelRatio,
height: displayRect.height * devicePixelRatio,
};
const unclampedSize = {
width: Math.round(displaySize.width * this.resolutionFactor),
height: Math.round(displaySize.height * this.resolutionFactor),
};
const canvasSize = {
width: Math.min(Math.max(unclampedSize.width, this.minCanvasSize.width), this.maxCanvasSize.width),
height: Math.min(Math.max(unclampedSize.height, this.minCanvasSize.height), this.maxCanvasSize.height),
};
if (this.canvas.width !== canvasSize.width || this.canvas.height !== canvasSize.height) {
this.canvas.width = canvasSize.width;
this.canvas.height = canvasSize.height;
}
this.resize?.({ displaySize, canvasSize });
}
}