5bcaca7233
统一主画布与子画布的可见渲染层和 viewport 状态管理。 将子画布改为固定视口加无限平移 world,并保证首次 fit 的可读比例。 补充转场、滚轮、viewport 和资源画本回归测试,更新技术方案文档。
94 lines
2.5 KiB
TypeScript
94 lines
2.5 KiB
TypeScript
import type { ResourceBookCategory } from './resourceBookModel';
|
|
import type { ResourceCanvasCardSize } from './resourceCanvasLayoutModel';
|
|
import type { ProjectResource } from './resourceProjectionModel';
|
|
import { projectResourceTypeLabel } from './resourceProjectionModel';
|
|
|
|
export type ResourceBookOverviewRect = {
|
|
left: number;
|
|
top: number;
|
|
width: number;
|
|
height: number;
|
|
};
|
|
|
|
export type ResourceBookStack = [type: string, items: ProjectResource[]];
|
|
|
|
export type ResourceBookCardLayout = {
|
|
x: number;
|
|
y: number;
|
|
width: number;
|
|
height: number;
|
|
dragX: number;
|
|
dragY: number;
|
|
rotation: number;
|
|
};
|
|
|
|
export function groupResourceBookStacks(
|
|
resources: readonly ProjectResource[],
|
|
): ResourceBookStack[] {
|
|
const groups = new Map<string, ProjectResource[]>();
|
|
for (const resource of resources) {
|
|
const items = groups.get(projectResourceTypeLabel(resource)) ?? [];
|
|
items.push(resource);
|
|
groups.set(projectResourceTypeLabel(resource), items);
|
|
}
|
|
return Array.from(
|
|
groups,
|
|
([type, items]) => [type, items] as ResourceBookStack,
|
|
);
|
|
}
|
|
|
|
export function groupResourceBookResourcesByCategory(
|
|
resources: readonly ProjectResource[],
|
|
) {
|
|
const result = new Map<ResourceBookCategory, ProjectResource[]>();
|
|
for (const resource of resources) {
|
|
const items = result.get(resource.category) ?? [];
|
|
items.push(resource);
|
|
result.set(resource.category, items);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
export function resourceBookOverviewCardLayout({
|
|
rect,
|
|
stackIndex,
|
|
stackColumn,
|
|
}: {
|
|
rect: ResourceBookOverviewRect | undefined;
|
|
stackIndex: number;
|
|
stackColumn: number;
|
|
}): ResourceBookCardLayout {
|
|
return {
|
|
x: (rect?.left ?? 0) + 18 + (stackColumn % 3) * 102,
|
|
y: (rect?.top ?? 0) + 58 + Math.min(stackIndex, 2) * 5,
|
|
width: 92,
|
|
height: 64,
|
|
dragX: 0,
|
|
dragY: 0,
|
|
rotation: stackIndex % 2 ? -(stackIndex + 0.5) : stackIndex + 0.5,
|
|
};
|
|
}
|
|
|
|
export function resourceBookChildCardLayout({
|
|
position,
|
|
size,
|
|
}: {
|
|
position: { x: number; y: number } | undefined;
|
|
size: ResourceCanvasCardSize;
|
|
}): ResourceBookCardLayout {
|
|
const x = position?.x ?? 0;
|
|
const y = position?.y ?? 0;
|
|
// The child scene applies the viewport transform on its card-world wrapper.
|
|
// Keep card geometry logical here so persistence, drag callbacks, and the
|
|
// public ResourceCard style contract are not polluted by screen space.
|
|
return {
|
|
x,
|
|
y,
|
|
width: size.width,
|
|
height: size.height,
|
|
dragX: x,
|
|
dragY: y,
|
|
rotation: 0,
|
|
};
|
|
}
|