2017-04-18 2 views
2

J'essaie de réaliser une animation assez basique en utilisant ThreeJS dans mon application Ionic 2. Essayant fondamentalement de faire pivoter un cube. Mais le cube ne tourne pas car requestAnimationFrame n'est exécuté qu'une seule fois dans la boucle de rendu.requestAnimationFrame est appelée une seule fois

Je ne peux voir que cela. enter image description here

Aucune animation en rotation. Je partage mon code ci-dessous.

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); 
    } 

} 
+0

essayez ceci ... lorsque vous appelez this.render(); mettre cela dans un setInterval (function() {that.render}, 50)? – getbuckts

Répondre

4

Le problème est que vous n'êtes pas appeler votre requestAnimationFrame correctement. Vous ne lui passez pas la fonction de rendu directement, mais à la place une fonction lambda qui renvoie la fonction de rendu.

Modifier la ligne requestAnimationFrame(() => this.render); à requestAnimationFrame(this.render);

Edit:

Lorsque vous utilisez des classes de ES2015 comme vous êtes, il est important de se rappeler que les méthodes de classe sont des fonctions qui sont déclarées comme propriétés de l'objet. Le contexte (this) sera l'objet auquel la méthode est attachée. Ainsi, lors du passage de la méthode à la méthode requestAnimationFrame(...), elle ne sera plus appelée avec la même référence d'objet. En raison de cela, nous devons lier le contexte de la méthode render avant de passer à la requestAnimationFrame(...):

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

C'est expained bien this blog post. (ne vous dérange pas qu'il est axé sur React, les principes et les exemples sont spécifiques ES2015).

+0

Oui, j'ai essayé cela en premier lieu. Mais le compilateur lance cette erreur ** TypeError: Impossible de lire la propriété 'render' de undefined **. Il ne peut pas identifier que render est la méthode. Peut-être ici en quelque sorte ** ce ** contexte est foutu. – somnathbm

+1

@somnathbm fait '' 'requestAnimationFrame (this.render.bind (this));' '' travail? – micnil

+0

ahh ouais enfin. ça marche. merci @micnil – somnathbm