检测div网格中的间隙

时间:2012-12-04 14:45:28

标签: javascript html css knapsack-problem bin-packing

编辑已找到解决方案!

这是关于它的blog post,这是Github repo

我正在创建一个由多个大小的框组成的div网格,这些大小设置为高度和宽度 - 但是是动态生成的,因此每次加载页面时都会有不同的网格。

我的问题 - 我尝试使用砌体,但它结束了留下空隙,也尝试了同位素。我目前正在浮动导致布局中断的元素。

如何构建 - 我计算屏幕尺寸并确定页面的最佳列数,范围从1到6,然后根据该列宽我计算一个“块”,这个块基本上是完美的网格。然后我遍历我的元素并给它们1x1,1x2,2x2维度。

The Green spaces are blank areas - black are specifically sized based on their priority

此处参考是另一个随机生成的网格 enter image description here

我的问题 - 有没有一种很好的方法来检测缺失的空间 - 目前我将我的红色和黑色框放在我的“块”的另一个网格上,这是绿色的,让我看到我在哪里缺少空间。我已经读过关于背包包装问题以及垃圾箱包装问题 - 我很难理解它们中的任何一个。

我尝试了什么 - 我试图计算,因为我放置块来确定最佳尺寸,但这仍然导致奇怪的行为。我也尝试过使用砌体和同位素。

我的底边很粗糙,但实际网格不能包含任何间隙。

注意 - 网格由潜在的无数元素组成 - 我一直在想是否要从底部区域采集并复制元素并将其放入我能够丢失的区域避免必须“转移”元素 - 我只需要知道如何找到丢失的空间。

任何帮助或指向正确的方向都会很棒!

这是jsfiddle

这是js的基本代码......

    (function() {
    GRID = function(el, sel) {
        var self = this,
            ran, ranSize, h, w;

        self.options = {
            el: $(el),
            sel: $(sel),
            cols: 1,
            block: {
                height: 0,
                width: 0
            },
            matrix: {
                w: [],
                h: [],
                t: [],
                l: []
            },
            row: {
                height: 0,
                width: 0
            },
            col: {
                height: 0,
                width: 0
            }
        };

/*
         * Size array
        */
        self.sizes = [];
        self.sizes[0] = [2, 2];
        self.sizes[1] = [1, 2];
        self.sizes[2] = [1, 1];



        self.setup = function() {

/*
             * Setup all options 
            */
            // block size
            self.options.block.height = (window.innerWidth / self.cols()) / 1.5;
            self.options.block.width = (window.innerWidth / self.cols());

            // row
            self.options.row.width = window.innerWidth;


            for (var i = 0; i < 60; i++) {
                $(".grid").append('<div class="box"></div>');
            }

            self.size_boxes();


        }
        self.size_boxes = function() {

            if (self.cols() == 1) {
                self.options.sel.height(self.options.block.height);
                self.options.sel.width(self.options.block.width);
            }
            else {
                self.options.sel.each(function() {

                    $this = $(this);

                    ran = Math.floor(Math.random() * self.sizes.length);
                    ranSize = self.sizes[ran];

                    if ($this.hasClass('promoted')) {
                        ran = 0;
                    }
                    if ($this.hasClass('post')) {
                        ran = 2;
                    }
                    h = self.options.block.height * self.sizes[ran][6];
                    w = self.options.block.width * self.sizes[ran][0];

                    // box sizes
                    $this.height(h);
                    $this.width(w);
                });
            }
            $(".grid .box").height(self.options.block.height);
            $(".grid .box").width(self.options.block.width);
        }
        self.cols = function() {
/*
             * Determine cols
            */
            var w = Math.floor(window.innerWidth);
            var cols = 0;

            if (w < 480) {
                cols = 1;
            }
            else if (w > 480 && w < 780) {
                cols = 2;
            }
            else if (w > 780 && w < 1080) {
                cols = 3;
            }
            else if (w > 1080 && w < 1320) {
                cols = 4;
            }
            else if (w > 1320 && w < 1680) {
                cols = 5
            }
            else {
                cols = 6;
            }
            return cols;
        }
        self.resize = function() {
            $(".grid").height(window.innerHeight);
            self.options.block.height = (window.innerWidth / self.cols()) / 1.5;
            self.options.block.width = (window.innerWidth / self.cols());

            self.options.row.width = window.innerWidth;

            self.size_boxes();
        }

        self.setup();
        return self;

    };
})();
var _GRID = new GRID('.gallery', '.box');​

2 个答案:

答案 0 :(得分:1)

我会用一个布尔值的内存矩阵跟踪你的“完美网格”。该矩阵存储是否填充空格。无论何时放置一个方框,都可以计算出哪些方格占用并更新矩阵。

答案 1 :(得分:0)

如果您将它们放在列中,只需将div放在列中即可。例如,如果您确定应该有4列:

<div>
    <div>Column 1, Div 1</div>
    <div>Column 1, Div 2</div>
    <div>Column 1, Div 3</div>
    <div>Column 1, Div 4</div>
</div>
<div>
    <div>Column 2, Div 1</div>
    <div>Column 2, Div 2</div>
    <div>Column 2, Div 3</div>
    <div>Column 2, Div 4</div>
</div>
<div>
    <div>Column 3, Div 1</div>
    <div>Column 3, Div 2</div>
    <div>Column 3, Div 3</div>
    <div>Column 3, Div 4</div>
</div>
<div>
    <div>Column 4, Div 1</div>
    <div>Column 4, Div 2</div>
    <div>Column 4, Div 3</div>
    <div>Column 4, Div 4</div>
</div>

当然,只有当每列中的div具有相同的高度时,这才有效。