【发布时间】:2021-11-27 05:51:23
【问题描述】:
我有一个包含一组矩形的算法。我的问题是所有矩形最终都在画布的让侧(以红色勾勒)完美对齐,但不在画布的右侧:
我希望每一行都以类似于justify-content: space-between 的弹性框所获得的方式对齐,看起来像这样:
LINK TO CODESANDBOX
我的特定用例的一些给定:
- 所有项目的高度相同
- 画布内的矩形数量永远不会超过可容纳的数量
- 所有矩形宽度都是某些恒定列宽值(2x、3x、4x)的倍数
现在我对如何暴力破解有了一些想法,例如:
- 进行初始包装
- 将打包的矩形排序成行
- 给定一行中矩形的宽度和画布的宽度,计算将它们分布在行宽上所需的填充量,然后更新每个矩形的坐标
有没有更优雅的解决方案,不涉及在初始打包后重复矩形?
这是 Packer 类:
export interface Block {
w: number;
h: number;
fit?: Node;
}
export interface Node {
x: number;
y: number;
w: number;
h: number;
used?: boolean;
down?: Node;
right?: Node;
}
export class Packer {
readonly w: number;
readonly h: number;
readonly root: Node;
readonly gutter: number;
constructor(w: number, h: number, gutter?: number) {
this.w = w;
this.h = h;
this.gutter = gutter ?? 5;
this.root = { x: 0, y: 0, w: w, h: h, used: false };
}
fit(blocks: Block[]): void {
let n, node, block;
for (n = 0; n < blocks.length; n++) {
block = blocks[n];
block.w += this.gutter;
block.h += this.gutter;
if ((node = this.findNode(this.root, block.w, block.h)))
block.fit = this.splitNode(node, block.w, block.h);
}
}
findNode(root: Node, w: number, h: number): Node | null {
if (root.used && root.right && root.down)
return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
else if (w <= root.w && h <= root.h) return root;
else return null;
}
splitNode(node: Node, w: number, h: number): Node {
node.used = true;
node.down = { x: node.x, y: node.y + h, w: node.w, h: node.h - h };
node.right = { x: node.x + w, y: node.y, w: node.w - w, h: h };
return node;
}
}
export default Packer;
【问题讨论】:
标签: javascript layout packing