web-dev-qa-db-ja.com

requestAnimationFrameは1回だけ呼び出されます

Ionic 2アプリケーションでThreeJSを使用して、かなり基本的なアニメーションを実現しようとしています。基本的に立方体を回転させようとしています。しかし、requestAnimationFrameは内部で1回だけ実行されるため、立方体は回転しません。レンダリングループ。

これしか見えません。 enter image description here

回転アニメーションはありません。以下のコードを共有しています。

home.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <div #webgloutput></div>
</ion-content>

home.ts

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController } from 'ionic-angular';

import * as THREE from 'three';


@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild('webgloutput') webgloutput: ElementRef;


  private renderer: any;
  private scene: any;
  private camera: any;
  private cube: any;

  constructor(public navCtrl: NavController) {
  }

  ngOnInit() {
    this.initThree();
  }

  initThree() {
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

    this.renderer = new THREE.WebGLRenderer();
    this.renderer.setSize( window.innerWidth, window.innerHeight );
    this.webgloutput.nativeElement.appendChild(this.renderer.domElement);

    let geometry = new THREE.BoxGeometry(1, 1, 1);

    let material = new THREE.MeshBasicMaterial({ color: 0x00ff00});
    this.cube = new THREE.Mesh(geometry, material);
    this.scene.add(this.cube);
    this.camera.position.z = 5;

    this.render();
  }


  render() {
    console.log("render called");
    requestAnimationFrame(() => this.render);

    this.cube.rotation.x += 0.5;
    this.cube.rotation.y += 0.5;
    this.renderer.render(this.scene, this.camera);
  }

}
10
somnathbm

問題は、requestAnimationFrameを正しく呼び出していないことです。レンダリング関数を直接渡すのではなく、がレンダリング関数を返すラムダ関数を渡します。

requestAnimationFrame(() => this.render);requestAnimationFrame(this.render);に変更します

編集:

ES2015クラスを現在のように使用する場合、クラスメソッドはオブジェクトプロパティとして宣言される関数であることを覚えておくことが重要です。コンテキスト(this)は、メソッドがアタッチされるオブジェクトになります。そのため、メソッドをrequestAnimationFrame(...)メソッドに渡すと、同じオブジェクト参照で呼び出されなくなります。このため、renderメソッドのコンテキストをバインドしてからrequestAnimationFrame(...)に渡す必要があります。

requestAnimationFrame(this.render.bind(this));

これは このブログ投稿 でよく説明されています。 (Reactに焦点を当てていることを気にしないでください。原則と例はES2015固有です)。

27
micnil