a51e63415f
将外部生成队列概览移到我的页签展示 移除生成页和进度页中的队列概览区域 新增全屏黑底图片预览器并支持缩放和边界拖拽 补充队列概览和图片预览的聚焦测试 同步更新玩法链路、运维、UI Kit 和团队共享记忆文档
97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
export type PlatformImagePreviewSize = {
|
|
width: number;
|
|
height: number;
|
|
};
|
|
|
|
export type PlatformImagePreviewTransform = {
|
|
scale: number;
|
|
offsetX: number;
|
|
offsetY: number;
|
|
};
|
|
|
|
export const MIN_PLATFORM_IMAGE_PREVIEW_SCALE = 1;
|
|
export const MAX_PLATFORM_IMAGE_PREVIEW_SCALE = 4;
|
|
export const PLATFORM_IMAGE_PREVIEW_SCALE_STEP = 0.5;
|
|
export const DEFAULT_PLATFORM_IMAGE_PREVIEW_TRANSFORM: PlatformImagePreviewTransform =
|
|
{
|
|
scale: MIN_PLATFORM_IMAGE_PREVIEW_SCALE,
|
|
offsetX: 0,
|
|
offsetY: 0,
|
|
};
|
|
|
|
function clampNumber(value: number, min: number, max: number) {
|
|
if (!Number.isFinite(value)) {
|
|
return min;
|
|
}
|
|
|
|
return Math.max(min, Math.min(max, value));
|
|
}
|
|
|
|
function normalizePreviewSize(size: PlatformImagePreviewSize | null) {
|
|
if (!size || size.width <= 0 || size.height <= 0) {
|
|
return { width: 1, height: 1 };
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
export function resolvePlatformImagePreviewContainedSize(
|
|
viewportSize: PlatformImagePreviewSize,
|
|
naturalSize: PlatformImagePreviewSize | null,
|
|
) {
|
|
const viewport = normalizePreviewSize(viewportSize);
|
|
const natural = normalizePreviewSize(naturalSize);
|
|
const imageRatio = natural.width / natural.height;
|
|
const viewportRatio = viewport.width / viewport.height;
|
|
|
|
if (imageRatio > viewportRatio) {
|
|
return {
|
|
width: viewport.width,
|
|
height: viewport.width / imageRatio,
|
|
};
|
|
}
|
|
|
|
return {
|
|
width: viewport.height * imageRatio,
|
|
height: viewport.height,
|
|
};
|
|
}
|
|
|
|
export function samePlatformImagePreviewTransform(
|
|
left: PlatformImagePreviewTransform,
|
|
right: PlatformImagePreviewTransform,
|
|
) {
|
|
return (
|
|
left.scale === right.scale &&
|
|
left.offsetX === right.offsetX &&
|
|
left.offsetY === right.offsetY
|
|
);
|
|
}
|
|
|
|
export function clampPlatformImagePreviewTransform(
|
|
transform: PlatformImagePreviewTransform,
|
|
viewportSize: PlatformImagePreviewSize,
|
|
naturalSize: PlatformImagePreviewSize | null,
|
|
): PlatformImagePreviewTransform {
|
|
const viewport = normalizePreviewSize(viewportSize);
|
|
const containedSize = resolvePlatformImagePreviewContainedSize(
|
|
viewport,
|
|
naturalSize,
|
|
);
|
|
const scale = clampNumber(
|
|
transform.scale,
|
|
MIN_PLATFORM_IMAGE_PREVIEW_SCALE,
|
|
MAX_PLATFORM_IMAGE_PREVIEW_SCALE,
|
|
);
|
|
const scaledWidth = containedSize.width * scale;
|
|
const scaledHeight = containedSize.height * scale;
|
|
const panLimitX = Math.max(0, (scaledWidth - viewport.width) / 2);
|
|
const panLimitY = Math.max(0, (scaledHeight - viewport.height) / 2);
|
|
|
|
return {
|
|
scale,
|
|
offsetX: clampNumber(transform.offsetX, -panLimitX, panLimitX),
|
|
offsetY: clampNumber(transform.offsetY, -panLimitY, panLimitY),
|
|
};
|
|
}
|