我一直在努力弄清楚TED Talk 主页是如何运作的。撇开所有的动画垃圾不谈,我发现盒子的组织方式真的很吸引人。
乍一看像jQuery masonry 插件,但很快就发现它倾向于创建几个直角三角形,但没有固定的列数或行数,最终生成的形状总是完全实心的(没有空心部分)。
我最初的假设是这些盒子(它们的大小是由网站上的某些因素预先确定的)是随机排序的,然后使用一些简单的规则按顺序添加到网格中,但是我无法确定这些规则可能是什么,或者它们如何可以防止最终形状出现任何空洞。
有谁知道这是如何工作的?
我一直在努力弄清楚TED Talk 主页是如何运作的。撇开所有的动画垃圾不谈,我发现盒子的组织方式真的很吸引人。
乍一看像jQuery masonry 插件,但很快就发现它倾向于创建几个直角三角形,但没有固定的列数或行数,最终生成的形状总是完全实心的(没有空心部分)。
我最初的假设是这些盒子(它们的大小是由网站上的某些因素预先确定的)是随机排序的,然后使用一些简单的规则按顺序添加到网格中,但是我无法确定这些规则可能是什么,或者它们如何可以防止最终形状出现任何空洞。
有谁知道这是如何工作的?
可能是错误的,但有一些观察:
对于给定的部分,总是有 4(#1)。(#2)、(#3) 和 (#4) 的数量可以是:
至于顺序:
这是执行此操作的 javascript 代码(您需要一个带有 的 html 页面div#container):
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}));
}
}
我想我已经解决了。
首先,项目的数量变化很大,我目前正在查看一个只有 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 不超过行宽的配置。
这可以通过图案密度的度量来完成,这将是块的数量除以图案的宽度。