캔버스 자동 확장/축소하기
핵심 개념
scale factor: 폼팩터/해상도 비율에 맞는 UI를 표현하기 위해 적절한 계수를 UI에 사용하는 모든 수치에 곱하여 크기를 보정한다.- x, y, width, height, etc.
delta time: ticker를 통해 얻은 시간 변량을 이동에 관한 변수에 곱하여 속도를 보정한다.- 오브젝트 이동, 게이지 변화, etc.
구현 예시
화면비와 안전 영역을 고려한 캔버스 크기는 다음을 참고:
- 16:9 portrait (450x800)
- 16:9 landscape (800x450)
- 4:3 portrait (450x600)
- 4:3 landscape (600x450)
// 디바이스 크기를 기반으로 캔버스 크기와 비율 계수를 계산
export const calculateStageSize = (
width: number,
height: number,
): { width: number; height: number; scale: number } => {
const maxWidth = Math.min(window.innerWidth, width);
const maxHeight = Math.min(window.innerHeight, height);
const widthScale = maxWidth / width;
const heightScale = maxHeight / height;
const scale = Math.min(widthScale, heightScale);
const calculatedWidth = width * scale;
const calculatedHeight = height * scale;
return { width: calculatedWidth, height: calculatedHeight, scale: scale };
};
// pixi.js 적용 예시
import { Application } from "pixi.js";
import { calculateStageSize } from "./game/utils/calculateStageSize";
(async () => {
const app = new Application();
const size = calculateStageSize(450, 800);
app.renderer.resize(size.width, size.height);
app.stage.scale.set(size.scale);
const container = document.getElementById("app");
container?.appendChild(app.view as HTMLCanvasElement);
window.addEventListener("resize", () => {
const size = calculateStageSize(450, 800);
app.renderer.resize(size.width, size.height);
app.stage.scale.set(size.scale);
});
})();
// @pixi/react 적용 예시
import { Stage } from '@pixi/react';
<Stage
height={stageSize.height}
width={stageSize.width}
onMount={(app) => {
initDevtools({ app });
app.renderer.resize(stageSize.width, stageSize.height);
app.stage.scale.set(stageSize.scale);
window.addEventListener('resize', () => {
const stageSize = calculateStageSize(
DEFAULT_CONFIG.STAGE.width,
DEFAULT_CONFIG.STAGE.height
);
app.renderer.resize(stageSize.width, stageSize.height);
app.stage.scale.set(stageSize.scale);
});
}}
>