Как мы можем выполнить цикл анимации, используя это вместо глобальной переменной с именем main? - PullRequest
0 голосов
/ 31 мая 2018

У меня есть следующий код, где я хотел бы заменить все основные ссылки в animate на эти ссылки, чтобы избежать использования глобальной переменной внутри класса 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 для визуализации сцены.

Кроме того, в настоящее время журналы:

In execute:

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}

В Animate первый вызов:

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

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

В animate другие вызовы:

Main::animate::this null

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

Итак, как мы видим в первом вызове, и this, и main одинаковы как в функциях execute, так и в функции animate.Затем в других вызовах this в animate является нулевым, а основные кадры являются экземпляром класса 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();

Чтобы изменить параметр, передаваемый в 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::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 Класс: доступ к 'this' с помощью метода addEventListener, примененного к методу

Как вызывать функции .render и .animate внутри класса объектов?

Как создать замыкание (защитить глобальные переменные) в цикле анимации?

Что я делаю не так?

Не могли бы вы мне помочь, пожалуйста?

1 Ответ

0 голосов
/ 31 мая 2018

Вы можете bind вашей анимационной функции, так что ссылки на this всегда будут ссылаться на ваш объект, а не window по умолчанию *1006* context.

Вотпростой пример:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...