我有一个大学项目来创建平面图设计软件..为此,我试图在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>
这是输出::
这是静态计划,
我想动态创建并将完整的计划存储在我的数据库(MySQL)上吗?给出足够的答案。
答案 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