代码之家  ›  专栏  ›  技术社区  ›  Code Guy

无法将画布类型的图像代码转换为SVG.js

  •  0
  • Code Guy  · 技术社区  · 5 年前

    我已经编码了一个画布图像,下面的代码能够将块打包成不同大小的给定面板。我想使用SVG实现相同的功能

    我试过使用SVG.js。我对SVG一无所知。任何指点都很好。

    SVG.js格式 用于操作和设置SVG动画的轻量级库。

    为什么选择SVG.js? js没有依赖关系,目标是尽可能小,同时提供接近完整的SVG规范覆盖范围。如果您还不确定,这里有一些要点。

    <!DOCTYPE HTML>
    <html>
    <head>
    <style>
    #canvas { background-color: #FBFBFB; }
    #unsupported               { border: 1px solid red; background-color: #FFFFAD; padding: 1em; margin: 1em; }
    textarea { resize: none; }
    select   { width: 8em;   }
    </style>
    </head>
    
    <body>
    <div id="packing">
    <div id="canvas"></div>
    <div id="desc"></div>
    </div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.7.1/svg.min.js"></script>
    
    <script src='js/demo.js'>          </script>
    
    <script>
    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);
    }
    
    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 = Parts.el.canvas.getContext("2d");
    //SVG('canvas').size(1200, 2400); 
    
        Parts.el.size.change(function() {
        	Parts.run(blocks)
    	});
        Parts.el.sort.change(function() {
        	Parts.run(blocks)
    	});
    
        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 "<br/><br/>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];
      }
    }
    
    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 = [];
    		var bb=blocks;
    		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)
    	{
    		count = count + blocks.length;
    	}
    	return count;
    }
    
    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([{
                    "w": 740,
                    "h": 580,
                    "area": 429200,
                    "id": 1,
                    "name": "Left Side Panel"
                }, {
                    "w": 740,
                    "h": 580,
                    "area": 429200,
                    "id": 2,
                    "name": "Right Side Panel"
                }, {
                    "w": 1200,
                    "h": 580,
                    "area": 696000,
                    "id": 3,
                    "name": "Bottom"
                }, {
                    "w": 1200,
                    "h": 100,
                    "area": 120000,
                    "id": 4,
                    "name": "Top"
                }, {
                    "w": 1200,
                    "h": 100,
                    "area": 120000,
                    "id": 5,
                    "name": "Top"
                }, {
                    "w": 1200,
                    "h": 740,
                    "area": 888000,
                    "id": 6,
                    "name": "Back 1"
                }, {
                    "w": 1200,
                    "h": 370,
                    "area": 444000,
                    "id": 7,
                    "name": "Back 2"
                }, {
                    "w": 1200,
                    "h": 580,
                    "area": 696000,
                    "id": 8,
                    "name": "Shelf"
                }], sheet_dim.w, sheet_dim.h))
    </script>
    
    
    </body>
    </html>
    0 回复  |  直到 5 年前