【问题标题】:Threejs - rendering different models and animating out of viewThreejs - 渲染不同的模型和动画
【发布时间】:2021-10-14 05:26:14
【问题描述】:

我有一个threejs项目,我想渲染一个模型并使用鼠标围绕它旋转。

这是一种想法 https://www.leroymerlin.fr/big2/guides-2021/experience-inspiration.html

我有一个可以运行的示例,但是控件是通过单击和拖动来绑定的。

  • 目标是渲染模型
  • 能够单击按钮,使相机旋转并在旧模型消散时渲染新模型(目前有一个下拉切换模型)
  • 将鼠标悬停在模型上时,会呈现一个作为链接的号召性用语/特殊鼠标动画
  • 能够使用鼠标移动(而不是单击拖动)来平移模型。

-- 我先玩这个演示 https://threejs.org/examples/webgl_animation_keyframes.html

我尝试用鼠标添加类似这里的东西

let mouseX = 0, mouseY = 0;

function onDocumentMouseMove( event ) {    
  mouseX = ( event.clientX - windowHalfX );
  mouseY = ( event.clientY - windowHalfY );    
}


function render() {    
  camera.position.x += ( mouseX - camera.position.x ) * 0.05;
  camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
  camera.lookAt( scene.position );
  renderer.render( scene, camera );
}

但它发生故障导致模型快速旋转并放大太多。


这是最新的代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - animation - keyframes</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link type="text/css" rel="stylesheet" href="main.css">
        <style>
            body {
                background-color: #bfe3dd;
                color: #000;
            }

            a {
                color: #2983ff;
            }
        </style>
    </head>

    <body>

        <div id="container"></div>

    
        <div id="info">
    
            <!--
                <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - animation - keyframes<br/>
                Model: <a href="https://www.artstation.com/artwork/1AGwX" target="_blank" rel="noopener">Littlest Tokyo</a> by
                <a href="https://www.artstation.com/glenatron" target="_blank" rel="noopener">Glen Fox</a>, CC Attribution.
            --> 

            <select id="models">
              <option value="models/gltf/LittlestTokyo.glb">LittlestTokyo</option>
              <option value="models/gltf/Flamingo.glb" selected="selected">Flamingo</option>
            </select>
        </div>
    




        <script type="module">

            import * as THREE from '../build/three.module.js';

            //import Stats from './jsm/libs/stats.module.js';

            import { OrbitControls } from './jsm/controls/OrbitControls.js';
            import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js';

            import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
            import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';

            let mixer;

            const clock = new THREE.Clock();
            const container = document.getElementById( 'container' );

            //const stats = new Stats();
            //container.appendChild( stats.dom );

            const renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.outputEncoding = THREE.sRGBEncoding;
            container.appendChild( renderer.domElement );

            const pmremGenerator = new THREE.PMREMGenerator( renderer );

            const scene = new THREE.Scene();
            scene.background = new THREE.Color( 0xbfe3dd );
            scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;

            const camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );
            camera.position.set( 5, 2, 8 );

            const controls = new OrbitControls( camera, renderer.domElement );
            controls.target.set( 0, 0.5, 0 );
            controls.update();
            controls.enablePan = false;
            controls.enableDamping = true;

            const dracoLoader = new DRACOLoader();
            dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' );

            const loader = new GLTFLoader();
            loader.setDRACOLoader( dracoLoader );
            

            loadModel('models/gltf/Flamingo.glb')


            function loadModel(path){

                loader.load(path, function ( gltf ) {
                     //remove model

                     // remove last model
                     // if(model) model.parent.remove(model)
                     scene.clear();

                    //add model
                    add(gltf)
                }, undefined, function ( e ) {
                    console.error(e);
                });

            }


            window.onresize = function () {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            };


            function add(gltf){
                let model = gltf.scene;
                model.position.set( 1, 1, 0 );
                model.scale.set( 0.01, 0.01, 0.01 );
                scene.add( model );

                mixer = new THREE.AnimationMixer( model );
                mixer.clipAction( gltf.animations[ 0 ] ).play();

                animate();
            }



            function load(path) {
               console.log("loading", path)

               loadModel(path)
            }


            document.getElementById('models').addEventListener('change', function() {
              console.log('You selected: ', this.value);

                console.log("model", window.model)

                load(this.value)
            });


            function animate() {

                requestAnimationFrame( animate );

                const delta = clock.getDelta();

                mixer.update( delta );

                controls.update();

                //stats.update();

                renderer.render( scene, camera );

            }


        </script>

    </body>

</html>

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    当您执行camera.position.x += mouseX - camera.position.x 时,您正在使用 x 位置来设置自身。这些自我引用的价值观会给你不稳定的行为。尝试更简单的方法:

    camera.position.x = mouseX * 0.05;
    

    或者,如果您想要一个流畅的动画,您可以在 2 个值之间进行线性插值:

    let mouseXTarget = 0, mouseX = 0;
    
    function onDocumentMouseMove( event ) {    
      mouseXTarget = ( event.clientX - windowHalfX ) * 0.05;
    }
    
    
    function render() {
      // mouseX will smoothly try to reach its target
      mouseX = THREE.MathUtils.lerp(mouseX, mouseXTarget, 0.1);
      camera.position.x += mouseX;
      camera.lookAt( scene.position );
    }
    
    

    【讨论】:

      猜你喜欢
      • 2019-05-31
      • 2019-07-02
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 2013-07-06
      • 1970-01-01
      • 2016-12-24
      • 2022-01-03
      相关资源
      最近更新 更多