HTML5画布-用于在网格中放置元素的循环
HTML5 Canvas - For loop to place elements in grid
我正在HTML5画布中构建一个简单的级别放置脚本,在实际放置每个元素时遇到了问题。我已经编写了一个创建网格的for循环,然后我试图创建一个新的循环,它迭代我的"level"数组中的每个语句,为每个图像设置位置。我以前没有用Canvas做过很多工作;因此,我不确定我在放置这些图像方面做错了什么;我在jQuery中写了一些类似的东西,效果很好——事实上,我一开始就复制并粘贴了代码,但它似乎在Canvas中不起作用。任何帮助都将不胜感激!
以下是代码片段;请原谅我的过度评论,这只是我在理解为什么有些东西不起作用时会做的一件事。它就像一只直排的橡皮鸭。
var $levelArray = [
[0, 0, 0, "blue", "blue"],
[0, "gray", 0, 0, 0],
["blue", "blue", "green", 0, "blue"],
["blue", 0, "yellow", 0, 0],
[0, 0, 0, "gray", 0],
["red", 0, 0, 0, 0]];
var border = 5, // set grid details
spaceWidth = 80,
spaceAmount = 5;
// create a tiled image
function makeTile(imageUrl, horizontalPosition, verticalPosition) {
var tile = new Image();
tile.onload = function() {
context.drawImage(tile, horizontalPosition, verticalPosition);
}
tile.src = imageUrl;
}
// place the image tiles on the board
for (var i=0; i < ($levelArray.length - 1); i++) {
var row = $levelArray[i]; // set each row's iterative position
var rowHeight = 5;
for (var j=0; j < row[j].length; j++) {
var rowPosition = 5; // set the left margin of each element
if (row[j] == 0) {
rowPosition += (spaceWidth + 5); // if an element does not exist, jump forwards to the next space
} else {
//if one DOES exist, place an image in this space
makeTile("http://lorempixel.com/80/80", rowPosition, rowHeight);
rowPosition += (spaceWidth + 5); // then move to the next space
};
};
rowHeight += (spaceWidth + 5); // once a row is complete, drop to the next row's positions
};
我把这个放在代码笔里:http://codepen.io/sarsparillo/pen/vNrWQG
我不知道为什么它一次只加载一个图像,并将其放在我网格上的0,0空间中;在jQuery中使用非常相似的代码(当前的代码到处都是,有点不干净,在这里-http://codepen.io/sarsparillo/pen/GpdjYY)把元素放在正确的位置很好。
此外,当我在for循环中添加console.log语句时,我真的不知道它是从哪里获取数据的。比如,一次迭代给了我"绿-绿-黄"作为第[j]行中的项目,另一次迭代是"蓝-灰-蓝"——Canvas在迭代数组时会做一些非常奇怪的事情吗?我看不出它怎么可能,因为这只是Javascript,但是。。。?
有人知道为什么会发生这种情况吗,或者有什么关于我如何解决的建议吗?理论上,它应该只是在每个"正方形"的起点加上空格宽度+边距宽度,所以我不确定为什么它只是。。。不是。
jsFiddle:https://jsfiddle.net/CanvasCode/4gr9apqm/
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var border = 5, // set grid details
spaceWidth = 80,
spaceAmount = 5;
var $levelArray = [
["blue", 0, 0, "blue", "blue"],
[0, "gray", 0, 0, 0],
["blue", "blue", "green", 0, "blue"],
["blue", 0, "yellow", 0, 0],
[0, 0, 0, "gray", 0],
["red", 0, 0, 0, 0]
];
canvas.width = (spaceWidth * spaceAmount) + (5 * spaceAmount) + 5; // and here's the canvas size
canvas.height = (spaceWidth * spaceAmount) + (5 * spaceAmount) + 5;
// make a rounded corner square; using a sizing hack to make sure that strokes don't effect the full size of the item
function square(originX, originY, size, corner, fill) {
var startFromX = originX + (corner / 2);
var startFromY = originY + (corner / 2);
var extentsX = startFromX + (size - corner);
var extentsY = startFromY + (size - corner);
context.lineJoin = "round";
context.lineWidth = corner;
context.fillStyle = "#513574";
context.strokeStyle = fill;
context.beginPath();
context.moveTo(startFromX, startFromY);
context.lineTo(startFromX, extentsY);
context.lineTo(extentsX, extentsY);
context.lineTo(extentsX, startFromY);
context.closePath();
context.stroke();
context.fill();
}
// build a grid of said squares
function squareGrid(spacing, size, corner, color, amount) {
for (var x = 0; x < amount; x++) {
// build rows
for (var y = 0; y < amount; y++) {
// build column spacing in each row
square(5 + (size * x) + (spacing * x), 5 + (size * y) + (spacing * y), size, corner, color);
// build each square
}
};
};
// actually parse the arguments for said square
squareGrid(border, spaceWidth, (border * 2), "#f13574", spaceAmount);
// create a tiled image
function makeTile(tile, horizontalPosition, verticalPosition) {
switch (tile) {
case "blue":
context.fillStyle = "#00F";
context.fillRect(horizontalPosition, verticalPosition, 80, 80);
break;
case "green":
context.fillStyle = "#0F0";
context.fillRect(horizontalPosition, verticalPosition, 80, 80);
break;
case "red":
context.fillStyle = "#F00";
context.fillRect(horizontalPosition, verticalPosition, 80, 80);
break;
case "gray":
context.fillStyle = "#999";
context.fillRect(horizontalPosition, verticalPosition, 80, 80);
break;
case "yellow":
context.fillStyle = "#FF0";
context.fillRect(horizontalPosition, verticalPosition, 80, 80);
break;
}
};
var gapHeight = 5;
var gapWidth = 5;
for (var y = 0; y < $levelArray.length - 1; y++) {
var row = $levelArray[y];
for (var x = 0; x < row.length; x++) {
var newXPos = (gapWidth * (x + 1)) + (80 * x);
var newYPos = (gapHeight * (y + 1)) + (80 * y)
makeTile($levelArray[y][x], newXPos, newYPos);
}
}
我所改变的基本上是如何访问2D阵列和位置计算。基本上,你访问的第一件事是你的Y位置,然后从你的Y方向看那一行上的所有块。因此,我们首先找到"在我的情况下"blue, 0, 0, blue, blue
。所以所有这些块的y位置都是0,然后从0、80、160等等。但是,因为你想在块之间有一个间隙,所以你还必须将间隙乘以当时的x和y值:)
- 如何使用jquery处理php循环通过元素
- 每个$.,循环获胜't逐个迭代HTML元素
- JS.循环遍历多维数组,以计数元素在每列中的出现次数
- js循环遍历单击的元素子节点
- $.每个jquery循环打印一个“;未定义的“;对于getJSON请求后的每个元素,网格数据都会完美地打印出来
- 循环遍历元素jquery选择器
- 特定循环(html元素)方法的优点和缺点
- 循环对象时更新页面上的DIV元素
- 基于事件在循环中隐藏元素
- 在元素数组上循环只会影响最后一个元素
- 关于动态元素中循环中的事件
- 在没有大量回调函数的情况下在列表元素上循环播放同一动画
- PHP:同时循环元素粘在一起
- AngularJs localStorage在循环中删除元素
- 按数据属性循环元素并替换值
- 如何使用 for 循环 jquery 将相应的值附加到相应的 dom 元素
- JQuery:如何在循环 dom 元素时正确缩进字符串
- 使用 for 循环用逗号分隔的值填充选择元素
- 翡翠:每4个元素循环一次,改变职业
- 如何在javascript中使用提取元素循环图像