画布:X值在控制台中更改,但在画布中未更改 [英] Canvas: X value changing in console but not in canvas

查看:42
本文介绍了画布:X值在控制台中更改,但在画布中未更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从API中提取坐标,并将其设置为Rectangle类.在遍历数据数组时,我可以创建每个矩形,但是在移动它们时,这就是我遇到的麻烦.

I am pulling coordinates from an API and setting them to a class of Rectangle. When looping through the data array, I am able to create each rectangle, but when it comes to moving them, that is where I am having trouble.

控制台中的x坐标在move()的setInterval处更改,但是正方形本身并未在屏幕上移动.

The x coordinates are changing in the console at the setInterval of move(), but the squares themselves are not moving across the screen.

当我在 move()中具有 c.clearRect(0,0,innerWidth,innerHeight); 时,所有矩形都消失了.没有它,他们根本不会动弹.

When I have c.clearRect(0,0,innerWidth, innerHeight); in move(), all of the rectangles disappear. Without it, they do not move at all.

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

指的是数据数组,如果索引可以被6整除,则将该正方形变为黑色.尽管在这种情况下,它不起作用.

is referring to the data array and if the index is divisible by 6, make that square black. Although, in this context, it is not working.

这是我的代码:

<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. 您只是在更新位置,而不会再次进行抽签.将 rec.draw()调用移到 setInterval 中.请记住,订购很重要.理想情况下,您应该先 update(),然后再 draw().

  1. You are only updating the position and not making the draw call again. Move the rec.draw() call inside your setInterval. Remember, ordering is important. Ideally, you should update() first and draw() later.

setInterval(function() {
  rec.move();
  rec.draw();
}, 50);

  • 也请从 move()函数中删除这些行,因为您不想在每次更新变量时都清除画布.在 draw()函数的开头清除画布.另外,由于您要处理 fillRect(),因此不需要包含 beginPath()

  • Also, remove these lines from the move() function as you don't want to clear the canvas every time you update the variables. Clear the canvas in the beginning of the draw() function. Plus, since you're dealing with fillRect(), you dont need to include beginPath()

    c.clearRect(0,0,innerWidth, innerHeight);
    ...
    c.beginPath();
    

  • 您首先需要指定 fillStyle ,然后继续使用 fillRect()绘制矩形,而不要反过来. draw()函数应如下所示:

  • You first need to specify the fillStyle then proceed with drawing the rectangle using fillRect(), not the other way round. The draw() function should look like this:

    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);
    }
    

  • 在第3点的代码块中,您正在类本身的实例(即 this )而不是数字上使用Modulus运算符.我假设您想要在其中添加 this.x 之类的东西.

  • In the code block in point number #3 you are using the Modulus Operator % on the the instance of the class itself i.e. this and not a number. I'm assuming you want something like this.x in there.

    除上述几点外,您的代码还存在一些问题.但这不在这个问题的范围内.

    Apart from the points above there are still a handful of issues with your code. But it's outside the context of this question.

    针对以下最终解决方案进行了

    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);
        }
    
    }
    

    这篇关于画布:X值在控制台中更改,但在画布中未更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆