任意数量的图片,通过等比例缩放,重新排列生成最接近的正方形。
interface Item {
w: number,
h: number,
s?: Item[]
}
function getIndex(len: number) {
let x = 0;
let y = 0;
const arrat: Array<{ x: number, y: number }> = [];
while (x < len) {
y = 0;
while (y < len) {
if (x !== y) {
arrat.push({ x, y })
}
y += 1;
}
x += 1;
}
return arrat;
}
function sortItem(a: Item, b: Item) {
if (a.w === b.w) {
if (a.h === b.h) {
return 0
}
if (a.h < b.h) {
return 1
}
return -1
}
if (a.w < b.w) {
return 1
}
return -1
}
function mappedArray(ary: Item[], keys: Map<string, any>) {
const res: Array<{ w_hs: number, ws_h: number, item: Item[] }> = [];
getIndex(ary.length).map((v) => {
const ary1 = ary.filter((k, i) => i !== v.x && i !== v.y);
return [[...ary1, {
w: ary[v.x].w * ary[v.y].w,
h: ary[v.x].h * ary[v.y].w + ary[v.x].w * ary[v.y].h,
s: [ary[v.x], ary[v.y]]
}], [...ary1, {
h: ary[v.x].h * ary[v.y].h,
w: ary[v.x].w * ary[v.y].h + ary[v.x].h * ary[v.y].w,
s: [ary[v.x], ary[v.y]]
}]]
}).forEach(v => {
v.forEach(sub => {
const s2 = sub.sort(sortItem)
const k = JSON.stringify(s2);
if (keys.has(k)) {
return
}
if (sub.length > 2) {
res.push(...mappedArray(sub, keys))
} else {
const v4 = [sub[0].w * sub[1].w, sub[0].h * sub[1].w + sub[0].w * sub[1].h, sub[0].w * sub[1].h + sub[0].h * sub[1].w, sub[0].h * sub[1].h];
res.push({
item: sub,
ws_h: Math.min(v4[0], v4[1]) / Math.max(v4[0], v4[1]),
w_hs: Math.min(v4[2], v4[3]) / Math.max(v4[2], v4[3])
})
}
})
})
return res;
}
//宽高比
const items: Item[] = [
{ w: 1, h: 1 },
{ w: 1, h: 1 },
{ w: 2, h: 1 }]
console.log(JSON.stringify(items));
const ary2 = mappedArray(items, new Map<string, any>());
const arysorted = ary2.sort((a, b) => Math.max(a.w_hs, a.ws_h) - Math.max(b.w_hs, b.ws_h))
console.log(JSON.stringify(arysorted, null, '\t'));
生成JSON结果:
[
{
"item": [
{
"w": 2,
"h": 1
},
{
"w": 1,
"h": 2,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 1,
"h": 1
}
]
}
],
"ws_h": 0.4,
"w_hs": 0.4
},
{
"item": [
{
"w": 2,
"h": 1
},
{
"w": 1,
"h": 2,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 1,
"h": 1
}
]
}
],
"ws_h": 0.4,
"w_hs": 0.4
},
{
"item": [
{
"w": 2,
"h": 3,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 2,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.4,
"w_hs": 0.6
},
{
"item": [
{
"w": 2,
"h": 3,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 2,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.4,
"w_hs": 0.6
},
{
"item": [
{
"w": 2,
"h": 3,
"s": [
{
"w": 2,
"h": 1
},
{
"w": 1,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.4,
"w_hs": 0.6
},
{
"item": [
{
"w": 2,
"h": 3,
"s": [
{
"w": 2,
"h": 1
},
{
"w": 1,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.4,
"w_hs": 0.6
},
{
"item": [
{
"h": 1,
"w": 3,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 2,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.75,
"w_hs": 0.25
},
{
"item": [
{
"h": 1,
"w": 3,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 2,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.75,
"w_hs": 0.25
},
{
"item": [
{
"h": 1,
"w": 3,
"s": [
{
"w": 2,
"h": 1
},
{
"w": 1,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.75,
"w_hs": 0.25
},
{
"item": [
{
"h": 1,
"w": 3,
"s": [
{
"w": 2,
"h": 1
},
{
"w": 1,
"h": 1
}
]
},
{
"w": 1,
"h": 1
}
],
"ws_h": 0.75,
"w_hs": 0.25
},
{
"item": [
{
"w": 2,
"h": 1
},
{
"h": 1,
"w": 2,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 1,
"h": 1
}
]
}
],
"ws_h": 1,
"w_hs": 0.25
},
{
"item": [
{
"w": 2,
"h": 1
},
{
"h": 1,
"w": 2,
"s": [
{
"w": 1,
"h": 1
},
{
"w": 1,
"h": 1
}
]
}
],
"ws_h": 1,
"w_hs": 0.25
}
]
最后一个数据分析,
宽:高= 1:1 的两张图片,首先组合生成 宽:高=2:1 的图,然后再跟宽:高=2:1的图片,可组成 正方形。