Estoy tratando de lograr una animación bastante básica usando ThreeJS en mi aplicación Ionic 2. Básicamente tratando de rotar un cubo. Pero el cubo no gira porque requestAnimationFrame se ejecuta solo una vez dentro del ciclo de procesamiento.
Sin animación giratoria. Estoy compartiendo mi código a continuación.
inicio.html
<ion-header> <ion-navbar> <ion-title> Ionic Blank </ion-title> </ion-navbar> </ion-header> <ion-content> <div #webgloutput></div> </ion-content>
casa.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); } }
El problema es que no está llamando correctamente a su requestAnimationFrame. No le está pasando la función de procesamiento directamente, sino una función lambda que devuelve la función de procesamiento.
Cambia la línea requestAnimationFrame(() => this.render);
a requestAnimationFrame(this.render);
Editar:
Cuando utilice clases de ES2015 como usted, es importante recordar que los métodos de clase son funciones que se declaran como propiedades de objetos. El contexto (este) será el objeto al que se adjunta el método. Entonces, al pasar el método al método requestAnimationFrame(...)
, ya no se llamará con la misma referencia de objeto. Debido a esto, necesitamos enlazar el contexto del método de renderizado antes de pasarlo a requestAnimationFrame(...)
:
requestAnimationFrame(this.render.bind(this));
Esto se explica bien en esta publicación de blog . (no importa que se centre en React, los principios y ejemplos son específicos de ES2015).
El propósito de requestAnimationFrame no es hacer animaciones, su propósito es llamar a la función proporcionada en el siguiente cuadro, por lo que básicamente estamos llamando a la misma función en cada cuadro.
requestAnimationFrame(justNameofFun);
es decir
const clock = new THREE.Clock(); const tick = () => { const elapsedTime = clock.getElapsedTime() cube1.rotation.y = elapsedTime * Math.PI * 1; renderer.render(scene, camera); window.requestAnimationFrame(tick); };
// Llamar al menos una vez para realizar requestanimationframe
tick();