Search code examples
javascriptanimationthree.jsgltf

Three.js basics – Can't find variable – GLTFLoader animation


I’ve got very basic knowledge of JS. Following three.js docs Loading 3D models I have succesfully rendered 3D object and centered it:

const loader = new GLTFLoader();

loader.load( 'Duck.gltf', function ( duck ) {
    
    const model = duck.scene
    const box = new THREE.Box3().setFromObject( model );
    const center = new THREE.Vector3();
    box.getCenter( center );
    model.position.sub( center ); // center the model
    scene.add( model );

}, undefined, function ( error ) {

    console.error( error );

} );

I would like to animate it now, begining with simple rotation:

/**
 * Animate
 */

const clock = new THREE.Clock()

const tick = () =>
{

    const elapsedTime = clock.getElapsedTime()

    // Update objects
    model.rotation.y = .5 * elapsedTime

    // Update Orbital Controls
    // controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

But the problem is console returns:

ReferenceError: Can't find variable: model

Solution

  • You have declared model variable inside the functional scope, try to declare it outside

    const loader = new GLTFLoader();
    let model, box, center;
    
    loader.load( 'Duck.gltf', function ( duck ) {
        
        model = duck.scene
        box = new THREE.Box3().setFromObject( model );
        center = new THREE.Vector3();
        box.getCenter( center );
        model.position.sub( center ); // center the model
        scene.add( model );
    
    }, undefined, function ( error ) {
        console.error( error );
    } );
    

    Hopefully, this will work!

    Edited

    as @prisoner849 suggested in the comments

    const clock = new THREE.Clock()
    const tick = () =>
    {
        const elapsedTime = clock.getElapsedTime()
        // Update objects
        if (model) {
           model.rotation.y = .5 * elapsedTime
        }
        // Update Orbital Controls
        // controls.update()
        // Render
        renderer.render(scene, camera)
        // Call tick again on the next frame
        window.requestAnimationFrame(tick)
    }
    
    tick()