Files
heros_web/src/game/ui/dialoguePortrait.ts

77 lines
1.6 KiB
TypeScript

import type Phaser from 'phaser';
const defaultFaceCropRatio = 0.6;
const defaultFaceCropTopRatio = 0.035;
export type DialogueFacePortraitLayout = {
cropX: number;
cropY: number;
cropSize: number;
originX: number;
originY: number;
scale: number;
};
export function calculateDialogueFacePortraitLayout(
sourceWidth: number,
sourceHeight: number,
displaySize: number
): DialogueFacePortraitLayout {
if (
!Number.isFinite(sourceWidth) ||
!Number.isFinite(sourceHeight) ||
!Number.isFinite(displaySize) ||
sourceWidth <= 0 ||
sourceHeight <= 0 ||
displaySize <= 0
) {
throw new RangeError('Dialogue portrait dimensions must be finite positive numbers.');
}
const cropSize = Math.max(
1,
Math.round(
Math.min(sourceWidth, sourceHeight) * defaultFaceCropRatio
)
);
const cropX = Math.round((sourceWidth - cropSize) / 2);
const cropY = Math.round(
Math.min(
Math.max(0, sourceHeight * defaultFaceCropTopRatio),
sourceHeight - cropSize
)
);
return {
cropX,
cropY,
cropSize,
originX: (cropX + cropSize / 2) / sourceWidth,
originY: (cropY + cropSize / 2) / sourceHeight,
scale: displaySize / cropSize
};
}
export function fitDialogueFacePortrait(
portrait: Phaser.GameObjects.Image,
displaySize: number
) {
const layout = calculateDialogueFacePortraitLayout(
portrait.frame.realWidth,
portrait.frame.realHeight,
displaySize
);
portrait
.setCrop(
layout.cropX,
layout.cropY,
layout.cropSize,
layout.cropSize
)
.setOrigin(layout.originX, layout.originY)
.setScale(layout.scale);
return layout;
}