0797410eef
* 支持从项目, 本地电脑, 主站导入/引用素材. * 页面复杂, 需要足够空间, 作为资源打开时会占满右侧 * 编辑结果作为一种新的美术资源. * 新增素材按钮现在是空的实现, 临时在旁边加了一个新增UI设计的按钮 临时入口:  简化: * 组件实现了最基本的图片和文本 * 容器式布局未接入llm编辑 * 不同阶段统一维护一个状态State, 任何阶段都可以人工调整, 不设单独的步骤 * 多图的UI合并功能暂时不要求, 隐藏入口 * 因为生成工具尚未从主站迁移, 主站地图子画布未实现, 以tab栏的形式容纳素材的子画布需求搁置 * 未实现llm绑定字体功能 * 识别会替换现有UI树, 暂时不是增量的 Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/170 Co-authored-by: 王德宇 <kvtodev@outlook.com> Co-committed-by: 王德宇 <kvtodev@outlook.com>
120 lines
3.1 KiB
TypeScript
120 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import {
|
|
findNodePageContext,
|
|
pageRectFromSize,
|
|
resolveAnchorPresetTransform,
|
|
resolveChildrenTransformsForParentRect,
|
|
resolvePageRect,
|
|
resolveReparentTransform,
|
|
} from '../src/features/ui-editor/nodeTransformGeometry';
|
|
import type { Node } from '../src/features/ui-editor/types/Node';
|
|
import type { Transform } from '../src/features/ui-editor/types/Transform';
|
|
|
|
const ROOT_TRANSFORM: Transform = {
|
|
anchor_min: [0, 0],
|
|
anchor_max: [1, 1],
|
|
offset_min: [0, 0],
|
|
offset_max: [0, 0],
|
|
};
|
|
|
|
function node(id: string, transform: Transform, children: Node[] = []): Node {
|
|
return {
|
|
id,
|
|
layout: { transform } as Node['layout'],
|
|
metadata: {} as Node['metadata'],
|
|
components: [],
|
|
children_display_mode: 'Stack',
|
|
children,
|
|
};
|
|
}
|
|
|
|
describe('nodeTransformGeometry', () => {
|
|
it('resolves nested context and inverts page offsets at the same seam', () => {
|
|
const childTransform: Transform = {
|
|
anchor_min: [0.5, 0.5],
|
|
anchor_max: [0.5, 0.5],
|
|
offset_min: [-10, -15],
|
|
offset_max: [30, 25],
|
|
};
|
|
const root = node('root', ROOT_TRANSFORM, [
|
|
node(
|
|
'parent',
|
|
{
|
|
anchor_min: [0, 0],
|
|
anchor_max: [0, 0],
|
|
offset_min: [20, 30],
|
|
offset_max: [220, 130],
|
|
},
|
|
[node('child', childTransform)],
|
|
),
|
|
]);
|
|
|
|
const context = findNodePageContext(
|
|
root,
|
|
'child',
|
|
pageRectFromSize([400, 300]),
|
|
);
|
|
|
|
expect(context).toMatchObject({
|
|
parentRect: { min: [20, 30], max: [220, 130] },
|
|
rect: { min: [110, 65], max: [150, 105] },
|
|
});
|
|
expect(
|
|
resolveReparentTransform(
|
|
childTransform,
|
|
context!.rect,
|
|
context!.parentRect,
|
|
),
|
|
).toEqual(childTransform);
|
|
});
|
|
|
|
it('preserves direct child page rectangles when a parent changes', () => {
|
|
const child = node('child', {
|
|
anchor_min: [0.25, 0],
|
|
anchor_max: [0.75, 1],
|
|
offset_min: [5, 10],
|
|
offset_max: [-10, -15],
|
|
});
|
|
const oldParentRect = {
|
|
min: [20, 30] as [number, number],
|
|
max: [220, 130] as [number, number],
|
|
};
|
|
const newParentRect = {
|
|
min: [40, 50] as [number, number],
|
|
max: [340, 250] as [number, number],
|
|
};
|
|
const oldChildRect = resolvePageRect(child.layout.transform, oldParentRect);
|
|
|
|
const [{ transform }] = resolveChildrenTransformsForParentRect(
|
|
[child],
|
|
oldParentRect,
|
|
newParentRect,
|
|
);
|
|
|
|
expect(resolvePageRect(transform, newParentRect)).toEqual(oldChildRect);
|
|
});
|
|
|
|
it('keeps the page rectangle stable when inspector anchors change', () => {
|
|
const transform: Transform = {
|
|
anchor_min: [0.5, 0.5],
|
|
anchor_max: [0.5, 0.5],
|
|
offset_min: [-60, -20],
|
|
offset_max: [40, 30],
|
|
};
|
|
const parentSize = { width: 300, height: 200 };
|
|
const pageRect = pageRectFromSize([parentSize.width, parentSize.height]);
|
|
|
|
const next = resolveAnchorPresetTransform(
|
|
transform,
|
|
[0, 0],
|
|
[1, 1],
|
|
parentSize,
|
|
);
|
|
|
|
expect(resolvePageRect(next, pageRect)).toEqual(
|
|
resolvePageRect(transform, pageRect),
|
|
);
|
|
});
|
|
});
|