2021-09-06 14:27:54 +02:00
|
|
|
import { HdpiManager } from "./HdpiManager";
|
2021-05-04 11:29:37 +02:00
|
|
|
import ScaleManager = Phaser.Scale.ScaleManager;
|
2021-09-06 14:27:54 +02:00
|
|
|
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
|
|
|
|
import type { Game } from "../Game/Game";
|
|
|
|
import { ResizableScene } from "../Login/ResizableScene";
|
|
|
|
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
2021-05-04 11:29:37 +02:00
|
|
|
|
2021-12-02 13:20:40 +01:00
|
|
|
export class WaScaleManager {
|
2021-05-04 11:29:37 +02:00
|
|
|
private hdpiManager: HdpiManager;
|
|
|
|
private scaleManager!: ScaleManager;
|
2021-05-18 09:20:38 +02:00
|
|
|
private game!: Game;
|
2021-05-19 18:08:53 +02:00
|
|
|
private actualZoom: number = 1;
|
2021-06-02 16:08:31 +02:00
|
|
|
private _saveZoom: number = 1;
|
2021-05-04 11:29:37 +02:00
|
|
|
|
2021-12-07 12:48:08 +01:00
|
|
|
private focusTarget?: { x: number; y: number; width: number; height: number };
|
|
|
|
|
2021-05-04 14:08:40 +02:00
|
|
|
public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) {
|
|
|
|
this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber);
|
2021-05-04 11:29:37 +02:00
|
|
|
}
|
|
|
|
|
2021-05-18 09:20:38 +02:00
|
|
|
public setGame(game: Game): void {
|
|
|
|
this.scaleManager = game.scale;
|
|
|
|
this.game = game;
|
2021-05-04 11:29:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public applyNewSize() {
|
2021-09-06 14:27:54 +02:00
|
|
|
const { width, height } = coWebsiteManager.getGameSize();
|
2021-12-02 17:46:09 +01:00
|
|
|
const devicePixelRatio = window.devicePixelRatio ?? 1;
|
2021-09-06 14:27:54 +02:00
|
|
|
const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({
|
|
|
|
width: width * devicePixelRatio,
|
|
|
|
height: height * devicePixelRatio,
|
|
|
|
});
|
2021-05-04 11:29:37 +02:00
|
|
|
|
2021-05-19 18:08:53 +02:00
|
|
|
this.actualZoom = realSize.width / gameSize.width / devicePixelRatio;
|
2021-12-07 12:48:08 +01:00
|
|
|
|
2021-09-06 14:27:54 +02:00
|
|
|
this.scaleManager.setZoom(realSize.width / gameSize.width / devicePixelRatio);
|
2021-05-04 11:29:37 +02:00
|
|
|
this.scaleManager.resize(gameSize.width, gameSize.height);
|
|
|
|
|
|
|
|
// Override bug in canvas resizing in Phaser. Let's resize the canvas ourselves
|
|
|
|
const style = this.scaleManager.canvas.style;
|
2021-09-06 14:27:54 +02:00
|
|
|
style.width = Math.ceil(realSize.width / devicePixelRatio) + "px";
|
|
|
|
style.height = Math.ceil(realSize.height / devicePixelRatio) + "px";
|
2021-06-09 18:08:14 +02:00
|
|
|
|
|
|
|
// Resize the game element at the same size at the canvas
|
2021-09-06 14:27:54 +02:00
|
|
|
const gameStyle = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("game").style;
|
2021-06-10 09:23:25 +02:00
|
|
|
gameStyle.width = style.width;
|
2021-06-14 15:54:22 +02:00
|
|
|
gameStyle.height = style.height;
|
2021-06-09 18:08:14 +02:00
|
|
|
|
2021-06-14 18:40:58 +02:00
|
|
|
// Note: onResize will be called twice (once here and once in Game.ts), but we have no better way.
|
2021-05-31 10:20:30 +02:00
|
|
|
for (const scene of this.game.scene.getScenes(true)) {
|
|
|
|
if (scene instanceof ResizableScene) {
|
2021-06-14 18:40:58 +02:00
|
|
|
// We are delaying the call to the "render" event because otherwise, the "camera" coordinates are not correctly updated.
|
|
|
|
scene.events.once(Phaser.Scenes.Events.RENDER, () => scene.onResize());
|
2021-05-31 10:20:30 +02:00
|
|
|
}
|
|
|
|
}
|
2021-05-18 09:20:38 +02:00
|
|
|
|
|
|
|
this.game.markDirty();
|
2021-05-05 13:14:00 +02:00
|
|
|
}
|
2021-05-04 11:29:37 +02:00
|
|
|
|
2021-12-07 12:48:08 +01:00
|
|
|
/**
|
|
|
|
* Use this in case of resizing while focusing on something
|
|
|
|
*/
|
|
|
|
public refreshFocusOnTarget(): void {
|
|
|
|
if (!this.focusTarget) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.zoomModifier = this.getTargetZoomModifierFor(this.focusTarget.width, this.focusTarget.height);
|
2021-12-07 13:18:36 +01:00
|
|
|
this.game.events.emit("wa-scale-manager:refresh-focus-on-target", this.focusTarget);
|
2021-12-07 12:48:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public setFocusTarget(targetDimensions?: { x: number; y: number; width: number; height: number }): void {
|
|
|
|
this.focusTarget = targetDimensions;
|
|
|
|
}
|
|
|
|
|
2021-12-02 17:46:09 +01:00
|
|
|
public getTargetZoomModifierFor(viewportWidth: number, viewportHeight: number) {
|
|
|
|
const { width: gameWidth, height: gameHeight } = coWebsiteManager.getGameSize();
|
|
|
|
const devicePixelRatio = window.devicePixelRatio ?? 1;
|
|
|
|
|
|
|
|
const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({
|
|
|
|
width: gameWidth * devicePixelRatio,
|
|
|
|
height: gameHeight * devicePixelRatio,
|
|
|
|
});
|
2021-12-07 12:48:08 +01:00
|
|
|
const desiredZoom = Math.min(realSize.width / viewportWidth, realSize.height / viewportHeight);
|
|
|
|
const realPixelNumber = gameWidth * devicePixelRatio * gameHeight * devicePixelRatio;
|
|
|
|
return desiredZoom / (this.hdpiManager.getOptimalZoomLevel(realPixelNumber) || 1);
|
2021-12-02 17:46:09 +01:00
|
|
|
}
|
|
|
|
|
2021-05-04 11:29:37 +02:00
|
|
|
public get zoomModifier(): number {
|
|
|
|
return this.hdpiManager.zoomModifier;
|
|
|
|
}
|
|
|
|
|
|
|
|
public set zoomModifier(zoomModifier: number) {
|
|
|
|
this.hdpiManager.zoomModifier = zoomModifier;
|
|
|
|
this.applyNewSize();
|
|
|
|
}
|
2021-05-18 09:20:38 +02:00
|
|
|
|
2021-06-02 16:08:31 +02:00
|
|
|
public saveZoom(): void {
|
|
|
|
this._saveZoom = this.hdpiManager.zoomModifier;
|
|
|
|
}
|
|
|
|
|
2021-12-02 14:44:13 +01:00
|
|
|
public getSaveZoom(): number {
|
|
|
|
return this._saveZoom;
|
|
|
|
}
|
|
|
|
|
2021-09-06 14:27:54 +02:00
|
|
|
public restoreZoom(): void {
|
2021-06-02 16:08:31 +02:00
|
|
|
this.hdpiManager.zoomModifier = this._saveZoom;
|
|
|
|
this.applyNewSize();
|
|
|
|
}
|
|
|
|
|
2021-05-19 18:08:53 +02:00
|
|
|
/**
|
|
|
|
* This is used to scale back the ui components to counter-act the zoom.
|
|
|
|
*/
|
|
|
|
public get uiScalingFactor(): number {
|
2021-05-21 16:25:12 +02:00
|
|
|
return this.actualZoom > 1 ? 1 : 1.2;
|
2021-05-19 18:08:53 +02:00
|
|
|
}
|
2021-05-04 11:29:37 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 14:27:54 +02:00
|
|
|
export const waScaleManager = new WaScaleManager(640 * 480, 196 * 196);
|