使用three.js移动对象

时间:2018-09-20 15:34:53

标签: three.js

我对这Three.js非常陌生。我想创建两个多维数据集。我对其动画最不感兴趣。因此,我希望多维数据集1可以在没有任何键盘输入的情况下移向多维数据集2。我还提供图片以供更好地理解。

预先感谢

enter image description here

2 个答案:

答案 0 :(得分:0)

您可以通过几种不同的方式来做到这一点。

假设轴和两个立方体的起始位置也将更容易回答这个问题。

让我们说cube1的位置是:

  • x:0
  • y:0
  • z:0

Cube2的位置是:

  • x:10
  • y:20
  • z:0

在渲染循环中,沿y轴移动cube1,直到其与cube2(20)相同的值,然后沿x轴移动cube1,直到其达到cube2 x的位置。因此,多维数据集1将位于多维数据集2的顶部。您需要使用代码来移动cube1,但是仅在满足某些条件时运行。

例如,仅在cube1.position.y小于或等于cube2.position.y时才能在y轴上移动

可以通过更改增量值来提高或降低运动速度。因此,y轴上的更新可能如下所示:

cube1.position.y += 0.1;

这种方法可能更难管理,因为您将需要不断检查多维数据集1相对于多维数据集2的位置,并且由于多维数据集需要沿两个方向移动,因此从长远来看可能会变得混乱。

您可以在循环概念中查看此更新的示例-https://jsfiddle.net/f2Lommf5/

我希望使用一个动画库,例如Tween.js或Greensock,我认为它们更适合。您可以指定要沿其移动的轴,开始和结束位置,动画持续时间和缓动。 y轴上的动画完成后,您可以在x轴上开始动画。

一些有用的链接:

答案 1 :(得分:0)

要设置动画对象,请使用THREE.Tween

创建2个多维数据集:

var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);

var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);

创建一个Tween,它将旋转多维数据集并连续重新启动:

tweenStart = { value: 0 };
  var finish = { value: Math.PI/2 };

  cubeTween = new TWEEN.Tween(tweenStart);
  cubeTween.to(finish, 3000)

  cubeTween.onUpdate(function() {
      cube1.position.set(0.0, 0.0, 0.0);
      cube1.rotation.y = tweenStart.value;
      cube1.translateZ( 2.0 );
  });

  cubeTween.onComplete( function() {
      tweenStart.value = 0;
      requestAnimationFrame(function() {
          cubeTween.start();
      });
  });
  cubeTween.start();

(function onLoad() {
  var container, loader, camera, scene, renderer, controls, cube1, cube2, cubeTween, tweenStart;
  
  init();
  animate();
  animateCube();

  function init() {
    container = document.getElementById('container');
    
    renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    container.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
    camera.position.set(0, 6, 0);
    camera.lookAt( 0, 0, 0 );

    loader = new THREE.TextureLoader();
    loader.setCrossOrigin("");

    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xffffff);
    scene.add(camera);
    window.onresize = resize;
    
    var ambientLight = new THREE.AmbientLight(0x404040);
    scene.add(ambientLight);

    var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
    directionalLight.position.set(1,2,1.5);
    scene.add( directionalLight );

    controls = new THREE.OrbitControls(camera);
    
    addGridHelper();
    createModel();
  }

  function createModel() {

    var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
    var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
    cube1 = new THREE.Mesh(geometry1, material1);
    cube1.position.set(0.0, 0.0, 2.0);

    var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
    var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
    cube2 = new THREE.Mesh(geometry2, material2);
    cube2.position.set(2.0, 0.0, 0.0);

    scene.add(cube1);
    scene.add(cube2);

    
    tweenStart = { value: 0 };
    var finish = { value: Math.PI/2 };

    cubeTween = new TWEEN.Tween(tweenStart);
    cubeTween.to(finish, 3000)
    
    cubeTween.onUpdate(function() {
        cube1.position.set(0.0, 0.0, 0.0);
        cube1.rotation.y = tweenStart.value;
        cube1.translateZ( 2.0 );
    });
    
    cubeTween.onComplete( function() {
        tweenStart.value = 0;
        requestAnimationFrame(function() {
            cubeTween.start();
        });
    });
    cubeTween.start();
  }

  function addGridHelper() {
    var helper = new THREE.GridHelper(100, 100);
    helper.material.opacity = 0.25;
    helper.material.transparent = true;
    scene.add(helper);

    var axis = new THREE.AxesHelper(1000);
    scene.add(axis);
  }

  function resize() {
    
    var aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
  }

  function animate() {
    requestAnimationFrame(animate);
    TWEEN.update();
    render();
  }

  function render() {
    renderer.render(scene, camera);
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>
<div id="container"></div>


或者,您可以通过在animate函数中更改多维数据集的position属性来稍微更改多维数据集的位置:

function animate() {
      requestAnimationFrame(animate);

      if ( cube1.position.z > 0.0 ) {
          cube1.position.set(0.0, 0.0, cube1.position.z-0.01);
      } else if ( cube1.position.x < 2.0 ) {
          cube1.position.set(cube1.position.x+0.01, 0.0, 0.0);
      } else { 
        cube1.position.set(0.0, 0.0, 2.0); 
      }
      render();
  }   

(function onLoad() {
  var container, loader, camera, scene, renderer, controls, cube1, cube2, cubeTween, tweenStart;
  
  init();
  animate();
  animateCube();

  function init() {
    container = document.getElementById('container');
    
    renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMap.enabled = true;
    container.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
    camera.position.set(0, 6, 0);
    camera.lookAt( 0, 0, 0 );

    loader = new THREE.TextureLoader();
    loader.setCrossOrigin("");

    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xffffff);
    scene.add(camera);
    window.onresize = resize;
    
    var ambientLight = new THREE.AmbientLight(0x404040);
    scene.add(ambientLight);

    var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
    directionalLight.position.set(1,2,1.5);
    scene.add( directionalLight );

    controls = new THREE.OrbitControls(camera);
    
    addGridHelper();
    createModel();
  }

  function createModel() {

    var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
    var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
    cube1 = new THREE.Mesh(geometry1, material1);
    cube1.position.set(0.0, 0.0, 2.0);

    var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
    var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
    cube2 = new THREE.Mesh(geometry2, material2);
    cube2.position.set(2.0, 0.0, 0.0);

    scene.add(cube1);
    scene.add(cube2);
  }

  function addGridHelper() {
    var helper = new THREE.GridHelper(100, 100);
    helper.material.opacity = 0.25;
    helper.material.transparent = true;
    scene.add(helper);

    var axis = new THREE.AxesHelper(1000);
    scene.add(axis);
  }

  function resize() {
    
    var aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = aspect;
    camera.updateProjectionMatrix();
  }

  function animate() {
      requestAnimationFrame(animate);
      
      if ( cube1.position.z > 0.0 ) {
          cube1.position.set(0.0, 0.0, cube1.position.z-0.01);
      } else if ( cube1.position.x < 2.0 ) {
          cube1.position.set(cube1.position.x+0.01, 0.0, 0.0);
      } else { 
        cube1.position.set(0.0, 0.0, 2.0); 
      }
      render();
  }

  function render() {
    renderer.render(scene, camera);
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="container"></div>