in client/src/components/special/grid-layout/layout.js [211:374]
function findAvailablePlaces (oldLayout, key, box) {
if (oldLayout.filter(item => item.i === key).length > 0) {
return;
}
const createZone = ({x, y, w, h}) => {
return {
x,
y,
x2: x + w,
y2: y + h,
w,
h,
size: w * h
};
};
const xSorter = (zoneA, zoneB) => {
if (zoneA.x < zoneB.x) {
return -1;
} else if (zoneA.x > zoneB.x) {
return 1;
}
return 0;
};
const ySorter = (zoneA, zoneB) => {
if (zoneA.y < zoneB.y) {
return -1;
} else if (zoneA.y > zoneB.y) {
return 1;
}
return 0;
};
const sizeSorter = (zoneA, zoneB) => {
if (zoneA.size < zoneB.size) {
return -1;
} else if (zoneA.size > zoneB.size) {
return 1;
}
return 0;
};
const breakpointsX = [];
if (box.w < Infinity) {
for (let i = 0; i <= box.w; i++) {
breakpointsX.push(i);
}
} else {
breakpointsX.push(0);
breakpointsX.push(box.w);
}
const breakpointsY = [0, box.h];
for (let i = 0; i < oldLayout.length; i++) {
const layoutItem = oldLayout[i];
if (breakpointsX.indexOf(layoutItem.x) === -1) {
breakpointsX.push(layoutItem.x);
}
if (breakpointsX.indexOf(layoutItem.x + layoutItem.w) === -1) {
breakpointsX.push(layoutItem.x + layoutItem.w);
}
if (breakpointsY.indexOf(layoutItem.y) === -1) {
breakpointsY.push(layoutItem.y);
}
if (breakpointsY.indexOf(layoutItem.y + layoutItem.h) === -1) {
breakpointsY.push(layoutItem.y + layoutItem.h);
}
}
breakpointsX.sort((a, b) => a - b);
breakpointsY.sort((a, b) => a - b);
let zones = [];
const layoutItemOverZone = (layoutItem, zone) => {
return layoutItem.x <= zone.x && layoutItem.x + layoutItem.w >= zone.x &&
layoutItem.x <= zone.x + zone.w && layoutItem.x + layoutItem.w >= zone.x + zone.w &&
layoutItem.y <= zone.y && layoutItem.y + layoutItem.h >= zone.y &&
layoutItem.y <= zone.y + zone.h && layoutItem.y + layoutItem.h >= zone.y + zone.h;
};
for (let i = 0; i < breakpointsX.length - 1; i++) {
for (let j = 0; j < breakpointsY.length - 1; j++) {
const zone = createZone({
x: breakpointsX[i],
y: breakpointsY[j],
w: breakpointsX[i + 1] - breakpointsX[i],
h: breakpointsY[j + 1] - breakpointsY[j]
});
zone.empty = true;
for (let z = 0; z < oldLayout.length; z++) {
if (layoutItemOverZone(oldLayout[z], zone)) {
zone.empty = false;
break;
}
}
if (zone.empty) {
zones.push(zone);
}
}
}
const buildEmptyZonesOfSize = (size, originalZones) => {
const result = [];
const findZoneWithWidthAt = (x, y, w) => {
for (let j = 0; j < originalZones.length; j++) {
if (originalZones[j].x === x && originalZones[j].y === y && originalZones[j].w === w) {
return originalZones[j];
}
}
return null;
};
const firstStepZones = [];
for (let i = 0; i < originalZones.length; i++) {
const startZone = originalZones[i];
let nextZone = startZone;
while (nextZone.y2 - startZone.y < size.h) {
let next = findZoneWithWidthAt(nextZone.x, nextZone.y2, nextZone.w);
if (next) {
nextZone = next;
} else {
break;
}
}
if (nextZone.y2 - startZone.y >= size.h) {
firstStepZones.push(createZone({
x: startZone.x,
y: startZone.y,
w: startZone.w,
h: nextZone.y2 - startZone.y
}));
}
}
const findZoneWithHeightAt = (x, y, h) => {
for (let j = 0; j < firstStepZones.length; j++) {
if (firstStepZones[j].x === x && firstStepZones[j].y === y && firstStepZones[j].h === h) {
return firstStepZones[j];
}
}
return null;
};
for (let i = 0; i < firstStepZones.length; i++) {
const startZone = firstStepZones[i];
let nextZone = startZone;
while (nextZone.x2 - startZone.x < size.w) {
let next = findZoneWithHeightAt(nextZone.x2, nextZone.y, nextZone.h);
if (next) {
nextZone = next;
} else {
break;
}
}
if (nextZone.x2 - startZone.x >= size.w) {
result.push(createZone({
x: startZone.x,
y: startZone.y,
w: nextZone.x2 - startZone.x,
h: startZone.h
}));
}
}
return result;
};
const size = defaultSizes[key] || {w: 1, h: 1};
const availableZones = buildEmptyZonesOfSize(size, zones);
availableZones.sort((zoneA, zoneB) => {
return ySorter(zoneA, zoneB) || xSorter(zoneA, zoneB) || sizeSorter(zoneA, zoneB);
});
return availableZones.filter((zone, index, array) => {
const [originalZone] = array.filter(z => z.x === zone.x && z.y === zone.y);
return array.indexOf(originalZone) === index;
});
}