Javascript 尝试画书架(汗学院练习)

Javascript 尝试画书架(汗学院练习),javascript,canvas,processing,Javascript,Canvas,Processing,我正在做一个练习,在画布上根据一系列书籍对象绘制书架。具体说明如下: 现在添加更多的书,并使用循环在画布上绘制更多的书架。考虑如何使用条件和/或%运算符来实现这一点 我的代码在循环中包含一个条件,但我似乎无法让它工作。条件语句位于下面代码的末尾 //book array var books = [{ title: "The Giver", author: "Lois Lowry", coverColor: color(214, 255, 219), stars:

我正在做一个练习,在画布上根据一系列书籍对象绘制书架。具体说明如下:

现在添加更多的书,并使用循环在画布上绘制更多的书架。考虑如何使用条件和/或%运算符来实现这一点

我的代码在循环中包含一个条件,但我似乎无法让它工作。条件语句位于下面代码的末尾

//book array
var books = [{
    title: "The Giver",
    author: "Lois Lowry",
    coverColor: color(214, 255, 219),
    stars: 3
}, {
    title: "The Outsiders",
    author: "S. E. Hinton",
    coverColor: color(255, 127, 127),
    stars: 5
}, {
    title: "Harry Potter",
    author: "J. K. Rowling",
    coverColor: color(135, 193, 255),
    stars: 4
}, {
    title: "Harry Potter",
    author: "J. K. Rowling",
    coverColor: color(135, 193, 255),
    stars: 4
}];

// draw shelf
background(230, 187, 122);
fill(173, 117, 33);
rect(0, 120, width, 10);

// book loop
for (var i = 0; i < books.length; i++) {
    var book = books[i]; //setting book variable
    var xPos = i * 100;
    var yPos = 20;
    fill(book.coverColor);
    rect(xPos + 10, yPos, 90, 100);
    fill(0, 0, 0);
    textSize(11); //general book drawings
    text(book.title, xPos + 15, yPos + 5, 70, 100);
    textSize(9);
    text(book.author, xPos + 20, yPos * 2, 70, 100);

    //Seal of approval
    if (book.stars > 3) {
        var approvalSeal = getImage("cute/Star");
        image(approvalSeal, xPos + 10, yPos * 4, 30, 40);
        text("Seal of approval!", xPos + 45, yPos * 4 + 15, 50, 40);
    }

    //conditional wrap-around
    if (xPos > 350) {
        xPos = i * 100;
        yPos += 120;
    }
}
//书本数组
var账簿=[{
标题:“给予者”,
作者:“Lois Lowry”,
封面颜色:颜色(214255 219),
星星:3颗
}, {
标题:“局外人”,
作者:“S.E.辛顿”,
封面颜色:颜色(255、127、127),
星星:5
}, {
标题:“哈利波特”,
作者:“J.K.罗琳”,
封面颜色:彩色(135193255),
星星:4
}, {
标题:“哈利波特”,
作者:“J.K.罗琳”,
封面颜色:彩色(135193255),
星星:4
}];
//画架
背景(230187122);
填充(173、117、33);
矩形(0,120,宽度,10);
//书圈
for(var i=0;i3){
var approvalSeal=getImage(“可爱/明星”);
图像(批准,xPos+10,YPO*4,30,40);
文本(“批准盖章!”,xPos+45,YPO*4+15,50,40);
}
//条件环绕
如果(xPos>350){
xPos=i*100;
yPos+=120;
}
}

您应该将其置于循环之外:

var yPos = 20;
目前,在每次迭代中都要重置
yPos
,因此环绕代码永远不会生效

xpo也有一个问题。每次迭代时,您都将其设置为
i*100
,这使得它超出了书架的末端。在制作新的工具架时,您必须重置XPO

正确的方法是初始化
xPos
yPos
,绘制第一个书架,然后开始在书籍上迭代。如有必要,增加书本位置并环绕:

function drawShelf(yPos) {
  var saved = context.fillStyle;
  fill(color(173, 117, 33));
  rect(0, yPos + 120, width, 10);
  context.fillStyle = saved;
}

var xPos = 0,
    yPos = 0;

drawShelf(yPos);

for (var i = 0; i < books.length; i++) {
  var book = books[i];
  fill(book.coverColor);
  rect(xPos + 10, yPos + 20, 90, 100);
  xPos += 100;
  if (xPos > 350) {
    xPos = 0;
    yPos += 130;
    drawShelf(yPos);
  }
}
功能绘图架(yPos){
var saved=context.fillStyle;
填充(颜色(173、117、33));
矩形(0,yPos+120,宽度,10);
context.fillStyle=已保存;
}
var xPos=0,
yPos=0;
牵引架(yPos);
for(var i=0;i350){
xPos=0;
yPos+=130;
牵引架(yPos);
}
}
您可以在下面的代码段中看到此代码的运行。我添加了代码来模拟处理环境中的绘图命令,并制作了十几个随机颜色的图书对象。其他书本属性被省略

var canvas=document.getElementsByTagName('canvas')[0],
宽度=410,
高度=400,
context=canvas.getContext('2d');
画布宽度=宽度;
canvas.height=高度;
功能背景(r、g、b){
var saved=context.fillStyle;
填充(颜色(r、g、b));
矩形(0,0,宽度,高度);
context.fillStyle=已保存;
}
功能色(r、g、b){
返回'rgb('+r+'、'+g+'、'+b+');
}
函数填充(样式){
context.fillStyle=样式;
}
函数rect(x,y,w,h){
fillRect(x,y,w,h);
}
var books=新数组(12);
对于(变量i=0;i350){
xPos=0;
yPos+=130;
牵引架(yPos);
}
}

条件不执行任何操作的原因是因为它处于for循环迭代的末尾。分配的新值不做任何处理,随着下一次迭代的进行,坐标将恢复为“第一行书本”坐标。在使用这些坐标之前,需要指定这些坐标

我画(难看的)书架的方法是只对x坐标使用%操作符,对行使用地板分割。对我来说,这似乎比使用条件句更容易。书架可以看作是一个网格,按如下顺序排列

0 1 2 
3 4 5 
6 7 8 ... etc
由于您编写了
350
作为限制,因此我假设您希望每行显示3本书。请注意,x坐标会重复,如下所示

0 100 200
0 100 200
0 100 200
%运算符与正参数一起使用时,返回第一个参数的余数除以第二个参数。使用300作为第二个参数,我得到了x坐标的0、100和200的重复序列

现在,每3本书,行y坐标只会增加。因此,我使用Math.floor向下取整到我想要跳转到的确切行数,并使用这些值确定在何处绘制书籍

在我的快速演示中,我只能依靠原始画布操作。我不熟悉提供的工具

另外,我不认为你的意思是使用yPos*2或*4,因为当你向下移动几行时,这些偏移会成倍增加,而不仅仅是向下移动

var ctx=document.getElementById(“canvas”).getContext(“2d”);
函数color(){}
功能填充(r、g、b){
}
函数rect(x,y,w,h){
ctx.rect(x,y,w,h);
ctx.stroke();
}
函数文本(s、x、y、w、h){
ctx.beginPath();
移动到