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

查看:68
本文介绍了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.

我只能看到这个.

没有旋转动画.我在下面分享我的代码.

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); 行更改为 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天全站免登陆