ILayout - 自动排版容器
ILayout 是画布图形的自动排版容器。它根据主轴方向、对齐模式、锚点、间距和是否换行等配置,自动计算并设置子元素的位置。
底层会使用每个元素自身实现的 getBoundRect() 来获取参与排版的真实尺寸(宽高),并在定位时叠加容器的 x,y 偏移。
类型
LayoutDirection:horizontal|verticalLayoutMode:left|right|between|centerLayoutAnchor:top|bottom
属性
| 名称 | 类型 | 说明 |
|---|---|---|
x | number | 容器 X 偏移(所有子元素最终坐标会叠加该偏移) |
y | number | 容器 Y 偏移(所有子元素最终坐标会叠加该偏移) |
width | number | 容器宽度(用于布局计算与对齐) |
height | number | 容器高度(用于布局计算与对齐) |
colSpace | number | 列间距(横向相邻元素的水平间距) |
rowSpace | number | 行间距(纵向相邻元素的垂直间距) |
direction | LayoutDirection | 主轴方向:horizontal 横排;vertical 竖排 |
mode | LayoutMode | 主轴对齐:left 左对齐、right 右对齐、center 居中、between 两端对齐(均分间距) |
anchor | LayoutAnchor | 交叉轴锚点:top 顶部对齐、bottom 底部对齐 |
wrap | boolean | 是否自动换行/换列(主轴空间不足时) |
注:元素尺寸来自自身
getBoundRect()的width/height;排版后容器会将计算位置写入每个图形的x,y,并标记needsUpdate = true。
方法
构造函数
constructor(canvas: ICanvas)
创建布局容器实例,并以画布宽高作为默认的容器宽高。
canvas: 画布实例
基础设置
addShape(shapes: Shape[]): void
添加参与布局的图形(按 id 去重)。
setsX(x: number): void
设置容器 X 偏移。
setsY(y: number): void
设置容器 Y 偏移。
setsPosition(x: number, y: number): void
同时设置容器 X/Y 偏移。
setsSize(w: number, h: number): void
设置容器尺寸。
setsWidth(w: number): void
设置容器宽度。
setsHeight(h: number): void
设置容器高度。
布局配置
setsSpaceCol(space: number): void
设置列间距(横向相邻元素的水平间距)。
setsSpaceRow(space: number): void
设置行间距(纵向相邻元素的垂直间距)。
setsSpace(col: number, row: number): void
同时设置列/行间距。
setsLayoutDirection(direction: LayoutDirection): void
设置主轴方向(horizontal/vertical)。
setsMode(mode: LayoutMode): void
设置主轴对齐模式(left/right/between/center)。
setsAnchor(anchor: LayoutAnchor): void
设置交叉轴锚点(top/bottom)。
setsWrap(value: boolean): void
设置是否自动换行/换列。
执行布局
render(): void
根据当前配置计算并写入每个子元素的 x,y。规则:
- 使用元素
getBoundRect()的width/height参与计算; - 横向布局(
horizontal):left从左开始排布;right从右对齐;center居中;between两端对齐均分间距;anchor = top行内元素顶部对齐;anchor = bottom行内元素底部对齐;wrap = true时,主轴不足自动换到下一行;行间距用rowSpace;
- 纵向布局(
vertical):left/center/right/between用于列内的水平对齐/分布;anchor = top从上向下;anchor = bottom从下向上对齐;wrap = true时,主轴不足自动换到下一列;列间距用colSpace;
- 最终位置会叠加容器
x,y偏移; - 执行后会为所有子元素设置
needsUpdate = true。
使用示例
横向排布(不换行)
typescript
const layout = new ILayout(canvas)
layout.setsPosition(50, 40)
layout.setsSize(600, 120)
layout.setsLayoutDirection('horizontal')
layout.setsMode('between')
layout.setsAnchor('top')
layout.setsSpace(20, 12)
layout.addShape([rect1, rect2, rect3])
layout.render()横向排布(自动换行)
typescript
layout.setsLayoutDirection('horizontal')
layout.setsWrap(true)
layout.setsSpace(16, 10)
layout.setsMode('left')
layout.setsAnchor('bottom')
layout.addShape(cards) // 多个不同尺寸的元素
layout.render()纵向排布(不换列,居中对齐)
typescript
layout.setsLayoutDirection('vertical')
layout.setsWrap(false)
layout.setsMode('center')
layout.setsAnchor('top')
layout.setsSpace(24, 12)
layout.addShape([img1, img2, img3])
layout.render()对齐与分布策略说明
left/right/center:控制主轴方向上的整体对齐;between:在可用主轴空间内均分相邻元素间距;top/bottom(anchor):控制交叉轴内元素在行/列中的垂直(横向布局)或水平(纵向布局)对齐;wrap:主轴空间不足时换到下一行/列。
注意事项
- 排版尺寸基于各元素
getBoundRect()的width/height,不同图形实现可能包含描边等 padding 修正。 - 容器
x,y作为整体偏移叠加在最终坐标上,不会改变元素自身的包围盒尺寸计算。 between在仅有一个元素时等效于left/top对齐。- 执行
render()后,元素会标记needsUpdate = true,以触发画布更新。 - 如需更复杂的交叉轴对齐(如每行垂直居中/拉伸),可在后续版本扩展。
