ThreeJS hace clic en el objeto y sigue dinámicamente la etiqueta div

1 Resolver la relación de inclusión de puntos de etiqueta

    

 <div id="WebGLwxp" align="center">
        <div id="notice"></div>
    </div>

  Notice es el div usado para mostrar información dinámica, WebGLwxp es el div usado para renderizar la escena

2 Primero resuelva el problema del clic del mouse

      Consulte la solución de clic del mouse

3 Luego resuelva el problema de convertir puntos de coordenadas tridimensionales en puntos de coordenadas bidimensionales.

 //三维坐标转屏幕坐标
        function transPosition(position) {
            var world_vector = new THREE.Vector3(position.x, position.y, position.z);
            var vector = world_vector.project(camera);
            var halfWidth = window.innerWidth / 2;
            var halfHeight = window.innerHeight / 2;
            return {
                x: Math.round(vector.x * halfWidth + halfWidth),
                y: Math.round(-vector.y * halfHeight + halfHeight)
            };
        }

Haga clic en diferentes objetos para mostrar sus nombres y coordenadas correspondientes. Por supuesto, puede agregar más funciones según sus necesidades

Código completo

<!DOCTYPE html>
<html>
<head>
    <title>Threejs三维场景基本模块</title>
    <style type="text/css">
        body
        {
            margin: 0;
            overflow: hidden; /* 隐藏body窗口区域滚动条 */
        }
    </style>
    <!--引入three.js三维引擎-->

    <script type="text/javascript" src="threejsmaster/build/three.js"></script>
    <script type="text/javascript" src="threejsmaster/build/js/libs/dat.gui.min.js"></script>
    <script type="text/javascript" src="threejsmaster/build/js/loaders/STLLoader.js"></script>

</head>
<body>
    <!-- 作为Three.js渲染器输出元素 -->
    <div id="WebGLwxp" align="center">
        <div id="notice"></div>
    </div>

    <script type="text/javascript">

        //全局变量---------------------------------

        //仿真场景必备变量
        var scene, camera, renderer;

        //界面变量
        var GuiControls;

        //物体变量
        var cube;

        //相机视角
        var fov = 45;
        var mouseDownX = 0;
        var mouseMoveX = 0;

        //鼠标点选变量 
        var objects = [];    //可以点选的物体容器
        var mouseXY;           //鼠标平面坐标
        var raycaster;         //射线对象
        var boundingBox;       //包围盒
        var selectedObject;    //被选中的物体

        var WxpTexture;        //纹理对象     

        //-----------------------------------------      
        //键盘函数    
        function WxpKeyPressed(e) {
            var key = event.keyCode;
            if (!boundingBox)
                document.getElementById("notice").innerHTML = "请先选中物体" + key.toString();
            switch (key) {

                case 37: /*左方向键*/
                    GuiControls.camerPositionX += 0.1;
                    break;

                case 39: /*右方向键*/
                    GuiControls.camerPositionX -= 0.1;
                    break;

                case 38: /*向上键*/
                    GuiControls.camerPositionY -= 0.1;
                    break;

                case 40: /*向下键*/
                    GuiControls.camerPositionY += 0.1;
                    break;

                case 87: /*w*/
                    selectedObject.position.y += 0.5;
                    selectedObject.rotation.x -= Math.PI / 4.0;
                    break;

                case 65: /*a*/
                    selectedObject.position.x -= 0.5;
                    selectedObject.rotation.y -= Math.PI / 4.0;
                    break;

                case 83: /*s*/
                    selectedObject.position.y -= 0.5;
                    selectedObject.rotation.x += Math.PI / 4.0;
                    break;
                case 68: /*d*/
                    selectedObject.position.x += 0.5;
                    selectedObject.rotation.y += Math.PI / 4.0; ;
                    break;
            }
            //
            if (boundingBox)
                scene.remove(boundingBox);

            boundingBox = new THREE.BoxHelper(selectedObject, 0x0000ff);
            scene.add(boundingBox);
        }

        //---------------------------------------------------
        //中键滚动
        function WxpMousewheel(e) {
            e.preventDefault();
            if (e.wheelDelta) {
                if (e.wheelDelta > 0) { //当滑轮向上滚动时
                    fov += 1;
                }

                if (e.wheelDelta < 0) { //当滑轮向下滚动时
                    fov -= 1;
                }

            } else if (e.detail) {  //Firefox滑轮事件
                if (e.detail > 0) { //当滑轮向上滚动时
                    fov -= 1;
                }
                if (e.detail < 0) { //当滑轮向下滚动时
                    fov += 1;
                }
            }
            camera.fov = fov;
            camera.updateProjectionMatrix();
            renderer.render(scene, camera);
        }

        //左键按下--------------------------------
        function WxpMouseDown(event) {//按下鼠标

            event.preventDefault();
            
            //鼠标点选物体
            mouseXY.set((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1);

            raycaster.setFromCamera(mouseXY, camera);
            var intersects = raycaster.intersectObjects(objects);

            if (intersects.length > 0) {

                selectedObject = intersects[0].object;
                var activePoint = intersects[0].point;

                if (boundingBox)
                    scene.remove(boundingBox);

                boundingBox = new THREE.BoxHelper(selectedObject, 0x0000ff);
                scene.add(boundingBox);

                //动态标签
                var str = new String("");
                var div = document.getElementById('notice');
                var left = transPosition(selectedObject.position).x;
                var top = transPosition(selectedObject.position).y - 50;
                div.style.position = 'absolute';
                div.style.color = "blue";
                div.style.display = "";
                div.style.left = left + 'px';
                div.style.top = top + 'px';

                str ="名称:"+selectedObject.name + " 坐标:  x=" + left + "   y=" + top;
                div.innerHTML = str;
            }
            //没有选中物体就移除包围盒
            else {
                if (boundingBox)
                    scene.remove(boundingBox);
                    
                //标签内容置空
                var div = document.getElementById('notice');
                div.innerHTML="";
            }

        }

        //三维坐标转屏幕坐标
        function transPosition(position) {
            var world_vector = new THREE.Vector3(position.x, position.y, position.z);
            var vector = world_vector.project(camera);
            var halfWidth = window.innerWidth / 2;
            var halfHeight = window.innerHeight / 2;
            return {
                x: Math.round(vector.x * halfWidth + halfWidth),
                y: Math.round(-vector.y * halfHeight + halfHeight)
            };
        }
        //按下左键后移动------------------------------
        function WxpMouseMove(event) {//移动鼠标

            mouseMoveX = event.clientX - mouseDownX;
            // mouseX = event.clientX - windowHalfX;

            // targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02;
        }

        //左键释放-------------------------------------
        function WxpMouseUp(event) {//释放鼠标键

            document.removeEventListener('mousemove', WxpMouseMove, false);
            document.removeEventListener('mouseup', WxpMouseUp, false);
        }
        //----------------------------------------- 
        //场景基本配置
        function WxpInitScene() {

            //**********************基本元素**************************************
            var sceneWidth = window.innerWidth;  // window.innerWidth-400;
            var sceneHeight = window.innerHeight; //window.innerHeight-80;

            //创建一个场景
            scene = new THREE.Scene();

            //创建一个摄像机对象
            camera = new THREE.PerspectiveCamera(45, sceneWidth / sceneHeight, 0.1, 200);

            //设置摄像机参数
            camera.position.set(10.0, -20, 13);
            camera.up.set(0, 0, 1);                          //Z轴正向向上
            camera.lookAt(new THREE.Vector3(0, 0, 0));

            //创建一个WebGL渲染器
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setClearColor(new THREE.Color(0x7696f1));
            renderer.setSize(sceneWidth, sceneHeight);
            renderer.setPixelRatio(window.devicePixelRatio); //框锯齿设置

            //系统坐标系绘制-------------------------
            var axesHelper = new THREE.AxesHelper(12);
            scene.add(axesHelper);

            raycaster = new THREE.Raycaster();
            mouseXY = new THREE.Vector2();

            //网格线绘制
            var grid = new THREE.GridHelper(24, 24, 0xFF0000, 0x444444);
            grid.material.opacity = 0.4;
            grid.material.transparent = true;
            grid.rotation.x = Math.PI / 2.0;                  //默认网格线旋转90度
            scene.add(grid);
            //---------------------------------------           
            //***********************************************************************
            //建立环境光线
            var ambient = new THREE.AmbientLight(0x666666);
            scene.add(ambient);

            //平行光(没感觉到作用)
            var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
            scene.add(directionalLight);

            //创建点光源 正上面
            var spotLightTop = new THREE.SpotLight(0xFFFFFF);
            spotLightTop.position.set(0, 0, 50);
            spotLightTop.castShadow = true;
            scene.add(spotLightTop);

            //左前方
            var spotLightFront = new THREE.SpotLight(0xaaaaaa);
            spotLightFront.position.set(-50, 50, 5);
            spotLightFront.castShadow = true;
            scene.add(spotLightFront);

            //右前方
            var spotLightRight = new THREE.SpotLight(0xaaaaaa);
            spotLightRight.position.set(50, 50, 5);
            spotLightRight.castShadow = true;
            scene.add(spotLightRight);

            //左后方
            var spotLightLeft = new THREE.SpotLight(0xaaaaaa);
            spotLightLeft.position.set(-50, -50, 5);
            spotLightLeft.castShadow = true;
            scene.add(spotLightLeft);

            //右后方
            var spotLightRear = new THREE.SpotLight(0xaaaaaa);
            spotLightRear.position.set(50, -50, 5);
            spotLightRear.castShadow = true;
            scene.add(spotLightRear);

            //将渲染的结果输出到指定页面元素中
            document.getElementById("WebGLwxp").appendChild(renderer.domElement);
            window.addEventListener('keydown', WxpKeyPressed, false);
            window.addEventListener('mousedown', WxpMouseDown, false);
            window.addEventListener('mousewheel', WxpMousewheel, false);
        }

        //----------------------------------------- 
        //加载场景物体
        function WxpAddObject() {

            //加载物体
            //创建一个立方体
            var cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
            var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000, opacity: 0.5, transparent: true });
            cube = new THREE.Mesh(cubeGeometry, cubeMaterial);    //物体=几何体+材质
            cube.castShadow = true;
            cube.name = "objtest";

            //设置立方体的位置
            cube.position.set(0, 0, 0.5);
            scene.add(cube);
            objects.push(cube);

            //创建一个立方体
            var cubeGeometry2 = new THREE.CylinderGeometry(0, 1, 1, 20, 20, false);
            // var cubeMaterial2 = new THREE.MeshNormalMaterial({flatShading: true});
            // var cubeMaterial2 = new THREE.MeshPhongMaterial({color: 0x836DED,specular:0x111111,shininess:80});
            WxpTexture = new THREE.ImageUtils.loadTexture("aa.png");
            var cubeMaterial2 = new THREE.MeshBasicMaterial({ map: WxpTexture, transparent: true });
            WxpTexture.wrapS = THREE.RepeatWrapping;
            WxpTexture.wrapT = THREE.RepeatWrapping;
            WxpTexture.repeat.set(2, 2);
            WxpTexture.center.set(0.5, 0.5);

            cube2 = new THREE.Mesh(cubeGeometry2, cubeMaterial2);    //物体=几何体+材质
            //设置立方体的位置
            cube2.position.set(4, 0, 0.5);
            scene.add(cube2);
            objects.push(cube2);
            cube2.name = "obj多对多";


            //创建管道成型的路径(3D样条曲线)
            var path = new THREE.CatmullRomCurve3([
              new THREE.Vector3(-5, 0, 1),
              new THREE.Vector3(0, 5, 1),
              new THREE.Vector3(5, 0, 1),
              new THREE.Vector3(0, 0, 0)]);
            var point = path.getPoints(100);
            var points = new THREE.CatmullRomCurve3(point);
            // path:路径   40:沿着轨迹细分数  2:管道半径   25:管道截面圆细分数
            var geometry3 = new THREE.TubeGeometry(path, 40, 0.2, 25);
            var cube3 = new THREE.Mesh(geometry3, cubeMaterial2);    //物体=几何体+材质
            cube3.name = "objwwww";

            scene.add(cube3);
            objects.push(cube3);


            //地板
            var plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(10, 10),
					                   new THREE.MeshBasicMaterial({ color: 0xdddddd, side: THREE.DoubleSide })
					                   );
            scene.add(plane);
            plane.receiveShadow = true;


            var loader = new THREE.STLLoader();
            var stlFileName = new String("aa.stl");
            loader.load(stlFileName, function(geometry) {
                //创建纹理
                var mat = new THREE.MeshPhongMaterial({ color: 0x836DED, specular: 0x111111, shininess: 100 });
                var mesh = new THREE.Mesh(geometry, mat);
                mesh.scale.set(0.01, 0.01, 0.01);       //缩放
                geometry.center();                      //建立几何中心
                mesh.position.set(0, -2, 0.5);          //位置
                mesh.castShadow = true;
                mesh.receiveShadow = true;

                mesh.name = "test";

                objects.push(mesh);
                scene.add(mesh);
            });
        }

        //----------------------------------------- 
        //界面设置  
        function WxpGuiSetting() {
            //存放所有需要改变的属性的对象
            GuiControls = new function() {
                this.rotationSpeed = 0.01;

                this.camerPositionX = 4.00;
                this.camerPositionY = -8.00;
                this.camerPositionZ = 4.00;
            };

            //创建dat.GUI,传递并设置属性
            var gui = new dat.GUI();
            gui.add(GuiControls, 'rotationSpeed', 0, 0.5);

            gui.add(GuiControls, 'camerPositionX', -40.0, 20.0);
            gui.add(GuiControls, 'camerPositionY', -40.0, 10.0);
            gui.add(GuiControls, 'camerPositionZ', 0.0, 40.0);
        }

        //渲染场景
        function WxpRender() {

            //更新必要的参数
            cube.rotation.z += GuiControls.rotationSpeed;

            camera.position.x = GuiControls.camerPositionX;
            camera.position.y = GuiControls.camerPositionY;
            camera.position.z = GuiControls.camerPositionZ;

            WxpTexture.offset.x += 0.006;

            //tture.rotation+= 0.01;               

            //鼠标控制旋转
            //cube.rotation.z=mouseMoveX*0.02; 
            //document.getElementById("notice").innerHTML = cube.rotation.x.toFixed(2).toString();
            //divRender();
            //console.log(scene);
            //通过requestAnimationFrame方法在特定时间间隔重新渲染场景,循环调用
            requestAnimationFrame(WxpRender);

            //渲染场景
            renderer.render(scene, camera);
        }

        //-----------------------------------------    
        //ThreeJS仿真函数
        function WxpThreeJSInit() {

            //初始化场景
            WxpInitScene();

            //加载物体
            WxpAddObject();

            //界面设置
            WxpGuiSetting();

            //渲染场景
            WxpRender();
        }

        //确保WxpThreeJSinit方法在网页加载完毕后被调用
        window.onload = WxpThreeJSInit;
 
    </script>

</body>
</html>

 

 

Supongo que te gusta

Origin blog.csdn.net/sichuanpb/article/details/110953582
Recomendado
Clasificación