代码之家  ›  专栏  ›  技术社区  ›  Hide

three.js动态更改对象距离

  •  0
  • Hide  · 技术社区  · 6 年前

    它的概念是有许多文本的宇宙。

    如果我点击文本,不管它的距离,对象必须移动到固定的位置(或相机的前面)

    [索引.html]

    <html>
    <head>
      <script
      src="https://code.jquery.com/jquery-3.3.1.min.js"
      integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
      crossorigin="anonymous"></script>
      <script src="https://gitcdn.xyz/repo/thesmart/jquery-scrollspy/0.1.3/scrollspy.js"></script>
      <script src="./src/WOW.js"></script>
      <script src="./src/three.js"></script>
      <script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/ColladaLoader.js"></script>
      <script src="https://unpkg.com/three.texttexture"></script>
      <script src="https://unpkg.com/three.textsprite"></script>
      <script src="./src/DeviceOrientationControls.js"></script>
      <script src="./src/hammer.js"></script>
      <script src="./src/Detector.js"></script>
      <script src="./src/perlin.js"></script>
      <link rel="stylesheet" type="text/css" href="style.css">
      <link rel="stylesheet" href="animate.css">
      <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
      <meta charset="UTF-8">
    </head>
    <body>
      <header>
        <div class="header-left">
          <a href="#loading-screen" onclick="topFunction()">MAIN</a>
        </div>
        <div class="header-right">
          <a href="#">MISSION</a>
          <a href="#section1">PRODUCT</a>
          <a href="#">CULTURE</a>
          <a href="#">STORY</a>
        </div>
      </header>
      <main>
        <!-- Universe -->
        <section id="universe" class="wow" data-wow-duration="0.5s"></section>
        <!-- Main -->
        <section class="main" id="main">
        </section>
        <script src="./src/src.js"></script>
      </main>
    </body>
    </html>
    

    [src.js]公司

    // VARIABLES
    let clock, camera, scene, renderer, mixer;
    const sleep = ms => new Promise(res => setTimeout(res, ms));
    
    var myElement = document.getElementById("threejs");
    const mouse = new THREE.Vector2();
    const clicked = new THREE.Vector2();
    const target = new THREE.Vector2();
    const windowHalf = new THREE.Vector2( window.innerWidth / 2, window.innerHeight / 2 );
    const moveState = {forward: 0, back: 0};
    var isMobile = false;
    var textCount = 500;
    var firstTime = true;
    var fontFamily = '"Courier New", Courier, monospace';
    var lock = true;
    var group = new THREE.Group();
    
    const scrollPosition = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
    
    checkMobile()
    
    // WOW.js
    var wow = new WOW();
    wow.init();
    
    init();
    
    async function init() {
      if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
    
      scene = new THREE.Scene();
    
      // CAMERA
      camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2100 );
      camera.position.x = 0;
      camera.position.y = 0;
      camera.position.z = 1200;
      camera.lookAt(scene.position);
    
      clock = new THREE.Clock();
    
      // HELPER
      const gridHelper = new THREE.PolarGridHelper( 8, 16 );
      scene.add( gridHelper );
    
      // LIGHT
      const ambientLight = new THREE.AmbientLight( 0xffffff, 0.2 );
      scene.add( ambientLight );
    
      const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
      directionalLight.position.set( 1, 1, - 1 );
      scene.add( directionalLight );
    
      // CONTROLS
      if(isMobile) { // 모바일이면 
        var controls = new THREE.DeviceOrientationControls(camera);
        console.log('isMobile true');
      } else {
        console.log('isMobile false');
      }
      // SATISFY THE DESIRES OF LOVE
      let sprite = new THREE.TextSprite({
        textSize: 5,
        redrawInterval: 250,
        texture: {
          text: 'MAIN TEST',
          fontFamily: fontFamily,
        },
        material: {
          color: 'white',
        },
      });
      sprite.position.x = 0;
      sprite.position.y = 0;
      sprite.position.z = 10;
      scene.add(sprite);
    
      // ADD MESH
      var size = ( isMobile ? 2 : 2 );
      var starsLights = new THREE.Group();
    
      var starGeometry = new THREE.SphereGeometry(0.3, 16, 16);
      var emptyGeometry = new THREE.Geometry();
    
      for ( let i = 0; i < textCount; i ++ ) {
        var lod = new THREE.LOD();
    
        // Text
        let sprite = new THREE.TextSprite({
          textSize: size,
          redrawInterval: 250,
          texture: {
            text: 'For Test',
            fontFamily: fontFamily,
          },
          material: {
            color: 'white',
            transparent: true,
          },
        });
    
        // Star
        var starMaterial = new THREE.MeshBasicMaterial({color: 0xffffff, transparent: true});
        var star = new THREE.Mesh(starGeometry, starMaterial);
    
        // Dummy
        var dummy = new THREE.Mesh(emptyGeometry, new THREE.MeshBasicMaterial());
    
        // Add
        lod.addLevel(sprite, 1);
        lod.addLevel(star, 100, 240);
        lod.addLevel(dummy, 200, 300);
    
        lod.position.x = (Math.random() * 180-100);
        lod.position.y = Math.random() * 180-100;
        lod.position.z = Math.random() * 1000-40;
    
        group.add(lod);
      }
      scene.add(group);
    
      // Renderer
      renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
      renderer.setPixelRatio( window.devicePixelRatio );
      renderer.setSize( window.innerWidth, window.innerHeight );
      document.getElementById("universe").appendChild(renderer.domElement);
    
      // Event handler
      window.addEventListener('load', refreshCheck, false);
      window.addEventListener('resize', onWindowResize, false); 
      document.addEventListener('mousemove', onMouseMove, false);
      document.addEventListener('mousewheel', onMouseWheel, false); 
      document.addEventListener('contextmenu', onContextMenu, false); 
      document.addEventListener('mouseup', onMouseClick, false); 
    
    
      function animate() {
        target.x = ( 1 - mouse.x ) * 0.002;
        target.y = ( 1 - mouse.y ) * 0.002;
        camera.rotation.x += 0.05 * ( target.y - camera.rotation.x );
        camera.rotation.y += 0.05 * ( target.x - camera.rotation.y );
    
        if(isMobile) {
          controls.update();
        }
        // Object change related to distance
        group.children.forEach(function(child) {
          child.update(camera);
        })
        // Render
        requestAnimationFrame( animate );
        render(scene, camera);
      }
    
      animate();
    }
    
    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize( window.innerWidth, window.innerHeight );
    }
    
    function onMouseWheel(event) {
      event.preventDefault();
      camera.position.z -= event.deltaY * 0.2;
    }
    
    function render() {
      const delta = clock.getDelta();
      if ( mixer !== undefined ) mixer.update( delta );
      renderer.render( scene, camera );
    }
    
    function onTransitionEnd( event ) {
      console.log("Loading Complete");
      event.target.remove();
    }
    
    // Exist functions
    function checkMobile() {
      var UserAgent = navigator.userAgent;
    
      if (UserAgent.match(/iPhone|iPod|Android|Windows CE|BlackBerry|Symbian|Windows Phone|webOS|Opera Mini|Opera Mobi|POLARIS|IEMobile|lgtelecom|nokia|SonyEricsson/i) != null || UserAgent.match(/LG|SAMSUNG|Samsung/) != null) {
          isMobile = true;
      } else {
          isMobile = false;
      }
    }
    
    var raycaster = new THREE.Raycaster();
    var mouseVector = new THREE.Vector3();
    
    function getIntersects( x, y ) {
        x = ( x / window.innerWidth ) * 2 - 1;
        y = - ( y / window.innerHeight ) * 2 + 1;
        mouseVector.set( x, y, 0.5 );
        raycaster.setFromCamera( mouseVector, camera );
        return raycaster.intersectObject( group, true );
    }
    
    var selectedObject = null;
    var intersects;
    
    function onMouseMove(event) {
      event.preventDefault();
      mouse.x = ( (event.clientX/2) - (windowHalf.x/2) );
      mouse.y = ( (event.clientY/2) - (windowHalf.y/2) );
      clicked.x = ( event.clientX / window.innerWidth ) * 2 - 1;
      clicked.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    
      // Select object
      if ( selectedObject ) {
          selectedObject.material.color.set( '#ffffff' );
          selectedObject = null;
      }
      intersects = getIntersects( event.layerX, event.layerY );
    
      if ( intersects.length > 0 ) {
        var res = intersects.filter( function ( res ) {
            return res && res.object;
        } )[ 0 ];
        if ( res && res.object ) {
          selectedObject = res.object;
          selectedObject.material.color.set( '#f00' );
        }
      }
    }
    
    function onMouseClick() {
      if(intersects[0]) {
        console.log(intersects[0].point);
        intersects[0].object.position.z += intersects[0].distance-70;
        intersects[0].object.position.x = 0;
        intersects[0].object.position.y = 0;
      }
    }
    
    function onResize(event) {
      const width = window.innerWidth;
      const height = window.innerHeight;
    
      windowHalf.set( width / 2, height / 2 );
    
      camera.aspect = width / height;
      camera.updateProjectionMatrix();
      renderer.setSize( width, height );
    }
    
    function onContextMenu(event) { // Mouse right click
      event.preventDefault();
    }
    
    function refreshCheck() {
      if(window.performance) {
        if(performance.navigation.type === 1) {
          setTimeout(() => {
            document.body.scrollTop = 0; // Other Browser
            document.documentElement.scrollTop = 0; // IE
          }, 0);
        }
      }
    }
    

    onMouseWheel() 函数,检测当前光标指向对象与否。

    var intersects .

    同时添加 onMouseClick() . 在这个函数中,我这样改变物体的位置。

      if(intersects[0]) {
        console.log(intersects[0].point);
        intersects[0].object.position.z += intersects[0].distance-70;
        intersects[0].object.position.x = 0;
        intersects[0].object.position.y = 0;
      }
    

    因此,如果单击对象,对象的x,y,z坐标将更改为,0,0,距离-70。

    请参阅此网站 https://50-jahre-hitparade.ch/

    我的目标是让它像上面的网站。

    enter image description here (像这样)

    有什么解决办法吗?

    谢谢。

    (可能我必须更新到animate()?)

    资料来源: https://github.com/teamhide/raycast

    启动: https://teamhide.github.io/raycast/

    1 回复  |  直到 6 年前
        1
  •  0
  •   HariV    6 年前

    而不是

    if(intersects[0]) {
        intersects[0].point.z = 100;
        intersects[0].point.x = 100;
        intersects[0].point.y = 100;
    }
    

    intersects[0].object.position 这样地,

    if(intersects[0]) {
        intersects[0].object.position.z = 100;
        intersects[0].object.position.x = 100;
        intersects[0].object.position.y = 100;
    }