用javascript实现图像的最有效径向排列方式是什么?

4

我一直在思考如何使其工作。我找不到相关的例子,也没有以前的问题。基本上,我有121个缩略图图像(具有完全相同的尺寸),将它们排列成带间距的网格,并想将第一张图片放在中心位置。 (这允许11x11的图像网格) 然后,我想采取每个下一个图像并开始安排它们围绕中心图像使用最接近中心图像的可用空位,直到用完为止。假设图像列表将从数组对象获取。完成此操作最高效的方法是什么?


这被称为“螺旋顺序填充矩阵”。尝试谷歌搜索,有很多解决方案。 - georg
2
这可能并不相关,但我被你的问题所吸引,并编写了一个jQuery脚本来解决它 - 以防有人感兴趣,我会在这里留下它的链接:http://jsfiddle.net/PxLAV/2/ - Andreas Eriksson
非常感謝您的貢獻,Andreas! - lukas56z
1个回答

4

这可能不是解决问题效率最高的方法,但我想试着玩一下:

您可以迭代遍历网格中的所有点,计算它们到中心点的距离,然后按照这个距离对点进行排序。与算法解决方案相比的优势在于您可以使用各种距离函数:

// Setup constants
var arraySize = 11;
var centerPoint = {x:5, y:5};

// Calculate the Euclidean Distance between two points
function distance(point1, point2) {
    return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2));
}

// Create array containing points with distance values
var pointsWithDistances = [];
for (var i=0; i<arraySize; i++) {
    for (var j=0; j<arraySize; j++) {
        var point = {x:i, y:j};
        point.distance = distance(centerPoint, point);
        pointsWithDistances.push(point);
    }
}

// Sort points by distance value
pointsWithDistances.sort(function(point1, point2) {
    return point1.distance == point2.distance ? 0 : point1.distance < point2.distance ? -1 : 1;
});

生成的pointsWithDistances数组将如下所示:
[
    {x:5, y:5, distance:0},
    {x:4, y:5, distance:1},
    {x:5, y:4, distance:1},
    ...
    {x:4, y:4, distance:1.4142135623730951},
    {x:4, y:6, distance:1.4142135623730951},
    ...
    {x:3, y:5, distance:2},
    ...
]

通过按照这个顺序迭代数组,你有效地从中心向外填充网格。

使用欧几里得距离

(感谢Andreas Carlbom的想法如何显示这个结构。)

看看使用曼哈顿距离的区别:

// Rectilinear Distance between two points
function distance(point1, point2) {
    return Math.abs(point1.x - point2.x) + Math.abs(point1.y - point2.y);
}

使用直线距离

对于算法方法的壳结构,您可以使用最大度量:

// 'Maximum Metric' Distance between two points
function distance(point1, point2) {
    return Math.max(Math.abs(point1.x - point2.x), Math.abs(point1.y - point2.y));
}

使用“最大度量”距离

您可以在此处尝试代码:http://jsfiddle.net/green/B3cF8/


你回答了我希望有人能够回答的问题,谢谢!也许有人会向我们展示更快的方法,但在此期间,如果按照你的示例通过绝对定位计算位置,那么如何在每个div之间添加gutters呢? 通过CSS添加margin不会影响周围div的定位... - lukas56z
是的,jsFiddle代码中的div是绝对定位的,并且瓷砖大小在代码中是固定的。我提取了一个“tileSize”变量并更新了示例,请看一下。 - Julian D.
谢谢你的工作,这让我完全朝着正确的方向前进!非常好的建议! - lukas56z
是的:http://jsfiddle.net/green/e2gFx。如果不需要瓦片无缝贴合,可以取消所有`Math.ceil`/`Math.floor`调用。 - Julian D.
我一直在尝试将中间的 DIV(用红色标出)居中于视口中,当您点击齿轮时,但是我希望这个 DIV 在页面加载时自动居中于视口。第二个问题是,在移动数组并点击齿轮时...由于超滚动的方式,它会使另一个区域的数组居中,我想找出一种克服这种情况的方法,以便每次单击齿轮时都可以将您带到中心 DIV。 这是我的演示 http://jsfiddle.net/virtuapete/QVQ5r/1/ - lukas56z
好吧,那是另外一个故事... - Julian D.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接