requestAnimationFrame只被调用一次 [英] requestAnimationFrame is being called only once

查看:1761
本文介绍了requestAnimationFrame只被调用一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图在我的Ionic 2应用程序中使用ThreeJS实现一个非常基本的动画。基本上是试图旋转立方体。但是立方体没有旋转,因为requestAnimationFrame只在渲染循环中执行一次。

I'm trying to achieve a pretty basic animation using ThreeJS in my Ionic 2 application. Basically trying to rotate a cube. But the cube isn't rotating because requestAnimationFrame is being executed only once inside the render loop.

我只能看到这个。

I'm able to see only this.

无旋转动画。我在下面分享我的代码。

No rotating animation. I'm sharing my code below.

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

}


推荐答案

问题是您没有正确调用requestAnimationFrame。你不是直接传递渲染函数,而是传递返回渲染函数的lambda函数。

The problem is that you are not calling your requestAnimationFrame correctly. You are not passing it the render function directly, but instead a lambda function that returns the render function.

更改行 requestAnimationFrame(()=> this.render); to requestAnimationFrame(this.render);

编辑:

当您使用类似于您的ES2015课程时,请务必记住类方法是函数被声明为对象属性。上下文(this)将是该方法所附加的对象。因此,当将方法传递给 requestAnimationFrame(...)方法时,将不再使用相同的对象引用调用它。因此,我们需要绑定render方法的上下文,然后将其传递给 requestAnimationFrame(...)

When using ES2015 classes like you are, it is important to remember that class methods are functions that are declared as object properties. The context (this) will be the object that the method is attached to. So when passing the method to the requestAnimationFrame(...) method, it will no longer be called with the same object reference. Because of this, we need to bind the context of the render method before passing it to the requestAnimationFrame(...):

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

这在此博客文章。 (不介意它专注于React,原则和示例是ES2015特定的。)

This is expained well in this blog post. (don't mind that it is focused on React, the principles and examples are ES2015 specific).

这篇关于requestAnimationFrame只被调用一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆