0

This code works normally but with a little bug: without animation. It draws an axis and a cube. The cube must be animated. I see "animate" string in a console only once.

Solution. Replace this line requestAnimationFrame(() => this.animate); by this one requestAnimationFrame(this.animate.bind(this)); https://codepen.io/8Observer8/pen/oWoXyz

/// <reference path="../node_modules/@types/three/index.d.ts" />

//import * as THREE from "three";
// this line does't work. Error: Cannot find module 'three' from ...

// https://github.com/pinqy520/three-typescript-starter/blob/master/src/index.ts

class Game
{
    private _scene: THREE.Scene;
    //private _canvas: HTMLCanvasElement;
    private _camera: THREE.PerspectiveCamera;
    private _renderer: THREE.WebGLRenderer;
    private _axis: THREE.AxisHelper;
    private _light: THREE.DirectionalLight;
    private _light2: THREE.DirectionalLight;
    private _material: THREE.MeshBasicMaterial;
    private _box: THREE.Mesh;

    public constructor()
    {
        //this._canvas = <HTMLCanvasElement>document.getElementById(canvasElement);
        this._scene = new THREE.Scene(); // create the scene
        // create the camera
        this._camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this._renderer = new THREE.WebGLRenderer();
        this._axis = new THREE.AxisHelper(10); // add axis to the scene
        this._light = new THREE.DirectionalLight(0xffffff, 1.0); // add light1
        this._light2 = new THREE.DirectionalLight(0xffffff, 1.0); // add light2
        this._material = new THREE.MeshBasicMaterial({
            color: 0xaaaaaa,
            wireframe: true
        });
        // create a box and add it to the scene
        this._box = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), this._material);
    }

    public createScene(): void
    {
        // set size
        this._renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(this._renderer.domElement); // add canvas to dom
        this._scene.add(this._axis);
        this._light.position.set(100, 100, 100);
        this._scene.add(this._light);
        this._light2.position.set(-100, 100, -100)
        this._scene.add(this._light2);
        this._scene.add(this._box)
        this._box.position.x = 0.5;
        this._box.rotation.y = 0.5;

        this._camera.position.x = 5;
        this._camera.position.y = 5;
        this._camera.position.z = 5;

        this._camera.lookAt(this._scene.position);
    }

    public animate(): void
    {
        requestAnimationFrame(this.animate.bind(this));
        this._render();
    }

    private _render(): void
    {
        let timer = 0.002 * Date.now();
        this._box.position.y = 0.5 + 0.5 * Math.sin(timer);
        this._box.rotation.x += 0.1;
        this._renderer.render(this._scene, this._camera);
    }
}

window.onload = () =>
{
    let game = new Game();
    game.createScene();
    game.animate();
}
Mohammad Kermani
  • 5,188
  • 7
  • 37
  • 61
8Observer8
  • 868
  • 10
  • 17
  • How many times do you get the console log from the animate method? – Mohammad Kermani May 06 '17 at 10:54
  • I see "animate" string in a console only once. – 8Observer8 May 06 '17 at 11:08
  • Could you please try this? `requestAnimationFrame(this.animate());` – Mohammad Kermani May 06 '17 at 11:13
  • If I use `requestAnimationFrame(this.animate);` instead of `requestAnimationFrame(() => this.animate);` then I see "animate" string two times in a console but I receive this error in the console: **Uncaught TypeError: Failed to execute 'requestAnimationFrame' on 'Window': The callback provided as parameter 1 is not a function. at e.animate** – 8Observer8 May 06 '17 at 11:20
  • try using ```requestAnimationFrame(this.animate.bind(this));```. Explanation and duplicate of [this question](http://stackoverflow.com/questions/43466240/requestanimationframe-is-being-called-only-once/43505254#43505254) – micnil May 06 '17 at 11:31
  • 1
    Welcome to StackOverflow! To mark a question as solved, please don't edit the title. Instead, click the green arrow next to the answer, and consider showing some love by upvoting people who help you. – Mike Chamberlain May 06 '17 at 12:22
  • @MikeChamberlain I wanted to say same things! – Mohammad Kermani May 09 '17 at 07:07
  • Please note that you can't do that kind of edits! I just roll back your last edit. – Mohammad Kermani May 09 '17 at 11:39

2 Answers2

2

We talked in comments and I just wrote this, the code bellow is how you can make it work in TypeScript, I just added another console.log inside _render to see the result.

class Game {
    public animate()
    {
        console.log("animate()");
        this._render();
        requestAnimationFrame(()=>this.animate());

    }

    private _render(): void
    {
        console.log("From _render")

    }
}

let game = new Game();
    game.animate();

Take a look at the example on Playground and open your console when you run the example

Mohammad Kermani
  • 5,188
  • 7
  • 37
  • 61
  • Your code doesn't work for me. But it works when I replace `requestAnimationFrame(()=>this.animate());` by this: `requestAnimationFrame(()=>{ this.animate(); });` – 8Observer8 May 09 '17 at 11:24
  • @8Observer8 It's almost same as my code, my code works! I wrote a simple program using my code – Mohammad Kermani May 09 '17 at 11:28
-1

Solution 1: requestAnimationFrame(()=>this.animate());

Solution 2: requestAnimationFrame(() => {this.animate();});

Solution 3: requestAnimationFrame(this.animate.bind(this)); https://codepen.io/8Observer8/pen/oWoXyz

/// <reference path="../node_modules/@types/three/index.d.ts" />

//import * as THREE from "three";
// this line does't work. Error: Cannot find module 'three' from ...

// https://github.com/pinqy520/three-typescript-starter/blob/master/src/index.ts

class Game
{
    private _scene: THREE.Scene;
    //private _canvas: HTMLCanvasElement;
    private _camera: THREE.PerspectiveCamera;
    private _renderer: THREE.WebGLRenderer;
    private _axis: THREE.AxisHelper;
    private _light: THREE.DirectionalLight;
    private _light2: THREE.DirectionalLight;
    private _material: THREE.MeshBasicMaterial;
    private _box: THREE.Mesh;

    public constructor()
    {
        //this._canvas = <HTMLCanvasElement>document.getElementById(canvasElement);
        this._scene = new THREE.Scene(); // create the scene
        // create the camera
        this._camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this._renderer = new THREE.WebGLRenderer();
        this._axis = new THREE.AxisHelper(10); // add axis to the scene
        this._light = new THREE.DirectionalLight(0xffffff, 1.0); // add light1
        this._light2 = new THREE.DirectionalLight(0xffffff, 1.0); // add light2
        this._material = new THREE.MeshBasicMaterial({
            color: 0xaaaaaa,
            wireframe: true
        });
        // create a box and add it to the scene
        this._box = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), this._material);
    }

    public createScene(): void
    {
        // set size
        this._renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(this._renderer.domElement); // add canvas to dom
        this._scene.add(this._axis);
        this._light.position.set(100, 100, 100);
        this._scene.add(this._light);
        this._light2.position.set(-100, 100, -100)
        this._scene.add(this._light2);
        this._scene.add(this._box)
        this._box.position.x = 0.5;
        this._box.rotation.y = 0.5;

        this._camera.position.x = 5;
        this._camera.position.y = 5;
        this._camera.position.z = 5;

        this._camera.lookAt(this._scene.position);
    }

    public animate(): void
    {
        requestAnimationFrame(this.animate.bind(this));
        this._render();
    }

    private _render(): void
    {
        let timer = 0.002 * Date.now();
        this._box.position.y = 0.5 + 0.5 * Math.sin(timer);
        this._box.rotation.x += 0.1;
        this._renderer.render(this._scene, this._camera);
    }
}

window.onload = () =>
{
    let game = new Game();
    game.createScene();
    game.animate();
}
8Observer8
  • 868
  • 10
  • 17