目标:
这个想法是创建一个元素网格(例如图片库),它会在两个轴上滚动无限循环。 不应有空洞或过多的随机性(避免相同的元素随机地从自身中掉落)。而且无论一开始有多少元素(似乎很容易在 16 (4*4) 个元素的网格中无限循环,而不是超过 17 (17*1) 个元素)。(我的猜测是任何素数根据定义,元素的数量是制作网格的痛苦)。
所以我实际上找到了一个很棒的工作示例: http://www.benstockley.com/
它实际上比我想象的非常接近(可能更好)。现在它使用 Canvas ,我试着查看 javascript,它是一个 30000 行长的缩小脚本,所以我真的看不懂它背后的任何核心逻辑。
数学方面/问题解决:
这是问题背后的逻辑和理论,涉及的数学和心态。 程序应如何处理元素列表,以便我们没有孔、无限网格、所有轴上元素的最佳分配。
我的猜测是它在某种程度上必须是程序性的。我不确定我们是否应该创建网格或在每个轴上循环遍历列表(有点像数独游戏?我不知道);
实用方面/UI/UX:
有关所涉及技术的任何建议,代码片段。我猜经典的 DOM 已经不在了,不知何故 canvas 或 2D webgl 将是强制性的。但我很想听听这方面的任何建议。
除了所有的元素网格处理。在 DOM 或渲染器中探索 2D 无限或巨大布局所涉及的 UI 和 UX 在某种程度上不是经典的。欢迎提供最好的技术或建议。
例子:
我欢迎任何在某种程度上共享此问题的一个方面的工作示例。
最佳答案
我有一个 fiddle这是为了安排您的 2d 网格而设置的。
它通过使用水平和垂直“步长”来发挥作用。因此,在网格中向右移动一步会增加列表中的水平步长。向下移动一级会增加列表中的垂直步长(并且它们会累积)。
我们允许列表中的进度在到达末尾时循环回零。
使用 1 的水平步长可能有意义(因此网格的一行将保持列表顺序)。对于垂直步长,您需要一个与列表长度没有公约数的整数。虽然不能保证,但我使用列表长度的(四舍五入的)平方根作为在很多情况下都适用的东西。
我将在这里重现 fiddle :
var list = ['red','green','blue','cyan','orange','yellow','pink'];
var hstep = 1;
var vstep = Math.ceil(Math.sqrt(list.length));
function getListItem(x,y) {
var index = x * hstep + y * vstep;
return list[index % list.length];
}
var elementSize = 30;
var gutterSize = 10;
function getOffset(x,y) {
return [10 + (elementSize + gutterSize) * x, 10 + (elementSize + gutterSize) * y];
}
var frame = $('.frame');
function drawElement(x,y) {
var listItem = getListItem(x,y);
var offsets = getOffset(x,y);
var element = $('<div></div>').addClass('element').css({
left: offsets[0] + 'px',
top: offsets[1] + 'px',
'background-color': listItem
});
frame.append(element);
}
function drawElements() {
var x = 0, y = 0;
while (10 + (elementSize + gutterSize) * x < frame.width()) {
while (10 + (elementSize + gutterSize) * y < frame.height()) {
drawElement(x,y);
y++;
}
y = 0;
x++;
}
}
drawElements();
.frame {
border: 2px solid black;
margin: 40px auto;
height: 300px;
width: 300px;
position: relative;
overflow: hidden;
}
.frame .element {
position: absolute;
width: 30px;
height: 30px;
}
.buttons {
position: absolute;
top: 0px;
width: 100%;
}
.buttons button {
position: absolute;
width: 30px;
height: 30px;
padding: 5px;
}
button.up {top: 0px; left: 46%;}
button.down {top: 355px; left: 46%;}
button.left {top: 160px; left: 15px;}
button.right {top: 160px; right: 15px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="frame">
</div>
<div class="buttons">
<button class="up">↑</button>
<button class="down">↓</button>
<button class="left">←</button>
<button class="right">→</button>
</div>
你可以看到我留下了一些简单的按钮来实现移动,但它们还没有发挥作用。如果您想按照我在这里所做的事情继续实现,您可以将您的元素渲染到可见框架之外的某个范围,然后实现某种动画重新定位。这里的 renderElements
函数只渲染可见的东西,所以你可以使用类似的东西而不会陷入渲染无限元素的困境,即使你可以“滚动”的距离没有理论上的限制。
关于javascript - 二维无限循环元素数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46012938/