【问题标题】:How does the TED Talk home page organise the grid of videos?TED Talk 主页如何组织视频网格?
【发布时间】:2013-11-24 05:57:26
【问题描述】:

我一直在努力弄清楚TED Talk homepage 的工作原理。撇开所有的动画垃圾不谈,我发现盒子的组织方式真的很吸引人。

乍一看像jQuery masonry plugin,但很快就会发现它倾向于创建几个直角三角形,但没有固定的列数或行数,最终生成的形状总是完全立体的(没有空心部分)。

我最初的假设是这些盒子(它们的大小由网站上的某些因素预先确定)是随机排序的,然后使用一些简单的规则按顺序添加到网格中,但是我无法确定这些规则可能是什么,或者他们如何防止最终形状出现任何空洞。

有人知道这是如何工作的吗?

【问题讨论】:

  • 它有什么迷人之处?每个视频都放在一个 div 中,并且 div 的位置和大小是绝对的,这在我看来很容易!尝试在源代码中搜索“theAppContainer”div
  • 想详细说明答案吗?
  • 我的意思是,你可以创建一个带有矩形和正方形的随机布局,它不一定是你需要研究的分形模式。并且可以使用具有绝对位置和大小的 div 创建布局!
  • @ChingPing 我不是在谈论微不足道的实现,而是有趣的算法。 :P

标签: algorithm grid-layout


【解决方案1】:

可能是错误的,但有几点意见:

  • 每个部分有 19 个视频
  • 有 4 种尺寸 1 (#1)、1/4 (#2)、1/16 (#3) 和 1/32 (#4)

对于给定的部分,总是有 4(#1)。 (#2)、(#3) 和 (#4) 的数量可以是:

  • 4(#1), 10(#2), 4(#3), 1(#1) = 19
  • 4(#1), 11(#2), 4(#3), 0(#1) = 19
  • 4(#1), 11(#2), 3(#3), 1(#1) = 19
  • 4(#1), 12(#2), 2(#3), 1(#1) = 19
  • 4(#1), 13(#2), 1(#3), 1(#1) = 19

关于顺序:

  • 第一行始终包含 2(#1) 和 4(#2)
  • (#4) 始终位于列的底部

【讨论】:

  • 我去看看,没想到这么专业,好无聊!
  • 我刚刚看了,发现这个排列:3(#1), 12(#2), 4(#3), 0(#4) = 19
【解决方案2】:

这是执行此操作的 javascript 代码(您需要一个带有 div#container 的 html 页面):

function ted_layout(settings, coordinates_array, num_elements, start_x, start_y, arrangement, remaining_elements, is_child){
    var num_columns = arrangement.length;
    var col = 0;
    var current_x = start_x;
    while( col < num_columns){
        var column_x_scale = 100 / arrangement[col];
        var current_column_arrangement;
        if(is_child){
            if(num_elements > 14){
                if(column_x_scale == 50){
                    current_column_arrangement = random_shuffle([1, 2, 2]);
                } else {
                    current_column_arrangement = random_shuffle([1, 2]);
                }
            } else if(num_elements > 10){
                if(column_x_scale == 50){
                    current_column_arrangement = [1];
                } else {
                    current_column_arrangement = random_shuffle([1, 2]);
                }
            } else{
                    current_column_arrangement = random_shuffle([1, 2]);
            }
        } else {
            if(num_elements > 14){
                if(column_x_scale == 25){
                    current_column_arrangement = [1, 1];
                } else {
                    current_column_arrangement = [1];
                }
            } else if(column_x_scale == 25){
                    current_column_arrangement = [1, 1];
            } else {
                    current_column_arrangement = [1];
            }
        }


        var num_rows = current_column_arrangement.length;
        var current_y = start_y;
        var row = 0;
        while(row < num_rows){

            var numRects = current_column_arrangement[row];
            var current_rectangle = 0;
            var current_rectangle_x = current_x;

            while( current_rectangle < numRects){
                if(remaining_elements == 0){
                   return coordinates_array;
                }
                var currScale = column_x_scale/numRects;
                var height = settings.height * currScale*0.01;
                var width = settings.width * currScale*0.01;
                if(current_rectangle == numRects-1 && row == num_rows-1 && is_child && Math.random() > 0.5){
                    coordinates_array.push({x: current_rectangle_x, y:current_y, w:width/2, h:height/2, scale:currScale/2*0.01*2})
                }
                else{
                    coordinates_array.push({x: current_rectangle_x, y:current_y, w:width, h:height, scale:currScale*0.01*2})
                }
                current_rectangle_x += width;
                remaining_elements--;
                current_rectangle++;
            }
            row++;
            current_y += height;
        }
        current_x = current_rectangle_x;
        col++;
    }
    if( remaining_elements > 0){
        coordinates_array = ted_layout(settings, coordinates_array, num_elements, start_x, current_y, random_shuffle([2, 4, 4, 2]), remaining_elements, true);
    }
    return coordinates_array;
}


function generate_ted_layout(num_elements){
    var settings = {
        width: 640,
        height: 480,
    };
    var coordinates_array=[];
    returned = ted_layout(settings, coordinates_array, num_elements, 0, 0, random_shuffle([2, 4, 4, 2]), num_elements, false);
    console.log("Returned", returned)
    return returned;
}

function random_shuffle(array){
    var temp;
    for(var i = array.length - 1; i >= 1; i--){
        var elem = Math.floor(Math.random() * (i + 1));
        temp = array[elem];
        array[elem] = array[i];
        array[i] = temp;
    }
    return array;
}


function initAndLayout() {
    var items = generate_ted_layout(20);

    var container = $('#container');    // cache jquery object
    console.log(items);
    for (var i = 0; i < items.length; i++)
    {
        var item = items[i];
        console.log(item);
        $('#container').append($('<div class="item"></div>').css({'left': item.x, 'top': item.y, 'width': item.w, 'height': item.h}));
    }
}

【讨论】:

  • 显然这是最好的答案。这正是页面的工作方式。只是缺少随附的说明。
【解决方案3】:

我想我已经解决了。

首先,项目的数量变化很大,我目前正在查看一个只有 13 个框的页面。

首先,我将从最大到最小的 4 种大小的块中的每一个命名为: A,B,C,D

我们知道第一行包含两个 As 和两个垂直的 B 堆栈,例如:

 _______________________
|   A   | B |   A   | B |
|       |___|       |___|
|       | B |       | B |
|_______|___|_______|___|

这些排列似乎是随机的,但 B 始终处于相同的垂直模式。刚才看这个才发现只有两行,第二行也是这样。

第二行是第一行高度的两倍,占据了页面的其余部分。它由水平堆叠的形状图案构成,这些图案(至少部分)是随机选择的。

我找到了 9 种这样的形状图案,其中两种是单一的 A 或 B,其余的是:

  _______    _______    _______    ___    ___    _______    ___
 | B | B |  |   A   |  | B | B |  |C|C|  | B |  |   A   |  |C|C|
 |___|___|  |       |  |___|___|  | B |  |___|  |       |
 |   A   |  |       |  | B | B |  |___|  |C|D   |       |
 |       |  |_______|  |___|___|                |_______|
 |       |  | B | B |  |   A   |                | B |    
 |_______|  |___|___|  |       |                |___|    
 |B  |C|    |B  |C|    |       |
 |___|      |___|      |_______|

下一个问题是如何选择这些?可能需要一些巧妙的搜索来找到最佳配置:例如,如果要显示 X 个项目,我们需要找到一个总 X 不超过行宽的配置。

这可以通过图案密度的度量来完成,即块数除以图案的宽度。

【讨论】:

    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2011-10-21
    • 1970-01-01
    相关资源
    最近更新 更多