您如何将画布用作课程?

时间:2019-12-01 05:58:39

标签: javascript class object canvas

我试图创建一个以画布为对象的类,以尝试了解有关类的更多信息。我编写了以下代码,但除了空白屏幕外,什么也没有。


    class Canvas
{
    constructor(canvasId = 'canvas', dimension = '2d', canvasWidth = document.body.clientWidth,canvasHeight = window.innerHeight,canvasDisplay = 'block',canvasOverflow = 'hidden')
    {
        // Initialize Canvas and Context variables
        this.can = document.getElementById(canvasId);
        this.ctx = this.can.getContext(dimension);
        //  Set canvas properties
        this.can.width = canvasWidth;
        this.can.height = canvasHeight;
        this.can.style.display = canvasDisplay;
        this.can.style.overflow = canvasOverflow;
        this.count = 0;
    }

    display(ctx) 
    {
        var ctx = ctx;
        var scrollSS = new Image();
        scrollSS.src = "../../../Assets/Media/Images/Scroll/ScrollSpriteSheet.png";
        ctx.drawImage(scrollSS,0,0,102,345,10,0,canvas.width / 10,canvas.height);
    }

    animate(ctx) 
    {   
        var ctx = ctx;
        console.log(this.count);
        this.count++;
        this.display(ctx)
        requestAnimationFrame(this.animate(ctx));   
    }


}

var canvas = new Canvas();
console.log(canvas.ctx);
canvas.animate(canvas.ctx);

我做错什么了吗?

1 个答案:

答案 0 :(得分:2)

您的问题是您正在animate()方法中一次又一次地调用requestAnimationFrame()。相反,当requestAnimationFrame()决定这样做时,您需要让JS为您调用函数animate

这意味着您需要将animate函数传递给requestAnimationFrame,而不是实际的函数 call (因为调用该函数时,您实际上是在通过它返回值):

requestAnimationFrame(this.animate.bind(this));

由于JS将处理animate方法的调用,因此this内部的animate()(当被调用时)将不是您的Canvas对象,而是{ {1}}。要使window引用您的this对象,您需要Canvas使用.bind(this)函数。以上等同于使用箭头功能:

animate

您的另一个问题是您试图在图像加载之前显示它。您首先需要加载图像,然后显示它。如果您的图像将保持不变,建议您在绘制之前先加载它,而不是每次要重绘时都加载它(请参见第二代码段)。

此外,requestAnimationFrame(() => this.animate()); 是画布实例的一部分。每个画布对象将具有在构造函数中定义的ctx属性。因此,无需将其作为.ctxanimate的参数传递,因为您可以使用display来访问它。

请参见下面的示例(请注意,该图像是临时图像):

this.ctx
class Canvas {
  constructor(canvasId = 'canvas', dimension = '2d', canvasWidth = document.body.clientWidth, canvasHeight = window.innerHeight, canvasDisplay = 'block', canvasOverflow = 'hidden') {
    // Initialize Canvas and Context variables
    this.can = document.getElementById(canvasId);
    this.ctx = this.can.getContext(dimension);
    //  Set canvas properties
    this.can.width = canvasWidth;
    this.can.height = canvasHeight;
    this.can.style.display = canvasDisplay;
    this.can.style.overflow = canvasOverflow;
    this.count = 0;
  }

  display() {
    var ctx = this.ctx;
    var scrollSS = new Image();
    scrollSS.src = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRha_-J-uQR_8pUrUQOiPYZ_JXRoqfoqDt8BO8icSfkworyz9woQQ&s";
    scrollSS.addEventListener('load', e => {
      ctx.drawImage(scrollSS, 0, 0, 102, 345, 10, 0, this.can.width / 10, this.can.height);
    });
  }

  animate() {
    this.count++;
    this.display();
    requestAnimationFrame(this.animate.bind(this));
  }
}

var canvas = new Canvas();
canvas.animate();

这是使用Promises的一种方法,如果您只需要加载一个图像,则可能要采用这种方法:

<canvas id="canvas" style="border: 1px solid black"></canvas>
class Canvas {
  constructor(canvasId = 'canvas', dimension = '2d', canvasWidth = document.body.clientWidth, canvasHeight = window.innerHeight, canvasDisplay = 'block', canvasOverflow = 'hidden') {
    // Initialize Canvas and Context variables
    this.can = document.getElementById(canvasId);
    this.ctx = this.can.getContext(dimension);
    //  Set canvas properties
    this.can.width = canvasWidth;
    this.can.height = canvasHeight;
    this.can.style.display = canvasDisplay;
    this.can.style.overflow = canvasOverflow;
    this.count = 0;
  }

  loadImage(url) {
    var img = new Image();
    img.src = url;
    return new Promise((resolve) => {
      img.addEventListener('load', function(e) {
        resolve(this);
      });
    });
  }

  display(img) {
    var ctx = this.ctx;
    ctx.drawImage(img, 0, 0, 102, 345, 10, 0, this.can.width / 10, this.can.height);
  }

  animate(img) {
    this.count++;
    this.display(img);
    requestAnimationFrame(this.animate.bind(this, img));
  }
}

var canvas = new Canvas();
var img_url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRha_-J-uQR_8pUrUQOiPYZ_JXRoqfoqDt8BO8icSfkworyz9woQQ&s"; 
canvas
  .loadImage(img_url)
  .then(function(image) {
    canvas.animate(image);  
  });