2017-04-18 4 views
2

Ich versuche eine ziemlich einfache Animation mit ThreeJS in meiner Ionic 2-Anwendung zu erreichen. Grundsätzlich versuchen, einen Würfel zu drehen. Der Würfel rotiert jedoch nicht, da requestAnimationFrame nur einmal innerhalb der Render-Schleife ausgeführt wird.requestAnimationFrame wird nur einmal aufgerufen

Ich kann nur das sehen. enter image description here

Keine rotierende Animation. Ich teile meinen Code unten.

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

versuchen Sie dies ... wenn Sie this.render() aufrufen; Setzen Sie das in einem setInterval (function() {that.render}, 50)? – getbuckts

Antwort

4

Das Problem ist, dass Sie nicht richtig Aufruf Ihre request werden. Sie übergeben es die Render-Funktion nicht direkt, sondern stattdessen eine Lambda-Funktion, die die Render-Funktion zurückgibt.

Ändern Sie die Zeile requestAnimationFrame(() => this.render); zu requestAnimationFrame(this.render);

Edit:

Wenn ES2015-Klassen wie Sie sind, es ist wichtig, dass Klassenmethoden Funktionen zu merken sind, die als Objekteigenschaften deklariert sind. Der Kontext (das) ist das Objekt, an das die Methode angehängt ist. Wenn die Methode also an die Methode requestAnimationFrame(...) übergeben wird, wird sie nicht mehr mit der gleichen Objektreferenz aufgerufen. Aus diesem Grund müssen wir den Kontext der Render-Methode binden, bevor es an die requestAnimationFrame(...) vorbei:

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

Dies wird expained gut in this blog post. (Es macht nichts, dass es sich auf React konzentriert, die Prinzipien und Beispiele sind ES2015-spezifisch).

+0

Ja, ich habe das auf den ersten Platz versucht. Aber dies tut Compiler löst diesen Fehler aus ** TypeError: Kann die Eigenschaft 'render' von undefined ** nicht lesen. Es kann nicht identifizieren, dass das Rendern die Methode ist. Vielleicht ist hier irgendwie dieser Kontext versaut. – somnathbm

+1

@somnathbm tut '' 'requestAnimationFrame (this.render.bind (this));' '' Arbeit? – micnil

+0

ahh ja endlich. es funktioniert. danke @micnil – somnathbm

Verwandte Themen