fix: change the way region align works
This commit is contained in:
+36
-17
@@ -28,44 +28,63 @@ export type RegionAxis = {
|
||||
export function applyAlign(region: Region){
|
||||
if (region.children.length === 0) return;
|
||||
|
||||
// 对每个 axis 分别处理
|
||||
// 对每个 axis 分别处理,但保持空间关系
|
||||
for (let axisIndex = 0; axisIndex < region.axes.length; axisIndex++) {
|
||||
const axis = region.axes[axisIndex];
|
||||
if (!axis.align) continue;
|
||||
|
||||
// 根据当前轴的位置排序 children
|
||||
region.children.sort((a, b) => {
|
||||
const posA = a.value.position[axisIndex] ?? 0;
|
||||
const posB = b.value.position[axisIndex] ?? 0;
|
||||
return posA - posB;
|
||||
});
|
||||
// 收集当前轴上的所有唯一位置值,保持原有顺序
|
||||
const positionValues = new Set<number>();
|
||||
for (const accessor of region.children) {
|
||||
positionValues.add(accessor.value.position[axisIndex] ?? 0);
|
||||
}
|
||||
|
||||
// 排序位置值
|
||||
const sortedPositions = Array.from(positionValues).sort((a, b) => a - b);
|
||||
|
||||
// 创建位置映射:原位置 -> 新位置
|
||||
const positionMap = new Map<number, number>();
|
||||
|
||||
if (axis.align === 'start' && axis.min !== undefined) {
|
||||
// 从 min 开始紧凑排列
|
||||
region.children.forEach((accessor, index) => {
|
||||
accessor.value.position[axisIndex] = axis.min! + index;
|
||||
// 从 min 开始紧凑排列,保持相对顺序
|
||||
sortedPositions.forEach((pos, index) => {
|
||||
positionMap.set(pos, axis.min! + index);
|
||||
});
|
||||
} else if (axis.align === 'end' && axis.max !== undefined) {
|
||||
// 从 max 开始向前紧凑排列
|
||||
const count = region.children.length;
|
||||
region.children.forEach((accessor, index) => {
|
||||
accessor.value.position[axisIndex] = axis.max! - (count - 1 - index);
|
||||
const count = sortedPositions.length;
|
||||
sortedPositions.forEach((pos, index) => {
|
||||
positionMap.set(pos, axis.max! - (count - 1 - index));
|
||||
});
|
||||
} else if (axis.align === 'center') {
|
||||
// 居中排列
|
||||
const count = region.children.length;
|
||||
const count = sortedPositions.length;
|
||||
const min = axis.min ?? 0;
|
||||
const max = axis.max ?? count - 1;
|
||||
const range = max - min;
|
||||
const center = min + range / 2;
|
||||
|
||||
region.children.forEach((accessor, index) => {
|
||||
// 计算相对于中心的偏移
|
||||
sortedPositions.forEach((pos, index) => {
|
||||
const offset = index - (count - 1) / 2;
|
||||
accessor.value.position[axisIndex] = center + offset;
|
||||
positionMap.set(pos, center + offset);
|
||||
});
|
||||
}
|
||||
|
||||
// 应用位置映射到所有 part
|
||||
for (const accessor of region.children) {
|
||||
const currentPos = accessor.value.position[axisIndex] ?? 0;
|
||||
accessor.value.position[axisIndex] = positionMap.get(currentPos) ?? currentPos;
|
||||
}
|
||||
}
|
||||
|
||||
// 最后按所有轴排序 children
|
||||
region.children.sort((a, b) => {
|
||||
for (let i = 0; i < region.axes.length; i++) {
|
||||
const diff = (a.value.position[i] ?? 0) - (b.value.position[i] ?? 0);
|
||||
if (diff !== 0) return diff;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user