繁体   English   中英

如何单击并滑入三个js多维数据集?

[英]How to click and slide into three js cube?

我有这段代码,效果很好,我想添加一种情况,当我单击红色多维数据集时,所有页面“跳转”都靠近多维数据集。 (也许是相机?)。 我没有任何想法,希望您能帮助我。

通常,我想学习如何在三个js中单击一个对象,然后移至页面中的第二个对象。

这是我的代码:

<html>
<head>
    <script src="js/three.js"></script>
</head>

<body>
    <script>
        var renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(document.body.clientWidth, document.body.clientHeight);
        document.body.appendChild(renderer.domElement);
        renderer.setClearColorHex(0xEEEEEE, 1.0);
        renderer.clear();
        renderer.shadowCameraFov = 50;
        renderer.shadowMapWidth = 1024;;
        renderer.shadowMapHeight = 1024;


        var fov = 45; // camera field-of-view in degrees
        var width = renderer.domElement.width;
        var height = renderer.domElement.height;
        var aspect = width / height; // view aspect ratio
        var near = 1; // near clip plane
        var far = 10000; // far clip plane
        var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
        camera.position.z = -400;
        camera.position.x = 200;
        camera.position.y = 350;
        var scene = new THREE.Scene();
        var cube = new THREE.Mesh(
          new THREE.CubeGeometry(50, 50, 50),
          new THREE.MeshLambertMaterial({ color: 0xff0000 })
        );
        scene.add(cube);
        cube.castShadow = true;
        cube.receiveShadow = true;

        var plane = new THREE.Mesh(
          new THREE.PlaneGeometry(400, 200, 10, 10),
          new THREE.MeshLambertMaterial({ color: 0xffffff }));
        plane.rotation.x = -Math.PI / 2;
        plane.position.y = -25.1;
        plane.receiveShadow = true;
        scene.add(plane);

        var light = new THREE.SpotLight();
        light.castShadow = true;
        light.position.set(170, 330, -160);
        scene.add(light);
        var litCube = new THREE.Mesh(
          new THREE.CubeGeometry(50, 50, 50),
          new THREE.MeshLambertMaterial({ color: 0xffffff }));
        litCube.position.y = 50;
        litCube.castShadow = true;
        scene.add(litCube);

        renderer.shadowMapEnabled = true;


        renderer.render(scene, camera);
        var paused = false;
        var last = new Date().getTime();
        var down = false;
        var sx = 0, sy = 0;
        window.onmousedown = function (ev) {
            down = true; sx = ev.clientX; sy = ev.clientY;
        };
        window.onmouseup = function () { down = false; };
        window.onmousemove = function (ev) {
            if (down) {
                var dx = ev.clientX - sx;
                var dy = ev.clientY - sy;
                camera.position.x += dx;
                camera.position.y += dy;
                sx += dx;
                sy += dy;
            }
        }
        function animate(t) {
            if (!paused) {
                last = t;
                litCube.position.y = 60 - Math.sin(t / 900) * 25;
                litCube.position.x = Math.cos(t / 600) * 85;
                litCube.position.z = Math.sin(t / 600) * 85;
                litCube.rotation.x = t / 500;
                litCube.rotation.y = t / 800;
                renderer.clear();
                camera.lookAt(scene.position);
                renderer.render(scene, camera);
            }
            window.requestAnimationFrame(animate, renderer.domElement);
        };
        animate(new Date().getTime());
        onmessage = function (ev) {
            paused = (ev.data == 'pause');
        };
    </script>
</body>

</html>

等待您的重播,谢谢:)

您需要实现不同且分开的部分来执行此操作:

  • 可以使用Raycaster来选择对象,您可以在SO上以及在three.js示例中找到很多示例,例如示例
  • 可以使用多种方法来定向摄影机(请参阅camera.lookAt(target.position))和缩放,但是您可能希望使用一种Control来简化摄影机的放置过程,例如其中一种 例如, TrackballControls似乎合适。

  • 正如您的标题所说的“滑动”,最后一点是“相机跳跃”的完成方式。 如果要平滑缩放,则需要一种缓动功能。 看一下Tween.js

文森特写了一个很好的答案。 我只想添加一个示例以帮助理解。

杰斯菲德尔

 <script>
        var container, stats;
        var camera, scene, projector, raycaster, renderer, selected;
        var target, zoom=false;

        var mouse = new THREE.Vector2(), INTERSECTED;
        var radius = 100, theta = 0;

        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );

            scene = new THREE.Scene();

            var light = new THREE.DirectionalLight( 0xffffff, 2 );
            light.position.set( 1, 1, 1 ).normalize();
            scene.add( light );

            var light = new THREE.DirectionalLight( 0xffffff );
            light.position.set( -1, -1, -1 ).normalize();
            scene.add( light );

            var geometry = new THREE.CubeGeometry( 20, 20, 20 );
            var cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F3B557' } ) );
            cube.rotation = new THREE.Euler(0,Math.PI/4,0);
            cube.position = new THREE.Vector3(-20,0,0);
            scene.add(cube);

            cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F05B47' } ) );
            cube.rotation = new THREE.Euler(0,Math.PI/4,0);
            cube.position = new THREE.Vector3(20,0,0);
            scene.add(cube);


            projector = new THREE.Projector();
            raycaster = new THREE.Raycaster();

            renderer = new THREE.WebGLRenderer();
            renderer.setClearColor( 0xf0f0f0 );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.sortObjects = false;
            container.appendChild(renderer.domElement);

            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            window.addEventListener( 'resize', onWindowResize, false );
            renderer.domElement.addEventListener( 'mousedown', onCanvasMouseDown, false);
        }

        function animate() {

            requestAnimationFrame( animate );
            render();

        }

        function render() {
            // set lookAt position according to target position
            if(target){
                camera.lookAt( target.position );
            }else{
                camera.lookAt(new THREE.Vector3(0,0,0));
            }

            //zoom in and out
            if(zoom && camera.fov>10){
                camera.fov-=1;
                camera.updateProjectionMatrix();
            }else if(!zoom && camera.fov<70){
                camera.fov+=1;
                camera.updateProjectionMatrix();
            }


            camera.position = new THREE.Vector3(0,100,100);


            // find intersections
            var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
            projector.unprojectVector( vector, camera );
            raycaster.set( camera.position, vector.sub( camera.position ).normalize() );

            var intersects = raycaster.intersectObjects( scene.children );
            if ( intersects.length > 0 ) {
                if ( INTERSECTED != intersects[ 0 ].object ) {
                    if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );

                    INTERSECTED = intersects[ 0 ].object;
                    INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
                    INTERSECTED.material.emissive.setHex( 0xff0000 );
                }
            } else {
                if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
                INTERSECTED = null;
            }
            renderer.render( scene, camera );

        }

        function onWindowResize() {

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

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

        }

        function onDocumentMouseMove( event ) {

            event.preventDefault();

            mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

        }

        //detect selected cube
        function onCanvasMouseDown( event ){
            if(INTERSECTED){
                target = INTERSECTED;
                zoom = true;
            }else{
                zoom = false;
            }
        }

    </script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM