「所有资源」展开态改回平铺画布:不再为每个栏目渲染标题栏
展开态真实栏目不再渲染栏目标题栏,整个场景只留 all 那一条钉在视口上、带「资源总览」收起入口的标题栏 原因是分带只为有可见资源的栏目生成,空栏目拿不到标题栏矩形后全部回落到世界原点叠成一摞(空项目必现,现场是 7 条) ResourceBookSceneCategoryPlan 新增 titlebar 字段,渲染层按它决定是否产出标题栏节点 分带去掉标题栏横带的高度预留与矩形换算,删除 RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT 与 resourceBookAllTitlebarRects 拖动写回口径不变(resourceBookAllBandLocalPoint 一行未改),零 CSS 变更 resourceBookLayout.test 与 appSurface 两条「所有资源」用例加反向守卫;变异验证改回旧行为时两条同时红(got 7) decision-log 与 pitfalls 记这次倒因为「缺一路坐标输入时不要静默回落到原点」
This commit is contained in:
@@ -165,7 +165,6 @@ import {
|
||||
buildResourceBookScenePlan,
|
||||
resourceBookAllBandLocalPoint,
|
||||
type ResourceBookAllLayout,
|
||||
resourceBookAllTitlebarRects,
|
||||
type ResourceBookOverviewRect,
|
||||
resourceBookSceneCardKey,
|
||||
resourceBookSceneCardLayoutSignature,
|
||||
@@ -1176,26 +1175,32 @@ function ResourceBookScene({
|
||||
: undefined;
|
||||
return (
|
||||
<Fragment key={group.category}>
|
||||
<div
|
||||
className={`game-resource-book-scene-titlebar${active ? ' is-active' : ''}`}
|
||||
data-resource-book-category={group.category}
|
||||
style={
|
||||
{
|
||||
left: `${titleLayout.left}px`,
|
||||
top: `${titleLayout.top}px`,
|
||||
width: titleLayout.width,
|
||||
opacity: titleLayout.opacity,
|
||||
transform: titlebarTransform,
|
||||
transformOrigin: active ? '0 0' : undefined,
|
||||
} as CSSProperties
|
||||
}
|
||||
>
|
||||
<ResourceBookTitleBar
|
||||
category={group.category}
|
||||
countLabel={`${group.resourceCount} 项`}
|
||||
onCollapse={active ? onCollapse : undefined}
|
||||
/>
|
||||
</div>
|
||||
{/*
|
||||
展开态的真实栏目不出标题栏:那一页是**一张平铺画布**,只有 `all` 那一条钉在
|
||||
视口上的标题栏(见 `ResourceBookSceneCategoryPlan.titlebar`)。
|
||||
*/}
|
||||
{group.titlebar ? (
|
||||
<div
|
||||
className={`game-resource-book-scene-titlebar${active ? ' is-active' : ''}`}
|
||||
data-resource-book-category={group.category}
|
||||
style={
|
||||
{
|
||||
left: `${titleLayout.left}px`,
|
||||
top: `${titleLayout.top}px`,
|
||||
width: titleLayout.width,
|
||||
opacity: titleLayout.opacity,
|
||||
transform: titlebarTransform,
|
||||
transformOrigin: active ? '0 0' : undefined,
|
||||
} as CSSProperties
|
||||
}
|
||||
>
|
||||
<ResourceBookTitleBar
|
||||
category={group.category}
|
||||
countLabel={`${group.resourceCount} 项`}
|
||||
onCollapse={active ? onCollapse : undefined}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
{group.cards.map((card) => {
|
||||
const expanded = card.presentation === 'child';
|
||||
const cardVisible =
|
||||
@@ -2307,20 +2312,6 @@ export default function ProjectDevelopmentView({
|
||||
resourcePositionById,
|
||||
visibleResourcesByCategory,
|
||||
]);
|
||||
/**
|
||||
* 展开态的栏目标题栏落点。复用总览态"按矩形钉标题栏"的同一条渲染路径,
|
||||
* 只是矩形来自分带而不是总览缩略卡的测量。
|
||||
*/
|
||||
const resourceBookAllTitlebarRectMap = useMemo(
|
||||
() => resourceBookAllTitlebarRects(resourceBookAllLayout),
|
||||
[resourceBookAllLayout],
|
||||
);
|
||||
/**
|
||||
* 画本场景当前该用哪份标题栏矩形:展开态用分带,其余状态用总览缩略卡的测量结果。
|
||||
*/
|
||||
const resourceBookSceneRects = resourceBookOpensAllResources
|
||||
? resourceBookAllTitlebarRectMap
|
||||
: resourceBookOverviewRects;
|
||||
/**
|
||||
* 展开态的视口拟合(入口与「适应画布」共用一处,避免两份几何口径)。
|
||||
*/
|
||||
@@ -2990,7 +2981,7 @@ export default function ProjectDevelopmentView({
|
||||
state: resourceBookState,
|
||||
visibleCategoryOrder: resourceBookSceneCategoryOrder,
|
||||
resourcesByCategory: resourceBookSceneResourcesByCategory,
|
||||
overviewRects: resourceBookSceneRects,
|
||||
overviewRects: resourceBookOverviewRects,
|
||||
positions: resourcePositionById,
|
||||
cardSizes: resourceCardSizeByResourceId,
|
||||
visibleResourceIds,
|
||||
@@ -3010,8 +3001,8 @@ export default function ProjectDevelopmentView({
|
||||
resourceBookAllLayout,
|
||||
resourceBookCategoryViewCenters,
|
||||
resourceBookExitingCards,
|
||||
resourceBookOverviewRects,
|
||||
resourceBookSceneCategoryOrder,
|
||||
resourceBookSceneRects,
|
||||
resourceBookSceneResourcesByCategory,
|
||||
resourceBookState,
|
||||
resourceCardSizeByResourceId,
|
||||
@@ -3022,8 +3013,8 @@ export default function ProjectDevelopmentView({
|
||||
],
|
||||
);
|
||||
/**
|
||||
* 展开态的标题栏几何由分带同步算出,不需要等总览缩略卡测量完(那套是总览态的 `is-measuring`
|
||||
* 首帧门)。其它状态维持原判据不变。
|
||||
* 展开态不需要等总览缩略卡测量完就能画(它的几何来自分带,不来自测量);其它状态维持
|
||||
* 原判据不变(总览态的 `is-measuring` 首帧门)。
|
||||
*/
|
||||
const resourceBookOverviewReady = useMemo(
|
||||
() =>
|
||||
@@ -3037,7 +3028,7 @@ export default function ProjectDevelopmentView({
|
||||
const resourceBookMotionSignatures = useMemo(() => {
|
||||
const signatures = new Map<string, string>();
|
||||
for (const group of resourceBookScenePlan) {
|
||||
const rect = resourceBookSceneRects.get(group.category);
|
||||
const rect = resourceBookOverviewRects.get(group.category);
|
||||
signatures.set(
|
||||
resourceBookSceneTitleKey(group.category),
|
||||
group.titlebarActive
|
||||
@@ -3049,7 +3040,7 @@ export default function ProjectDevelopmentView({
|
||||
}
|
||||
}
|
||||
return signatures;
|
||||
}, [resourceBookScenePlan, resourceBookSceneRects]);
|
||||
}, [resourceBookScenePlan, resourceBookOverviewRects]);
|
||||
// 拖拽中的卡片只跟指针走,不参与布局 FLIP。
|
||||
const resourceBookFrozenMotionKeys = useMemo(() => {
|
||||
const keys = new Set<string>();
|
||||
@@ -6248,7 +6239,7 @@ export default function ProjectDevelopmentView({
|
||||
<ResourceBookScene
|
||||
plan={resourceBookScenePlan}
|
||||
resourceBookState={resourceBookState}
|
||||
overviewRects={resourceBookSceneRects}
|
||||
overviewRects={resourceBookOverviewRects}
|
||||
overviewReady={resourceBookOverviewReady}
|
||||
visibleResourceIds={visibleResourceIds}
|
||||
viewport={activeResourceCanvasViewport}
|
||||
|
||||
@@ -70,13 +70,12 @@ export function groupResourceBookStacks(
|
||||
/**
|
||||
* 「所有资源」展开态里一个栏目的分带。
|
||||
*
|
||||
* `titlebarTop` 是**标题栏**在世界坐标里的顶边,`originX / originY` 是**卡片空间原点**:
|
||||
* 栏目内局部坐标加它才得到世界坐标(`resourceBookChildCardLayout` 的产物仍是局部坐标)。
|
||||
* 两者分开是因为标题栏要占一条不被卡片压住的横带。
|
||||
* `originX / originY` 是**卡片空间原点**:栏目内局部坐标加它才得到世界坐标
|
||||
* (`resourceBookChildCardLayout` 的产物仍是局部坐标)。展开态只铺卡片、不出栏目标题栏
|
||||
* (见 `ResourceBookSceneCategoryPlan.titlebar`),所以这里没有任何标题栏几何。
|
||||
*/
|
||||
export type ResourceBookAllBand = {
|
||||
category: ResourceBookCategory;
|
||||
titlebarTop: number;
|
||||
originX: number;
|
||||
originY: number;
|
||||
width: number;
|
||||
@@ -90,21 +89,20 @@ export type ResourceBookAllLayout = {
|
||||
bounds: { x: number; y: number; width: number; height: number };
|
||||
};
|
||||
|
||||
/** 相邻两条分带之间的竖直留白(带上一条的卡片底边到下一条的标题栏顶边)。 */
|
||||
/** 相邻两条分带之间的竖直留白(上一带最后一张卡到下一条带第一张卡)。 */
|
||||
export const RESOURCE_BOOK_ALL_BAND_GAP = 48;
|
||||
|
||||
/**
|
||||
* 分带标题栏的高度。取 `.game-resource-book-scene-titlebar .game-resource-book-titlebar`
|
||||
* 的 `min-height`,让展开态的标题栏与总览/栏目态那一条同高,不为它另立一套尺寸。
|
||||
*/
|
||||
export const RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT = 42;
|
||||
|
||||
/**
|
||||
* 「所有资源」展开态的分带几何:沿用总览的栏目顺序,每个**有可见资源**的栏目纵向占一带。
|
||||
*
|
||||
* 卡片坐标是栏目内局部坐标(见 `resourceCanvasSectionExtent`),铺进同一张画布前必须各给
|
||||
* 一个带原点,否则各栏目全叠在原点。带宽高取可见资源的 extent:被筛掉的栏目不占屏,
|
||||
* 与总览/旧网格页"只保留有资源的栏目"同口径。
|
||||
* 与总览"只保留有资源的栏目"同口径。
|
||||
*
|
||||
* 带内只有卡片,没有标题栏横带:展开态是"一张平铺画布",唯一的标题栏是钉在视口上的
|
||||
* `all` 那一条(见 `buildResourceBookScenePlan`)。因此带高就是卡片 extent,带间距就是
|
||||
* `RESOURCE_BOOK_ALL_BAND_GAP`。没有可见资源的栏目不产生带 —— 这一点是硬约束:
|
||||
* 曾经"每条带都配一条标题栏"时,空栏目拿不到带矩形,标题栏会全部回落到世界原点叠在一起。
|
||||
*
|
||||
* 这里的产物只描述几何,不参与任何持久化:落盘仍只有栏目内局部坐标。
|
||||
*/
|
||||
@@ -144,14 +142,9 @@ export function buildResourceBookAllLayout({
|
||||
}),
|
||||
cardSizes,
|
||||
);
|
||||
const titlebarTop = cursorTop;
|
||||
const originY =
|
||||
titlebarTop +
|
||||
RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT +
|
||||
RESOURCE_BOOK_ALL_BAND_GAP / 2;
|
||||
const originY = cursorTop;
|
||||
const band: ResourceBookAllBand = {
|
||||
category,
|
||||
titlebarTop,
|
||||
originX: 0,
|
||||
originY,
|
||||
width: extent.width,
|
||||
@@ -161,9 +154,9 @@ export function buildResourceBookAllLayout({
|
||||
bandByCategory.set(category, band);
|
||||
minX = Math.min(minX, extent.x);
|
||||
maxX = Math.max(maxX, extent.x + extent.width);
|
||||
minY = Math.min(minY, titlebarTop);
|
||||
minY = Math.min(minY, originY);
|
||||
maxY = Math.max(maxY, originY + extent.height);
|
||||
cursorTop = originY + extent.height + RESOURCE_BOOK_ALL_BAND_GAP / 2;
|
||||
cursorTop = originY + extent.height + RESOURCE_BOOK_ALL_BAND_GAP;
|
||||
}
|
||||
return {
|
||||
bands,
|
||||
@@ -177,28 +170,6 @@ export function buildResourceBookAllLayout({
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 分带 → 场景标题栏矩形。
|
||||
*
|
||||
* 展开态复用总览态"按矩形把栏目标题栏钉在世界坐标上"的同一条渲染路径,只是矩形来自分带,
|
||||
* 而不是总览缩略卡的 DOM 测量;`ResourceBookScene` 不需要为这一态知道任何新概念。
|
||||
*/
|
||||
export function resourceBookAllTitlebarRects(
|
||||
layout: ResourceBookAllLayout,
|
||||
): Map<ResourceBookTarget, ResourceBookOverviewRect> {
|
||||
return new Map(
|
||||
layout.bands.map((band) => [
|
||||
band.category as ResourceBookTarget,
|
||||
{
|
||||
left: band.originX,
|
||||
top: band.titlebarTop,
|
||||
width: band.width,
|
||||
height: RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT,
|
||||
},
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 展开态的世界坐标 → 栏目内局部坐标(**落盘前必须走的唯一换算**)。
|
||||
*
|
||||
@@ -364,6 +335,14 @@ export type ResourceBookSceneCardPlan = {
|
||||
export type ResourceBookSceneCategoryPlan = {
|
||||
category: ResourceBookTarget;
|
||||
resourceCount: number;
|
||||
/**
|
||||
* 这一组要不要渲染栏目标题栏节点。
|
||||
*
|
||||
* 展开态只有 `all` 那一条(钉在视口上、带「资源总览」收起入口):展开态是**一张平铺
|
||||
* 画布**,真实栏目只铺卡片。总览态与栏目态每一组都要(总览态靠它承载计数徽标,
|
||||
* 栏目态靠它承载当前栏目与返回入口)。
|
||||
*/
|
||||
titlebar: boolean;
|
||||
titlebarActive: boolean;
|
||||
titlebarOpacity: number;
|
||||
cards: ResourceBookSceneCardPlan[];
|
||||
@@ -377,7 +356,8 @@ export type ResourceBookSceneCategoryPlan = {
|
||||
* - 返回总览时源栏目未回到摞上的卡片按子画布布局淡出;
|
||||
* - 搜索/排序导致的卸载由 `exitingCards` 保留一帧,用同一套淡出撤下。
|
||||
* - 「所有资源」组在总览态只出栏目标题栏(计数即全量资源数),卡片本体仍由各栏目摞承载;
|
||||
* 在**展开态**则反过来:各真实栏目铺满自己分带里的全部卡片,`all` 只留标题栏与计数。
|
||||
* 在**展开态**则反过来:各真实栏目把自己分带里的全部卡片平铺在画布上(**不出标题栏**),
|
||||
* `all` 只留钉住的标题栏与计数。
|
||||
*/
|
||||
export function buildResourceBookScenePlan({
|
||||
state,
|
||||
@@ -453,7 +433,7 @@ export function buildResourceBookScenePlan({
|
||||
const categoryResources = resourcesByCategory.get(category) ?? [];
|
||||
/**
|
||||
* 展开态:`all` 只出标题栏与全量计数(`titlebarActive` 让它钉在视口上,并带上
|
||||
* 「资源总览」收起入口);真实栏目把全部卡片铺在自己那条分带里。
|
||||
* 「资源总览」收起入口);真实栏目把全部卡片平铺在自己那条分带里,**不渲染标题栏**。
|
||||
*
|
||||
* 真实栏目这一支仍然按 `presentation === 'child'` 取卡,而不是"展开态就一定出卡":
|
||||
* "能出卡的判定"只有 `resourceBookCategoryCardPresentation` 一处,避免两边口径分叉。
|
||||
@@ -463,6 +443,7 @@ export function buildResourceBookScenePlan({
|
||||
return {
|
||||
category,
|
||||
resourceCount: categoryResources.length,
|
||||
titlebar: true,
|
||||
titlebarActive: true,
|
||||
titlebarOpacity: 1,
|
||||
cards,
|
||||
@@ -485,8 +466,9 @@ export function buildResourceBookScenePlan({
|
||||
return {
|
||||
category,
|
||||
resourceCount: categoryResources.length,
|
||||
titlebar: false,
|
||||
titlebarActive: false,
|
||||
titlebarOpacity: 1,
|
||||
titlebarOpacity: 0,
|
||||
cards,
|
||||
};
|
||||
}
|
||||
@@ -575,6 +557,7 @@ export function buildResourceBookScenePlan({
|
||||
return {
|
||||
category,
|
||||
resourceCount: categoryResources.length,
|
||||
titlebar: true,
|
||||
titlebarActive: presentation === 'child',
|
||||
titlebarOpacity: childLayout || state.view === 'main' ? 1 : 0,
|
||||
cards,
|
||||
|
||||
@@ -9609,9 +9609,9 @@ export function registerProjectAgentStatusTests() {
|
||||
expect(previewHostRule).toMatch(/position:\s*absolute/);
|
||||
expect(previewHostRule).toMatch(/transform-origin:\s*0 0/);
|
||||
|
||||
// 3) 点它进入的是**同一套画本场景**,不是另一条渲染分支:每个真实栏目铺在自己的分带上,
|
||||
// 卡片宿主是栏目页那一个 `.game-resource-book-scene-card`、`data-resource-book-category`
|
||||
// 仍是真实栏目;`all` 自己只留钉住的标题栏与全量计数。
|
||||
// 3) 点它进入的是**同一套画本场景**,不是另一条渲染分支:真实栏目的卡片平铺在同一张
|
||||
// 画布上,卡片宿主是栏目页那一个 `.game-resource-book-scene-card`、
|
||||
// `data-resource-book-category` 仍是真实栏目;`all` 自己只留钉住的标题栏与全量计数。
|
||||
fireEvent.click(screen.getByRole('button', { name: '打开所有资源' }));
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
@@ -9651,6 +9651,14 @@ export function registerProjectAgentStatusTests() {
|
||||
);
|
||||
expect(hostCategories.length).toBeGreaterThan(1);
|
||||
expect(hostCategories).not.toContain('all');
|
||||
// 展开态是一张**平铺画布**:真实栏目不出标题栏,整个场景只留 `all` 那一条钉住的。
|
||||
// 曾经"每条分带配一条标题栏"时,没有可见资源的栏目拿不到带矩形,标题栏会全部回落到
|
||||
// 世界原点叠成一摞(用户报的破版就是这一摞);下面这条把它钉死。
|
||||
expect(
|
||||
document.querySelectorAll(
|
||||
'.game-resource-book-scene-titlebar:not([data-resource-book-category="all"])',
|
||||
),
|
||||
).toHaveLength(0);
|
||||
// 每张资源恰好一个宿主(展开态没有"第二份宿主"):条数与全量计数同源,
|
||||
// 因此不会出现「标题说 N 项、画布少几张」。
|
||||
expect(
|
||||
@@ -9785,6 +9793,13 @@ export function registerProjectAgentStatusTests() {
|
||||
expect(
|
||||
document.querySelectorAll('.game-resource-book-scene-card'),
|
||||
).toHaveLength(0);
|
||||
// 空项目恰恰是那一摞的现场:没有任何带 ⇒ 曾经每个真实栏目的标题栏都回落到世界原点
|
||||
// 叠在一起(最后画的「项目版本」浮在画布中央)。展开态只允许 `all` 那一条标题栏。
|
||||
expect(
|
||||
document.querySelectorAll(
|
||||
'.game-resource-book-scene-titlebar:not([data-resource-book-category="all"])',
|
||||
),
|
||||
).toHaveLength(0);
|
||||
expect(
|
||||
document.querySelector('.game-resource-page-empty')?.textContent,
|
||||
).toBe('没有匹配资源');
|
||||
|
||||
@@ -4,12 +4,11 @@ import {
|
||||
buildResourceBookAllLayout,
|
||||
buildResourceBookScenePlan,
|
||||
groupResourceBookStacks,
|
||||
RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT,
|
||||
RESOURCE_BOOK_ALL_BAND_GAP,
|
||||
RESOURCE_BOOK_OVERVIEW_STACK_LIMIT,
|
||||
type ResourceBookAllBand,
|
||||
resourceBookAllBandLocalPoint,
|
||||
type ResourceBookAllLayout,
|
||||
resourceBookAllTitlebarRects,
|
||||
resourceBookOverviewCardLayout,
|
||||
type ResourceBookOverviewRect,
|
||||
resourceBookSceneCardKey,
|
||||
@@ -421,7 +420,7 @@ describe('buildResourceBookScenePlan', () => {
|
||||
['unclassified', resources],
|
||||
['scene', [sceneResource]],
|
||||
]),
|
||||
overviewRects: resourceBookAllTitlebarRects(allLayout),
|
||||
overviewRects: new Map<ResourceBookTarget, ResourceBookOverviewRect>(),
|
||||
positions: allPositions,
|
||||
cardSizes: allCardSizes,
|
||||
visibleResourceIds: new Set(allResources.map((item) => item.id)),
|
||||
@@ -439,6 +438,7 @@ describe('buildResourceBookScenePlan', () => {
|
||||
)!;
|
||||
// `all` 一张卡都不挂:卡片由各真实栏目承载,否则同一张卡会挂两份、FLIP 键互相顶掉。
|
||||
expect(allGroup.cards).toEqual([]);
|
||||
expect(allGroup.titlebar).toBe(true);
|
||||
expect(allGroup.titlebarActive).toBe(true);
|
||||
expect(allGroup.titlebarOpacity).toBe(1);
|
||||
expect(allGroup.resourceCount).toBe(allResources.length);
|
||||
@@ -449,9 +449,11 @@ describe('buildResourceBookScenePlan', () => {
|
||||
expect(artGroup.cards.every((card) => card.presentation === 'child')).toBe(
|
||||
true,
|
||||
);
|
||||
// 展开态的栏目标题栏不钉在视口上,但要可见(它随分带一起被视口变换)。
|
||||
// 展开态的真实栏目**不出标题栏**:那一页是一张平铺画布,标题栏只有 `all` 那一条。
|
||||
// 曾经"每条带配一条标题栏"时,没有可见资源的栏目拿不到带矩形,标题栏会集体回落到
|
||||
// 世界原点叠成一摞(用户报的正是这个)。
|
||||
expect(artGroup.titlebar).toBe(false);
|
||||
expect(artGroup.titlebarActive).toBe(false);
|
||||
expect(artGroup.titlebarOpacity).toBe(1);
|
||||
// 画出来的是"栏目内局部坐标 + 带原点",拖动起点与它同系(提交时再减回带原点)。
|
||||
const first = artGroup.cards[0]!;
|
||||
expect(first.layout.x).toBe(positions.get('art-0')!.x + band.originX);
|
||||
@@ -491,7 +493,7 @@ describe('buildResourceBookScenePlan', () => {
|
||||
[RESOURCE_BOOK_ALL_TARGET, resources],
|
||||
['unclassified', resources],
|
||||
]),
|
||||
overviewRects: resourceBookAllTitlebarRects(allLayout),
|
||||
overviewRects: new Map<ResourceBookTarget, ResourceBookOverviewRect>(),
|
||||
state: {
|
||||
view: 'main',
|
||||
category: null,
|
||||
@@ -550,13 +552,17 @@ describe('buildResourceBookAllLayout', () => {
|
||||
|
||||
it('stacks the bands downward so no two categories share one origin', () => {
|
||||
const [first, second] = layout.bands;
|
||||
// 标题栏横带压在卡片区之上,两个带的首尾不重叠:否则拖上面一带的卡会压到下面一带的标题。
|
||||
expect(first!.titlebarTop).toBeLessThan(first!.originY);
|
||||
expect(second!.titlebarTop).toBeGreaterThan(first!.originY + first!.height);
|
||||
// 带里只有卡片,所以带宽从原点直接长出 extent 高;两带之间隔一条固定的留白:
|
||||
// 否则拖上面一带的卡会压到下面一带的卡上。
|
||||
expect(first!.originY).toBe(0);
|
||||
expect(first!.height).toBeGreaterThan(0);
|
||||
expect(second!.originY).toBe(
|
||||
first!.originY + first!.height + RESOURCE_BOOK_ALL_BAND_GAP,
|
||||
);
|
||||
expect(second!.originY).toBeGreaterThan(first!.originY);
|
||||
});
|
||||
|
||||
it('covers every titlebar and card box in its bounds', () => {
|
||||
it('covers every card box in its bounds', () => {
|
||||
const last = layout.bands.at(-1)!;
|
||||
expect(layout.bounds.x).toBeLessThanOrEqual(0);
|
||||
expect(layout.bounds.y).toBeLessThanOrEqual(0);
|
||||
@@ -565,25 +571,11 @@ describe('buildResourceBookAllLayout', () => {
|
||||
last.originY + last.height,
|
||||
);
|
||||
});
|
||||
|
||||
it('hands every band a titlebar rect so the scene reuses the overview titlebar path', () => {
|
||||
const rects = resourceBookAllTitlebarRects(layout);
|
||||
const audio = layout.bandByCategory.get('audio')!;
|
||||
|
||||
expect(rects.get('audio')).toEqual({
|
||||
left: audio.originX,
|
||||
top: audio.titlebarTop,
|
||||
width: audio.width,
|
||||
height: RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT,
|
||||
});
|
||||
expect(rects.has('character')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resourceBookAllBandLocalPoint', () => {
|
||||
const band: ResourceBookAllBand = {
|
||||
category: 'document',
|
||||
titlebarTop: 0,
|
||||
originX: 40,
|
||||
originY: 100,
|
||||
width: 620,
|
||||
|
||||
Reference in New Issue
Block a user