javascript - 二维无限循环元素数组

标签 javascript math canvas logic

目标:

这个想法是创建一个元素网格(例如图片库),它会在两个轴上滚动无限循环。 不应有空洞或过多的随机性(避免相同的元素随机地从自身中掉落)。而且无论一开始有多少元素(似乎很容易在 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">&uarr;</button>
  <button class="down">&darr;</button>
  <button class="left">&larr;</button>
  <button class="right">&rarr;</button>
</div>


你可以看到我留下了一些简单的按钮来实现移动,但它们还没有发挥作用。如果您想按照我在这里所做的事情继续实现,您可以将您的元素渲染到可见框架之外的某个范围,然后实现某种动画重新定位。这里的 renderElements 函数只渲染可见的东西,所以你可以使用类似的东西而不会陷入渲染无限元素的困境,即使你可以“滚动”的距离没有理论上的限制。

关于javascript - 二维无限循环元素数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46012938/

相关文章:

javascript - 如何获取iframe对象的来源

javascript - 如何转义冒号(:) in XML for XML Reader in extjs 4

java - Apache commons 数学优化在每次迭代中获得最佳解决方案

c - 在 C 中将整数数组添加为整数

ruby-on-rails - 如何使用 rails 的 Active Storage 从 Rails 表单中的 <canvas/> 将图像上传到 S3?

javascript - 编辑javascript Canvas 动画

javascript - 读取 JSON Tiled map 编辑器文件并显示到 Canvas

javascript - Ripple 模拟器 + Android 项目与 PhoneGap

javascript - JS ProgressEvent 仅在完成时触发

java - java中反转整数(关于方法的问题)