画布:X值在控制台中更改,但不在画布中更改

时间:2017-09-29 15:51:19

标签: javascript html5 canvas html5-canvas

我从API中提取坐标并将它们设置为一个Rectangle类。循环遍历数据数组时,我可以创建每个矩形,但是当它移动它们时,这就是我遇到麻烦的地方。

x坐标在控制台中在move()的setInterval处发生变化,但是正方形本身并没有在屏幕上移动。

c.clearRect(0,0,innerWidth, innerHeight);中有move()时,所有矩形都会消失。没有它,它们根本不动。

if(this % 6 === 0){
          c.fillStyle = "#000";
        } else {
        c.fillStyle = "" + this.color + "";

指的是数据数组,如果索引可以被6整除,则将该方形设为黑色。虽然,在这种情况下,它是行不通的。

这是我的代码:

<script>
const canvas = document.getElementById("canvas");
const c = canvas.getContext('2d');

let xhReq = new XMLHttpRequest();
 xhReq.open("GET", "(api here)", false);
 xhReq.send(null);
 const data = JSON.parse(xhReq.responseText);

class Rectangle {
  constructor(x, y, w, h, vx, color) {
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
      this.vx = vx;
      this.color = color;
    }
    draw() {
        c.fillRect(this.x, this.y, this.w, this.h);
        if(this % 6 === 0){
          c.fillStyle = "#000";
        } else {
        c.fillStyle = "" + this.color + "";
      }

    }
    move(){
    c.clearRect(0,0,innerWidth, innerHeight);
     if (this.x > 800 || this.x < 0){
        this.vx = -this.vx;
      }
       this.x+= this.vx;
      c.beginPath();
       console.log("here is the x value:" + this.x);

  }
}

 for(let i=0; i<data.length; i++){
    let info = data[i]
    let rec = new Rectangle(info.x, info.y, info.w, info.h, info.vx, info.color);
    rec.draw();
    setInterval(function() {
      rec.move();
    }, 50);
  }
</script>

1 个答案:

答案 0 :(得分:0)

您的代码存在很多问题。

  1. 您只是更新位置而不是再次进行绘制调用。 在rec.draw()内移动setInterval来电。 请记住,订购很重要。理想情况下,您应先update(),然后draw()

    setInterval(function() {
      rec.move();
      rec.draw();
    }, 50);
    
  2. 此外,从move()函数中删除这些行,因为每次更新变量时都不想清除画布。在draw()函数的开头清除画布。另外,由于您正在处理fillRect(),因此您无需包含beginPath()

    c.clearRect(0,0,innerWidth, innerHeight);
    ...
    c.beginPath();
    
  3. 首先需要指定fillStyle然后使用fillRect()继续绘制矩形,而不是相反。 draw()函数应如下所示:

    draw() {
        c.clearRect(0, 0, innerWidth, innerHeight);
        if(this % 6 === 0){               // <-- Not really sure what is going on here
            c.fillStyle = "#000";
        } else {
            c.fillStyle = "" + this.color + "";
        }
        c.fillRect(this.x, this.y, this.w, this.h);
    }
    
  4. 在第3号点的代码块中,您在类本身的实例上使用模数运算符%,即this而不是数字。我假设你想要this.x之类的东西。

  5. 除了以上几点之外,您的代码仍存在一些问题。但这不在这个问题的背景下。

    编辑以下最终解决方案:

    const canvas = document.getElementById("canvas");
    const context = canvas.getContext('2d');
    const xhr = new XMLHttpRequest();
    
    // Usng var as we are making an async request and need to update this variable
    var data = null;
    
    // An empty array to store our rectangles
    var collection = [];
    
    // Using an asyn request as we don't necessarily need to wait for this step
    xhr.open('GET', '<api>', true)
    
    xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
            if(xhr.status >= 200 && xhr.status < 300){
                data = JSON.parse(xhr.responseText);
                dataLoaded();
            } else {
                // The request gave an error response
            }
        }
    };
    
    xhr.send();
    
    function dataLoaded(){
        for(let i = 0; i < data.length; i++){
            let info = data[i];
            collection.push(new Rectangle(info.x, info.y, info.w, info.h, info.vx, info.color));
        }
    
        setInterval(animate, 50);
    }
    
    function animate(){
        context.clearRect(0, 0, canvas.width, canvas.height);
    
        for(let i = 0; i < collection.length; i++){
            let rect = collection[i];
    
            rect.update();
            rect.draw();
        }
    }
    
    class Rectangle {
    
        constructor(x, y, w, h, vx, color){
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.vx = vx;
            this.color = color;
        }
    
        update(){
            if (this.x > 800 || this.x < 0){
                this.vx = -this.vx;
            }
            this.x += this.vx;
        }
    
        draw(){
            context.fillStyle = this.color;
            context.fillRect(this.x, this.y, this.w, this.h);
        }
    
    }