如何动态存储楼层平面图?

时间:2014-10-08 10:48:55

标签: javascript canvas html5-canvas

我有一个大学项目来创建平面图设计软件..为此,我试图在HTML Canvas和网格的帮助下创建平面图。我想保存创建到数据库中的交互式楼层平面图,但不能将楼层平面图保存在数据库中,它将转换为图像文件。我想知道如何在创建地图后在数据库中保存交互式地图。取它来做改动。

简单画布地图的代码如下..

 <!doctype>
 <html>
 <head>
 </head>
 <body style=" background: lightblue;">
 <canvas id="canvas" width="500px" height="500px"style="background: #fff; magrin:20px;"> 
 Browser does not support canvas </canvas>
 <img id="canvasImg" alt="Right click to save me!">
 <script type="text/javascript" language="javascript">                                                                                  
 var bw = 400;
 var bh = 400;
 var p = 10;
 var cw = bw + (p*2) + 1;
 var ch = bh + (p*2) + 1;

 var grid = 50;

 var canvas = document.getElementById("canvas");
 var context = canvas.getContext("2d");

 function drawBoard(){

 context.beginPath();
 for (var x = 0; x <= bw; x += grid){
 context.moveTo(0.5 + x + p, p);
 context.lineTo(0.5 + x + p, bh + p);
 }
 for (var x = 0; x <= bh; x += grid) {
 context.moveTo(p, 0.5 + x + p);
 context.lineTo(bw + p, 0.5 + x + p);
 }
 context.lineWidth = 1;
 context.strokeStyle = "black";
 context.stroke();

 }
 drawBoard();

 function drawRect() {

 context.beginPath();
 context.rect(0.5+p+5*grid, 0.5+p+3*grid, 2*grid, 3*grid);
 context.rect(0.0+p+0*grid, 0.0+p+0*grid, 0*grid, 0*grid);
 context.rect(0.5+p+3*grid, 0.5+p+3*grid, 2*grid, 3*grid);
 context.rect(0.5+p+0*grid, 0.5+p+0*grid, 2*grid, 3*grid);
 context.fillStyle = 'yellow';
 context.fill();
 context.lineWidth = 2;
 context.strokeStyle = 'blue';
 context.stroke();
 }
 drawRect();

  ////new 

 var el = document.getElementById('canvas');
 var ctx = el.getContext('2d');
 var isDrawing;

 el.onmousedown = function(e) {
 isDrawing = true;
 ctx.moveTo(e.clientX, e.clientY);
 };
 el.onmousemove = function(e) {
 if (isDrawing) {
 ctx.lineTo(e.clientX, e.clientY);
 ctx.stroke();
 }
 };
 el.onmouseup = function() {
 isDrawing = false;
 };

 }

 // save canvas image as data url (png format by default)
 var dataURL = canvas.toDataURL();

 // set canvasImg image src to dataURL
 // so it can be saved as an image
  document.getElementById('canvasImg').src = dataURL;

 </script>
 </body>
 </html>

这是输出::

enter image description here

这是静态计划,

我想动态创建并将完整的计划存储在我的数据库(MySQL)上吗?给出足够的答案。

2 个答案:

答案 0 :(得分:1)

您在此处遇到的问题表明,您的应用程序中缺少一些抽象层。

首先,您需要定义一个合适的板对象。它将具有诸如尺寸之类的属性,以某种方式组织计划部分的集合,并且很可能您将需要一些我无法猜测的其他。

你还需要一个计划部分对象,-i无法猜出什么是好名字 - 这似乎只是你的例子中的矩形。

一旦掌握了这两个对象,就可以直接排序&#39;序列化&#39;它们是一个DB,一个sql表有一个单板列表,另一个表有一个楼层部分列表&#39;通过标识符链接到他们自己的董事会。

我刚刚上了小班让你开始,小提琴在这里:

http://jsfiddle.net/48gnjwae/1/

截至目前,它与您的代码完全相同,但从这一点开始保存/恢复更容易。

// ----------------------------------------------------------

 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 DB
     this.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) {
         return this.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();
     }
 }

现在的部分:

 // ----------------------------------------------------------

 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();
     }
 }

使用中:

 // ----------------------------------------------------------

 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);

答案 1 :(得分:0)

这种经典方法称为 MVC-Pattern (ModelViewController-Pattern),您可以从模型中分离绘制逻辑,从而保留描述应绘制内容的数据。 它还将控制逻辑从绘画逻辑中分离出来。

尝试通过忽略计划的绘制方式,找到一种面向对象的方式来描述您的平面布置图。您可以通过 - 例如 - 创建Floor-Object和Room-Object来实现。 Floor-Object将包含Room-Objects。 每个Room-Object都会知道它在地板上的位置以及它的形成方式或尺寸。

该模型可以轻松保存在数据库中。

然后,您将以逻辑知道如何在画布上绘制模型的方式编写绘制逻辑。

有关MVC的更多信息,请参阅此处:http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller