Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 47x 36x 36x 257x 47x 189x 47x 36x 47x 53x 47x 16x 16x 16x 26x 36x 16x 47x 20x 20x 20x 20x 31x 53x 20x 31x 53x 53x 53x 3x 50x 20x | export interface GridSelection {
x: number;
y: number;
width: number;
height: number;
}
export interface GridOffset {
x: number;
y: number;
}
const createGrid = <T>(
values: readonly T[],
width: number,
height: number,
emptyValue: T,
): T[] => {
const size = width * height;
return Array.from(
{ length: size },
(_, index) => values[index] ?? emptyValue,
);
};
const getGridIndex = (x: number, y: number, width: number): number =>
y * width + x;
const getSelectionBounds = (
selection: GridSelection,
width: number,
height: number,
) => ({
xStart: Math.max(0, selection.x),
yStart: Math.max(0, selection.y),
xEnd: Math.min(width, selection.x + selection.width),
yEnd: Math.min(height, selection.y + selection.height),
});
const isInsideGrid = (
x: number,
y: number,
width: number,
height: number,
): boolean => x >= 0 && y >= 0 && x < width && y < height;
export const clearGridSelection = <T>(
values: readonly T[],
width: number,
height: number,
selection: GridSelection,
emptyValue: T,
): T[] => {
const result = createGrid(values, width, height, emptyValue);
const bounds = getSelectionBounds(selection, width, height);
for (let y = bounds.yStart; y < bounds.yEnd; y++) {
for (let x = bounds.xStart; x < bounds.xEnd; x++) {
result[getGridIndex(x, y, width)] = emptyValue;
}
}
return result;
};
export const moveGridSelection = <T>(
values: readonly T[],
width: number,
height: number,
selection: GridSelection,
offset: GridOffset,
emptyValue: T,
): T[] => {
const source = createGrid(values, width, height, emptyValue);
const result = [...source];
const bounds = getSelectionBounds(selection, width, height);
for (let y = bounds.yStart; y < bounds.yEnd; y++) {
for (let x = bounds.xStart; x < bounds.xEnd; x++) {
result[getGridIndex(x, y, width)] = emptyValue;
}
}
for (let y = bounds.yStart; y < bounds.yEnd; y++) {
for (let x = bounds.xStart; x < bounds.xEnd; x++) {
const targetX = x + offset.x;
const targetY = y + offset.y;
if (!isInsideGrid(targetX, targetY, width, height)) {
continue;
}
result[getGridIndex(targetX, targetY, width)] =
source[getGridIndex(x, y, width)];
}
}
return result;
};
|