This question is a small subset of the problem I am trying to solve. I am trying to learn to break problems into better abstractions.
The original problem I am trying to solve is:
Write a JS library which allows an user to select an Image and then divide the image into square tiles. Calculate the average color of each tile and render the equivalent number of svg elements from top to bottom and left to right direction. The request for each svg element should be an XHR request.
I decided to create two abstractions for now:
- Grid
- Tile
here is the code:
class Tile {
constructor(shape='👽', width = Tile.Width, height = Tile.Height) {
this.shape = shape;
this.width = width;
this.height = height;
}
render() {
return this.shape;
}
}
Tile.Width = 50;
Tile.Height = 50;
class Grid {
constructor(rows, cols) {
this.cells = [];
this.R = rows;
this.C = cols;
for (let row = 0; row < rows; row++) {
const cells = [];
for (let col = 0; col < cols; col++) {
cells.push({
x: col * Tile.Width,
y: row * Tile.Height,
tile: new Tile()
});
}
this.cells.push(cells);
}
}
setTile(shape, {row, col}) {
if (row < 0 || row >= this.R || col < 0 || col >= this.C) {
throw new Error("Invalid tile position");
}
this.cells[row][col] = {
x: col * Tile.Width,
y: row * Tile.Height,
tile: new Tile(shape)
};
}
render() {
let output = [];
this.cells.forEach(row => {
output.push(this.renderRow(row));
});
console.log(output.join('\n'));
}
renderRow(cells) {
let output = [];
cells.forEach(cell => {
output.push(cell.tile.render());
});
return output.join(' ');
}
}
const grid = new Grid(2, 2);
grid.setTile('👾', {row: 0, col: 1});
grid.setTile('💩', {row: 1, col: 0});
grid.setTile('👻', {row: 0, col: 1});
grid.setTile('🎃', {row: 1, col: 1});
console.log(grid.render());
Here is the live example.
Question
Does the design of the grid system is compatible with the requirement so far? I want it to be used in the canvas or some other rendering platform so is this a good design?