我们怎么能用这个而不是名为main的globl变量执行动画循环?

时间:2018-05-31 07:18:02

标签: javascript animation three.js

我有以下代码,我希望将动画中的所有主要引用替换为此引用,以避免在Main类中使用全局变量:

class Main {

    constructor(idDiv) {
        this.div = document.getElementById(idDiv);
        this.sceneManager = new SceneManager(this.div);
    }


    animate() {
        console.log('Main::animate::this', this);
        console.log('Main::animate::main', main);
        requestAnimationFrame(main.animate);
        main.sceneManager.animate();
    }

    execute() {

        new ManageEvents(this.div, this.sceneManager);

        const atla = new Atla();

        const repository = new Repository();

        const loadData = new LoadData(atla, repository);

        loadData.load(this.sceneManager);

        console.log('Main::execute::this', this);
        console.log('Main::execute::main', main);
        this.animate(main.sceneManager);

    }
}


const main = new Main('original');
main.execute();

目前,前面的代码创建了一个动画循环,它使用THREEjs动画渲染场景。

此外,目前的日志是:

执行中:

Main::execute::this Main {div: div#original.column, sceneManager: SceneManager}div: div#original.columnsceneManager: SceneManager {div: div#original.column, camera: PerspectiveCamera, scene: Scene, controls: T…E.TrackballControls, renderer: WebGLRenderer}__proto__: Object


Main::execute::main Main {div: div#original.column, sceneManager: SceneManager}

在动画中,首先致电:

Main::animate::this Main {div: div#original.column, sceneManager: SceneManager}

Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}

在动画中,其他人打电话:

Main::animate::this null

Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}

正如我们在第一次调用中看到的那样,在执行和动画函数中,this和main都是相同的。然后在其他调用中,animate中的this为null,主要的Stills是Main类的实例。我觉得这是因为这条线:

requestAnimationFrame(main.animate);

我们失去了这个。

另外,要替换我尝试过的主要参考文献:

class Main {

    constructor(idDiv) {
        this.div = document.getElementById(idDiv);
        this.sceneManager = new SceneManager(this.div);
    }


    animate(main) {
        console.log('Main::animate::this', this);
        console.log('Main::animate::main', main);
        requestAnimationFrame(main.animate);
        main.sceneManager.animate();
    }

    execute() {

        new ManageEvents(this.div, this.sceneManager);

        const atla = new Atla();

        const repository = new Repository();

        const loadData = new LoadData(atla, repository);

        loadData.load(this.sceneManager);

        console.log('Main::execute::this', this);
        console.log('Main::execute::main', main);
        this.animate(this);

    }
}


const main = new Main('original');
main.execute();

要将传入的参数更改为动画以引用它,即当前的Main实例。

其结果如下:

第一个电话:

Main::execute::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:34 Main::execute::main Main {div: div#original.column, sceneManager: SceneManager}
Main.js:15 Main::animate::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}

第二个电话:

Main::animate::this null
Main.js:16 Main::animate::main 697.568

Main.js:17 Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function.
    at animate (Main.js:17)

我明白这是因为在线:

    requestAnimationFrame(main.animate);

我们没有再次通过我们的主要所以我做了:

...
        requestAnimationFrame(main.animate(main));
...

然而,它会产生一个无限循环,我们再也看不到它了。还有日志:

Main::execute::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:34 Main::execute::main Main {div: div#original.column, sceneManager: SceneManager}
Main.js:15 Main::animate::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}
Main.js:15 Main::animate::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}
Main.js:15 Main::animate::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}
Main.js:15 Main::animate::this Main {div: div#original.column, sceneManager: SceneManager}
Main.js:16 Main::animate::main Main {div: div#original.column, sceneManager: SceneManager}

我也读过:

ES6 Class: access to 'this' with 'addEventListener' applied on method

How to call .render and .animate functions inside object class?

How to create closure (protect globals) in an animation loop?

我做错了什么?

你能帮我吗?

1 个答案:

答案 0 :(得分:0)

您可以bind动画功能,以便引用this始终引用您的对象,而不是requestAnimationFrame的默认window上下文。

这是一个简单的例子:



class Test {
  constructor() {
    this.name = "Window doesn't have this name!"
    this.animate = this.animate.bind(this)
  }

  animate() {
    requestAnimationFrame(this.animate)
    console.log(this.name) // window's "name" property is usually empty or undefined
  }
}

let test = new Test()
test.animate() // look at the console