【问题标题】:How to animate camera.lookAt using gsap?如何使用 gsap 为 camera.lookAt 设置动画?
【发布时间】:2021-03-08 19:08:24
【问题描述】:

camera.lookAt(myObject) 将立即将 three.js 相机旋转到给定对象。

我想使用 gsap 为这个旋转设置动画。我可以使用 gsap 为相机位置的变化设置动画,但是下面的相机旋转代码什么也不做。

const targetOrientation = myObject.quaternion.normalize();
gsap.to({}, {
    duration: 2,
    onUpdate: function() {
        controls.update();
        camera.quaternion.slerp(targetOrientation, this.progress());
    }
});

如何以这种方式为相机旋转设置动画?

好的,现在已修复。主要问题是我的 render() 函数中有一个 controls.update() 行。轨道控件不适用于相机旋转,因此您需要确保它们在动画期间完全禁用。

我修改后的代码,包括旋转和位置动画:

const camrot = {'x':camera.rotation.x,'y':camera.rotation.y,'z':camera.rotation.z}
camera.lookAt(mesh.position);
const targetOrientation = camera.quaternion.clone().normalize();

camera.rotation.x = camrot.x;
camera.rotation.y = camrot.y;
camera.rotation.z = camrot.z;

const aabb = new THREE.Box3().setFromObject( mesh );
const center = aabb.getCenter( new THREE.Vector3() );
const size = aabb.getSize( new THREE.Vector3() );

controls.enabled = false;   

const startOrientation = camera.quaternion.clone();

gsap.to({}, {
    duration: 2,
    onUpdate: function() {
        camera.quaternion.copy(startOrientation).slerp(targetOrientation, this.progress());
    },
    onComplete: function() {
        gsap.to( camera.position, {
            duration: 8,
            x: center.x,
            y: center.y,
            z: center.z+4*size.z,
            onUpdate: function() {
                camera.lookAt( center );
            },
            onComplete: function() {
                controls.enabled = true;
                controls.target.set( center.x,  center.y, center.z);
            }
        } );
    }
});

【问题讨论】:

    标签: three.js gsap


    【解决方案1】:

    像这样尝试:

    let mesh, renderer, scene, camera, controls;
    
    init();
    animate();
    
    function init() {
    
        // renderer
        renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        renderer.setPixelRatio( window.devicePixelRatio );
        document.body.appendChild( renderer.domElement );
    
        // scene
        scene = new THREE.Scene();
        
        // camera
        camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
        camera.position.set( 20, 10, 20 );
        camera.lookAt( 0, 0, 0 );
    
        // ambient
        scene.add( new THREE.AmbientLight( 0x222222 ) );
        
        // light
        const light = new THREE.DirectionalLight( 0xffffff, 1 );
        light.position.set( 20,20, 0 );
        scene.add( light );
        
        // axes
        scene.add( new THREE.AxesHelper( 20 ) );
    
        // geometry
        const geometry = new THREE.SphereBufferGeometry( 5, 12, 8 );
        
        // material
        const material = new THREE.MeshPhongMaterial( {
            color: 0x00ffff, 
            flatShading: true,
            transparent: true,
            opacity: 0.7,
        } );
        
        // mesh
        mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );
            
        const startOrientation = camera.quaternion.clone();
        const targetOrientation = mesh.quaternion.clone().normalize();
            
        gsap.to( {}, {
            duration: 2,
            onUpdate: function() {
                camera.quaternion.copy(startOrientation).slerp(targetOrientation, this.progress());
            }
        } );
        
    }
    
    function animate() {
    
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
    
    }
    body {
      margin: 0;
    }
    <script src="https://cdn.jsdelivr.net/npm/three@0.123/build/three.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.0/gsap.min.js"></script>

    您必须确保始终以开始方向而不是camera.quaternion 调用Quaternion.slerp()。否则插值将不正确。

    【讨论】:

    • 感谢您提供这个有用的示例。不幸的是,当我在我的应用程序中使用您的代码时,尝试动画相机旋转时仍然没有响应(相机位置动画很好)。有趣的是,相同的代码在这里工作。我正在使用轨道控制。我确实尝试了 controls.enabled = false;但它没有任何区别。
    • 我将尝试删除我的其他代码的一部分,看看我是否可以让它工作。
    • 即使移除轨道控制也没有区别。将尝试在我的服务器上运行您的确切代码。
    • 好的,现在我看到了我认为的问题。当我在我的代码中记录结果时,targetOrientation == sourceOrientation。所以相机不会旋转。我认为问题在于 targetOrientation 需要是相机当前正在查看的位置与它正在查看网格时它将查看的位置之间的角度。这有意义吗?
    • 好的,已修复。我的代码现在太大了,无法提供完整的实时示例,但我会在一两周内将它放在 GitHub 上。目前,问题出在我的 render() 函数中的 controls.update() 行。摄像机旋转不适用于 Orbit 控件,因此您需要确保在动画进行期间的整个渲染过程中没有使用它们。将更新 OP 帖子。
    猜你喜欢
    • 2013-01-12
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多