从javascript对象中调用requestAnimationFrame

问题描述 投票:0回答:2

我试图解决这个问题。我是OO Javascript的新手,并试图整理我的第一个类/对象。我正在尝试创建一个画布加载器,它不起作用。我已经将错误缩小到我的clock类中的animate函数中的requestAnimationWindow部分。我得到一个Object [object global]没有方法'animate'错误。这是我的代码。

HTML:

<div id="loader"><canvas id="showLoader" width="250" height="250"></canvas><div id="showTimer"><p id="elapsedTime">
  <script>
    var clockTest = new clock(document.getElementById("showLoader"), 0, 100);
    clockTest.animate();
  </script>

</p></div></div>

使用Javascript:

function clock(canvas, curPerc, endPrecent){

var showPerc = document.getElementById("elapsedTime");
this.canvas = document.getElementById("showLoader");

var context = this.canvas.getContext('2d');
var x = this.canvas.width / 2;
var y = this.canvas.height / 2;
var radius = 75;
this.curPerc = 0;
this.endPercent = 110;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;


context.lineWidth = 10;
context.strokeStyle = '#ed3f36';


this.animate = function(current) {

    this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.context.beginPath();
    this.context.arc(x, y, radius, -(quart), ((circ) * current) - quart, false);
    this.context.stroke();
    this.curPerc++;

    if(this.curPerc < this.endPercent) {
        requestAnimationFrame(function () {
            this.animate(curPerc / 100);
            showPerc.innerHTML = this.curPerc + '%';
        });
    }
};

}

任何提示表示赞赏。谢谢!

javascript html5 canvas loader
2个回答
1
投票

它是在你传递给requestAnimationFrame的匿名函数中使用它的上下文,而不是你认为的this。使用封闭即

this.animate = function(current) {
    var self = this; //<-- Create a reference to the this you want
    self.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    /.. etc, etc..

    if(self.curPerc < self.endPercent) {
        requestAnimationFrame(function () {
            self.animate(self.curPerc / 100); //<-- and use it here
            showPerc.innerHTML = self.curPerc + '%'; //<-- and here
        });
    }
};

在其他几点上,我会尝试更好地构造对象,您似乎没有正确地保持对属性的引用。您传入的参数不存储在对象上,并且您没有正确存储上下文。就像是:

function clock(canvas, curPerc, endPrecent) {
    var self = this;
    // Set object properties here, i.e. from the parameters passed in
    // Note also, anything that is a property (i.e. this. ) is public, can be accessed from otuside this object,
    // whereas variable declared with var , are privte, can only be access within this object
    self.canvas = canvas;
    self.curPerc = curPerc;
    self.endPercent = endPrecent;
    self.context = self.canvas.getContext('2d'); //needs to be store like this, if you want to access below as this.context
    self.context.lineWidth = 10;
    self.context.strokeStyle = '#ed3f36';

    //Private variables
    var showPerc = document.getElementById("elapsedTime");   
    var x = self.canvas.width / 2;
    var y = self.canvas.height / 2;
    var radius = 75;  
    var counterClockwise = false;
    var circ = Math.PI * 2;
    var quart = Math.PI / 2;

    //Methods
    self.animate = function (current) {
        self.context.clearRect(0, 0, self.canvas.width, self.canvas.height);
        self.context.beginPath();
        self.context.arc(x, y, radius, -(quart), ((circ) * current) - quart, false);
        self.context.stroke();
        self.curPerc++;

        if (self.curPerc < self.endPercent) {
            requestAnimationFrame(function () {
                self.animate(curPerc / 100);
                showPerc.innerHTML = self.curPerc + '%';
            });
        }
    };
}

开始走向更好的方向。


0
投票

我从ES6类方法中调用requestAnimationFrame时使用three.js遇到了同样的问题,我最终解决它的方式是:

animate() {
    requestAnimationFrame(() => this.animate());
    this.render();
}
© www.soinside.com 2019 - 2024. All rights reserved.