113 lines
3.3 KiB
JavaScript
113 lines
3.3 KiB
JavaScript
/**
|
|
* Represents a canvas window that resizes to fit the screen while maintaining a native aspect ratio.
|
|
*/
|
|
export default class CanvasWindow {
|
|
/**
|
|
* Creates a new instance of the `CanvasWindow` class.
|
|
* @param {Object} config - The configuration options for the canvas window.
|
|
* @param {number} config.nativeWidth - The width of the native game size.
|
|
* @param {number} config.nativeHeight - The height of the native game size.
|
|
* @param {number} config.maxMultiplier - The maximum allowed size multiplier for the canvas window.
|
|
* @param {number} config.windowPercentage - The percentage of the screen size to use for the canvas window.
|
|
* @param {HTMLCanvasElement} config.canvas - The canvas element to resize.
|
|
*/
|
|
constructor(config) {
|
|
/**
|
|
* The width of the native game size.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.nativeWidth = config.nativeWidth ?? 320;
|
|
|
|
/**
|
|
* The height of the native game size.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.nativeHeight = config.nativeHeight ?? 240;
|
|
|
|
/**
|
|
* The max multiplier.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.maxMultiplier = config.maxMultiplier ?? 1;
|
|
|
|
/**
|
|
* The percentage of the window size to use for the canvas size.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.windowPercentage = config.windowPercentage ?? 1;
|
|
|
|
/**
|
|
* The canvas element to resize.
|
|
*
|
|
* @member {HTMLCanvasElement}
|
|
*/
|
|
this.canvas = config.canvas;
|
|
|
|
/**
|
|
* The maximum width of the canvas.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.maxWidth = this.nativeWidth * this.maxMultiplier;
|
|
|
|
/**
|
|
* The maximum width of the canvas.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.maxHeight = this.nativeHeight * this.maxMultiplier;
|
|
|
|
/**
|
|
* The maximum width of the canvas.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.canvasWidth = this.nativeWidth;
|
|
|
|
/**
|
|
* The maximum width of the canvas.
|
|
*
|
|
* @member {number}
|
|
*/
|
|
this.canvasHeight = this.nativeHeight;
|
|
|
|
window.addEventListener("resize", () => this.resize());
|
|
}
|
|
|
|
async load() {
|
|
return new Promise((resolve) => {
|
|
window.addEventListener("load", () => {
|
|
this.canvas.width = this.canvasWidth;
|
|
this.canvas.height = this.canvasHeight;
|
|
this.resize();
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Resizes the canvas window to fit the screen while maintaining the native aspect ratio.
|
|
*/
|
|
resize() {
|
|
this.canvasWidth = window.innerWidth;
|
|
this.canvasHeight = window.innerHeight;
|
|
const nativeRatio = this.nativeWidth / this.nativeHeight;
|
|
const browserWindowRatio = this.canvasWidth / this.canvasHeight;
|
|
if (browserWindowRatio > nativeRatio) {
|
|
this.canvasHeight = Math.floor(this.canvasHeight * this.windowPercentage);
|
|
if (this.canvasHeight > this.maxHeight)
|
|
this.canvasHeight = this.maxHeight;
|
|
this.canvasWidth = Math.floor(this.canvasHeight * nativeRatio);
|
|
} else {
|
|
this.canvasWidth = Math.floor(this.canvasWidth * this.windowPercentage);
|
|
if (this.canvasWidth > this.maxWidth) this.canvasWidth = this.maxWidth;
|
|
this.canvasHeight = Math.floor(this.canvasWidth / nativeRatio);
|
|
}
|
|
this.canvas.style.width = `${this.canvasWidth}px`;
|
|
this.canvas.style.height = `${this.canvasHeight}px`;
|
|
}
|
|
}
|