我有一个使用画布的装箱实现。我正在尝试将其转换为svg输出而不是canvas。
我尝试使用Canvas2SVG,但无法获得任何输出。
以下是画布的正确工作代码。任何指针都将不胜感激。
我是否对SVG绘图中的所有画布方法都可用感到困惑
Parts = {
init: function(blocks, canvasElement) {
Parts.el = {
canvas: canvasElement,
size: $('#size'),
sort: $('#sort'),
ratio: $('#ratio'),
nofit: $('#nofit')
};
var desc = '';
/*if (!Parts.el.canvas.getContext)
return false;*/
Parts.el.draw = new C2S(Parts.el.canvas.width,Parts.el.canvas.height);
Parts.el.size.change(function() {
Parts.run(blocks)
});
Parts.el.sort.change(function() {
Parts.run(blocks)
});
var mySerializedSVG = Parts.el.canvas.getSerializedSvg();
alert(mySerializedSVG)
return ( Parts.run(blocks));
},
//---------------------------------------------------------------------------
run: function(blocks) {
var packer = Parts.packer();
Parts.sort.now(blocks);
packer.fit(blocks);
Parts.canvas.reset(packer.root.w, packer.root.h);
Parts.canvas.blocks(blocks);
Parts.canvas.boundary(packer.root);
return (Parts.report(blocks, packer.root.w, packer.root.h));
},
//---------------------------------------------------------------------------
packer: function() {
var size = "1200x2400";
var dims = size.split("x");
return new Packer(parseInt(dims[0]), parseInt(dims[1]));
},
//---------------------------------------------------------------------------
report: function(blocks, w, h) {
var fit = 0,
nofit = [],
block, n, len = blocks.length;
for (n = 0; n < len; n++) {
block = blocks[n];
if (block.fit) {
fit = fit + block.area;
} else
nofit.push("" + block.w + "x" + block.h);
}
return "Percentage of area utilized: " + (Math.round(100 * fit / (w * h))) + "%<br/>Total used area: " + fit + " mm<sup>2</sup><br/>Wastage area: " + ((w * h) - fit) + " mm<sup>2</sup><br/>";
//Parts.el.nofit.html("Did not fit (" + nofit.length + ") :<br>" + nofit.join(", ")).toggle(nofit.length > 0);
},
//---------------------------------------------------------------------------
sort: {
random: function(a, b) {
return Math.random() - 0.5;
},
w: function(a, b) {
return b.w - a.w;
},
h: function(a, b) {
return b.h - a.h;
},
a: function(a, b) {
return b.w * b.h - a.w * a.h;
},
max: function(a, b) {
return Math.max(b.w, b.h) - Math.max(a.w, a.h);
},
min: function(a, b) {
return Math.min(b.w, b.h) - Math.min(a.w, a.h);
},
height: function(a, b) {
return Parts.sort.msort(a, b, ['h', 'w']);
},
width: function(a, b) {
return Parts.sort.msort(a, b, ['w', 'h']);
},
area: function(a, b) {
return Parts.sort.msort(a, b, ['a', 'h', 'w']);
},
maxside: function(a, b) {
return Parts.sort.msort(a, b, ['max', 'min', 'h', 'w']);
},
msort: function(a, b, criteria) { /* sort by multiple criteria */
var diff, n;
for (n = 0; n < criteria.length; n++) {
diff = Parts.sort[criteria[n]](a, b);
if (diff != 0)
return diff;
}
return 0;
},
now: function(blocks) {
var sort = "area";
if (sort != 'none')
blocks.sort(Parts.sort[sort]);
}
},
//---------------------------------------------------------------------------
canvas: {
reset: function(width, height) {
Parts.el.canvas.width = width + 1;
Parts.el.canvas.height = height + 1;
Parts.el.draw.clearRect(0, 0, Parts.el.canvas.width, Parts.el.canvas.height);
var color1 = "#ffffff",
color2 = "#d0d0d0";
var numberOfStripes = width;
for (var i = 0; i < numberOfStripes * 2; i++) {
var thickness = 5;
Parts.el.draw.beginPath();
Parts.el.draw.strokeStyle = i % 2 ? color1 : color2;
Parts.el.draw.lineWidth = thickness;
Parts.el.draw.lineCap = 'round';
Parts.el.draw.moveTo(i * thickness + thickness / 2 - Math.max(height, width), 0);
Parts.el.draw.lineTo(0 + i * thickness + thickness / 2, Math.max(height, width));
Parts.el.draw.stroke();
}
Parts.el.draw.lineWidth = 3;
Parts.el.draw.strokeStyle = "#c0c0c0";
Parts.el.draw.strokeRect(0 + 0.5, 0 + 0.5, width, height);
//Parts.el.draw.fillStyle = "gray";
//Parts.el.draw.fillRect(0 + 0.5, 0 + 0.5, width, height);
},
rect: function(x, y, w, h, color, id, name) {
Parts.el.draw.fillStyle = "White";
Parts.el.draw.fillRect(x + 0.5, y + 0.5, w, h);
//Parts.el.draw.font= (w/10) + "px Comic Sans MS";
Parts.el.draw.font = "12px Roboto";
Parts.el.draw.fillStyle = "black";
Parts.el.draw.textAlign = "center";
//Parts.el.draw.fillText(id + "-" + name + " (" + w + "x" + h + ")", x+w/2, y+h/2);
Parts.el.draw.fillText("#" + id + " " + name, x + w / 2, y + h / 2);
Parts.el.draw.fillText(w + " mm", x + w / 2, y + h - 5);
Parts.el.draw.save();
Parts.el.draw.translate(x - w, y + h / 2);
Parts.el.draw.rotate(-90 * Math.PI / 180);
Parts.el.draw.fillText(h + " mm", 0, 0 + w + 15);
Parts.el.draw.restore();
},
stroke: function(x, y, w, h) {
Parts.el.draw.strokeRect(x + 0.5, y + 0.5, w, h);
},
blocks: function(blocks) {
var n, block;
for (n = 0; n < blocks.length; n++) {
block = blocks[n];
if (block.fit)
Parts.canvas.rect(block.fit.x, block.fit.y, block.w, block.h, Parts.color(n), block.id, block.name);
}
},
boundary: function(node) {
if (node) {
Parts.canvas.stroke(node.x, node.y, node.w, node.h);
Parts.canvas.boundary(node.down);
Parts.canvas.boundary(node.right);
}
}
},
colors: {
pastel: ["#FFF7A5", "#FFA5E0", "#A5B3FF", "#BFFFA5", "#FFCBA5"],
basic: ["silver", "gray", "red", "maroon", "yellow", "olive", "lime", "green", "aqua", "teal", "blue", "navy", "fuchsia", "purple"],
gray: ["#111", "#222", "#333", "#444", "#555", "#666", "#777", "#888", "#999", "#AAA", "#BBB", "#CCC", "#DDD", "#EEE"],
vintage: ["#EFD279", "#95CBE9", "#024769", "#AFD775", "#2C5700", "#DE9D7F", "#7F9DDE", "#00572C", "#75D7AF", "#694702", "#E9CB95", "#79D2EF"],
solarized: ["#b58900", "#cb4b16", "#dc322f", "#d33682", "#6c71c4", "#268bd2", "#2aa198", "#859900"],
none: ["transparent"]
},
color: function(n) {
var cols = Parts.colors["none"];
return cols[n % cols.length];
}
}
//var blocks = [{"w":500,"h":200,"name":100000},{"w":250,"h":200,"name":50000},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500},{"w":50,"h":50,"name":2500}]
//$(Parts.init(blocks));
Packer = function(w, h) {
this.init(w, h);
};
Packer.prototype = {
init: function(w, h) {
this.root = {
x: 0,
y: 0,
w: w,
h: h
};
},
fit: function(blocks) {
var n, node, block;
for (n = 0; n < blocks.length; n++) {
block = blocks[n];
if (node = this.findNode(this.root, block.w, block.h))
block.fit = this.splitNode(node, block.w, block.h);
}
},
findNode: function(root, w, h) {
if (root.used)
return this.findNode(root.right, w, h) || this.findNode(root.down, w, h);
else if ((w <= root.w) && (h <= root.h))
return root;
else
return null;
},
splitNode: function(node, w, h) {
node.used = true;
node.down = {
x: node.x,
y: node.y + h,
w: node.w,
h: node.h - h
};
node.right = {
x: node.x + w,
y: node.y,
w: node.w - w,
h: h
};
return node;
}
}
function sortAllBlocks(blocks, type) {
var func;
switch (type) {
case 'random':
func = function(a, b) {
return Math.random() - 0.5;
};
break;
case 'w':
func = function(a, b) {
return b.w - a.w;
};
break;
case 'h':
func = function(a, b) {
return b.h - a.h;
};
break;
case 'a':
func = function(a, b) {
return b.w * b.h - a.w * a.h;
};
break;
case 'max':
func = function(a, b) {
return Math.max(b.w, b.h) - Math.max(a.w, a.h);
};
break;
case 'min':
func = function(a, b) {
return Math.min(b.w, b.h) - Math.min(a.w, a.h);
};
break;
}
return blocks.sort(func);
}
function getParts(blocks, last) {
console.log(last)
var b = [];
blocks.forEach(function(a) {
var c = a.dim.split("*");
if (c[2]) {
for (var i = 0; i < c[2]; i++) {
b.push({
"w": parseInt(c[0]),
"h": parseInt(c[1]),
"area": parseInt(c[0]) * parseInt(c[1]),
'id': b.length + last,
'name': a.name
});
}
} else b.push({
"w": parseInt(c[0]),
"h": parseInt(c[1]),
"area": parseInt(c[0]) * parseInt(c[1]),
'id': b.length + last,
'name': a.name
});
});
return b;
}
function getConsumedPanels(blocks, panelWidth, panelHeight) {
var leftOver = 0;
var count = 0;
while (blocks.length > 0 && leftOver != blocks.length) {
var leftOver = blocks.length;
var r = [];
toDelete = [];
//document.write(JSON.stringify(blocks))
//document.write("<br>***************<br>")
//var packer = new Packer(panelWidth, panelHeight);
var bb = blocks;
//var bb = sortAllBlocks(blocks, "max");
//packer.fit(bb);
var newCanvas = $('<canvas/>', {
'class': 'canvas'
});
$("#canvas").append("<div><br/><br/>Panel:" + (count + 1) + " [material name] " + panelWidth + "x" + panelHeight + "<br/></div>");
$("#canvas").append(newCanvas);
$("#canvas").append(Parts.init(bb, $(".canvas")[count]))
bb.forEach(function(o, i) {
if (o.fit) {
toDelete.push(i)
} else; //document.write("Not fit");
});
for (var x = toDelete.length - 1; x >= 0; x--) {
blocks.splice(toDelete[x], 1);
}
count++;
}
if (leftOver == blocks.length) {
//document.write("Some of the parts size exceeds!" + blocks.length);
count = count + blocks.length;
}
return count;
}
function abc(W, D, H, T, SHELF_QTY, DRAWER_QTY, CABINETS_QTY) {
var p = [];
for (var i = 0; i < CABINETS_QTY; i++) {
var last = p.length + 1;
p = p.concat(getParts([{
"dim": H + "*" + D,
"name": "Left Side Panel"
},
{
"dim": H + "*" + D,
"name": "Right Side Panel"
},
{
"dim": W + "*" + D,
"name": "Bottom"
},
{
"dim": W + "*" + 100 + "*" + 2,
"name": "Top"
},
{
"dim": W + "*" + H,
"name": "Back 1"
},
{
"dim": W + "*" + D + "*" + SHELF_QTY,
"name": "Shelf"
}
], last));
}
//document.write(JSON.stringify(p))
return p;
}
var w = 100;
var d = 200;
var h = 300;
var t = 400;
var shelf_qty = 3;
var drawer_qty = 2;
var sheet_dim = {
'w': 2400,
'h': 1200
};
document.write(getConsumedPanels(abc(w, d, h, t, shelf_qty, drawer_qty, 3), sheet_dim.w, sheet_dim.h))
#canvas {
background-color: #FBFBFB;
}
#unsupported {
border: 1px solid red;
background-color: #FFFFAD;
padding: 1em;
margin: 1em;
}
textarea {
resize: none;
}
select {
width: 8em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="packing">
<div id="canvas"></div>
<div id="desc"></div>
</div>