How Can I Store Floor Plan Dynamically?
Solution 1:
The issue you're having here shows that there is some missing layer(s) of abstraction in your application.
First thing is you need to define a proper board object. It will have properties such as it size, a somehow organized collection of the plan part, and most likely you'll need some others i cannot guess.
You need also a plan part object, -i can't guess what would be a good name- which seems to be only rectangles on your example.
Once you have those two object, it's pretty much straightforward to 'serialize' them to a DB, with a sql table having a list of boards, and another table having a list of 'floor parts' linked to their own board through an identifier.
I just made small classes to get you started, fiddle is here :
http://jsfiddle.net/48gnjwae/1/
As of now, it does the same thing as your code, but it will be way easier to save/restore things from that point.
// ----------------------------------------------------------
function Board(gridWidth, gridHeight, graphicSize) {
this.gridWidth = gridWidth;
this.gridHeight = gridHeight;
this.graphicSize = graphicSize;
this.planParts = [];
// no need to serialize this property // but you have to rebuild it after loading from DBthis.grid = new Array(gridWidth * gridHeight)
}
Board.prototype = {
draw: function (ctx) {
this.drawGrid(ctx);
for (var i = 0; i < this.planParts.length; i++) {
this.planParts[i].draw(ctx);
}
},
canAdd: function (part) {
// uses getGrid to check no cell is already covered// for (x) { for (y) { if this.getGrid(x,y) return false}}// return true;
},
addPart: function (part) {
this.planParts.push(part);
// + setGrid for all covered cells// for (x) { for (y) { this.setGrid(x,y,true)}}
},
getGrid: function (x, y) {
returnthis.grid[x + y * this.gridWidth];
},
setGrid: function (x, y, val) {
this.grid[x + y * this.gridWidth] = val;
},
drawGrid: function (ctx) {
ctx.strokeStyle = "black";
ctx.save();
ctx.scale(this.graphicSize, this.graphicSize);
ctx.lineWidth = 1 / this.graphicSize;
for (var x = 0; x <= this.gridWidth; x++) {
line(ctx, x, 0, x, this.gridHeight);
}
for (var y = 0; y <= this.gridHeight; y++) {
line(ctx, 0, y, this.gridWidth, y);
}
ctx.restore();
}
}
Now the part :
// ----------------------------------------------------------
function PlanPart(board, x, y, w, h) {
this.board = board;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
PlanPart.prototype = {
draw: function (ctx) {
ctx.save();
ctx.fillStyle = 'yellow';
ctx.strokeStyle = 'blue';
ctx.scale(this.board.graphicSize, this.board.graphicSize);
ctx.lineWidth = 2 / this.board.graphicSize;
ctx.fillRect(this.x, this.y, this.w, this.h);
ctx.strokeRect(this.x, this.y, this.w, this.h);
ctx.restore();
}
}
In use :
// ----------------------------------------------------------var myBoard = new Board(8, 8, 50);
var part;
part = new PlanPart(myBoard, 0, 0, 2, 3);
myBoard.addPart(part);
part = new PlanPart(myBoard, 3, 3, 2, 3);
myBoard.addPart(part);
part = new PlanPart(myBoard, 5, 3, 2, 3);
myBoard.addPart(part);
myBoard.draw(context);
Solution 2:
The classic approach todo this is called MVC-Pattern (ModelViewController-Pattern) where you seperate the painting-logic from the model which keeps the data that describes what should be painted. It also seperates the controlling-logic from the painting-logic.
Try to find an object-oriented way to describe your floorplan by ignoring how the plan will be painted. You could do that by -for instance- creating a Floor-Object and a Room-Object. A Floor-Object would contain Room-Objects. Each Room-Object would know where it is on the Floor and how it is formed or what size it has.
That model can easy be saved in a DB.
You would then write the painting-logic in a way that the logic knows how to paint the model on the canvas.
For more Informations on MVC see here: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
Post a Comment for "How Can I Store Floor Plan Dynamically?"