threejs示例

前言

本示例主要介绍threejs简单应用,仅供入门学习,涉及商用产生的风险本人概不负责。其中涉及obj模型加载,obj模型由SU创建并导出,模型表面经过贴图处理,模型不能搞太多顶点,建议贴图处理,否则场景展现会卡,另外obj加载近场景后会以group类型存放。示例中还会涉及材质变化、物体选中、物体移动、以及全局小地图的简单实现。对于threejs相关概念可以参考threejs.org官网,本文中所引用js脚本经过测试可用。

本示例界面如下

整体布局
小地图
菜单控制
物体选中、移动
物体获取焦点

全部代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <link rel="icon" href="three.png">
    <title>CHZH</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            /* 溢出隐藏 */
        }

        #titlepanel{
            position:absolute;
            top:0px;
            
            left: calc(50% - 324px);             
            width:648px;            
            height: 50px;
            /*background-color:#093909;*/
            background-image: url("img/frame1.png");
            -moz-background-size: 100% 100%;              
            -webkit-background-size: 100% 100%;  
            background-size: 100% 100%;  
	        background-size:contain;
            background-repeat: no-repeat;
            
            opacity: 0.6;
            z-index: 0;            
            border-width: 0px;
            border-radius: 10px;
            border-style:solid;
            border-color: #093909;
            color:#FFFFFF;      
            text-align: center;                       
        }
         #titletext{
            position:absolute;
            top:15px;            
            left: calc(50% - 150px);             
            width:300px;            
            height: 50px;
            background-color:transparent;          
            z-index: 0;            
           
            border-color:transparent;
            color:#76b9fd;      
            text-align: center;   
            font-family:微软雅黑;   
            font-size:large;
            font-weight: bold;            

            
        }


        #loading {
            position: fixed;
            top: 50%;
            left: 50%;
            color: #FFFFFF;
            font-size: 20px;
            margin-top: -30px;
            margin-left: -40px;
        }
        #smallscreen{
            position:absolute;
            top:calc(100% - 325px);
            left: 5px;
            width: 320px;
            height: 320px;
           
            background-color:transparent;
            z-index: 0;
            border-style:solid;
            border-width: 1px;
            border-color: #76b9fd;
            color: green;
            
        }
        #smallscreenlabel
        {
            position:absolute;
            top:0px;
            left: 0px;
            background-color:transparent;
            z-index: 0; 
            padding: 0px;
            margin: 0px;
            color: green;
            
        }
        #capturescreen{
            position:absolute;
            top:calc(100% - 245px);
            left:calc(100% - 325px);
            width: 320px;
            height: 240px;
            background-color: #FFFFFF;
            z-index: 0;
            border-style:solid;
            border-width: 1px;
            border-color: #76b9fd;
        }
        #movie{
            
            width: 320px;
            height: 240px;
        }
        #focusobjinfo{
            position:absolute;
            top:calc(95vh);
            left: calc(100vh);
            width:fit-content;
            height:fit-content;
            background-color:black;
            opacity: 1;
            z-index: 0;
            border-width: 1px;
            color:#76b9fd;            
        }
        #findobjpanel{
            position:absolute;
            top:calc(95vh);
            left: calc(50vh);
            width: 450px;
            height: 50px;
            background-color:transparent;
            opacity: 1;
            z-index: 0;            
            border-width: 1px;
            color:green;
            
        }

        #searchcontext{
            
            background-color:black;
            opacity: 1;
            z-index: 0;            
            border-width: 1px;
            color:white;
            border-color: green;
            
        }       
        
        #searchbutton{            
            background-color:darkgreen;
            opacity: 1;
            z-index: 0;            
            border-width: 1px;
            color:white;
            border-color: green;            
        }
         #searchitem{            
            background-color:darkgreen;
            opacity: 1;
            z-index: 0;            
            border-width: 1px;
            color:white;
            border-color: green;            
        }
         #whiteboard{
            position:absolute;
            top:80px;
            left: 5px;
            width: 320px;
            height: 240px;
            background-color:transparent;
            z-index: 0;
            border-style:solid;
            border-width: 0px;
            border-color: gray;
            color: green;
        }
       
    </style>
    <script src="js/three-r93.js"></script>
    <script src="js/Detector.js"></script>
    <script src="js/dat.gui.min.js"></script>
    <script src="js/stats.min.js"></script>
     <!-- <script src="js/TrackballControls.js"></script>  -->
    
    <script src="js/OrbitControls.js"></script>
    <script src="js/MTLLoader.js"></script>
    <script src="js/OBJLoader.js"></script>
    <script src="js/chroma.js"></script>



</head>

<body>
    <p id="loading">加载中......</p>
    <div id="titlepanel"></div>
    <div id="titletext">货运场站仿真控制</div>
    <div id="whiteboard">
        <p>总箱-22 (TEU)</p>
        <p>空箱-5</p>
        <p>重箱-16</p>
        <p>待提-2</p>
    </div>




    <div id="smallscreen" ><p id="smallscreenlabel">俯视</p></div>
    <div id="focusobjinfo"></div>
    <div id="findobjpanel">        
        <select id="searchitem" >
            <option value="container" selected>集装箱</option>
            <option value="vehicle">货车</option>
        </select>
        <input id="searchcontext" type="text" width="100px" />
        <input id="searchbutton" type="button" onclick="searchobject()" value="查找">
    <input id="focusinfofollowmouse" onclick="layoutchange(this)" type="checkbox" >焦点信息跟随鼠标
    </div>
    <div id="capturescreen"><video id="movie" src="capture.mp4" loop="loop" autoplay  x5-video-player-type="h5"></video></div>



    <script>

        var focusinfoleft,focusinfotop//焦点信息显示对象显示位置信息

        var projectiveObj, selectobject;//定义上次投射到的对象,单击选中的对象

        var raycaster, mouse;//光投射器,鼠标位置对应的二维向量
        
        var focushelper,selectedhelper;

        var directionalLight;

        var listener, audioclick,audiobackground; 

        var moviesource;
        
        var yourposition;
           
        let scene, camera,smallcamera, renderer,smallrender, controls, guiControls,axes;
        let stats = initStats();

    function changemovesource(source){
        document.getElementById("movie").src=source;        
    }
   
    function initaudio(){
        
        //初始化音频

        // 非位置音频可用于不考虑位置的背景音乐
        // 创建一个监听者
         listener = new THREE.AudioListener();
        // camera.add( listener );
        // 创建一个非位置音频对象  用来控制播放
       
        audioclick = new THREE.Audio(listener);
        // 创建一个音频加载器对象
        var audioLoader = new THREE.AudioLoader();
        // 加载音频文件,返回一个音频缓冲区对象作为回调函数参数
        audioLoader.load('audio/select.mp3', function (AudioBuffer) {
            // console.log(AudioBuffer)
            // 音频缓冲区对象关联到音频对象audio
            audioclick.setBuffer(AudioBuffer);
            audioclick.setLoop(false); //是否循环
            audioclick.setVolume(1); //音量
            // 播放缓冲区中的音频数据           
        });

         audiobackground = new THREE.Audio(listener);
        var backaudioloader=new THREE.AudioLoader();
        backaudioloader.load("audio/background.mp3",function(AudioBuffer){
            audiobackground.setBuffer(AudioBuffer);
            audiobackground.setLoop(true); //是否循环
            audiobackground.setVolume(0.1); //音量
        });

    }

        function layoutchange(source){
            if(source.checked)
            {
                remberlayoutinfo();
                        
            }
            else
            {                
                resetlayoutinfo();
            }
        }

        function remberlayoutinfo(){
            //记录布局历史信息
            focusinfoleft=document.getElementById("focusobjinfo").offsetLeft;
            focusinfotop= document.getElementById("focusobjinfo").offsetTop;
        }
        function resetlayoutinfo()
        {
            //恢复布局历史信息
            document.getElementById("focusobjinfo").style.left = focusinfoleft+"px";
            document.getElementById("focusobjinfo").style.top = focusinfotop+"px";
        }

        function searchobject()
        {
            var searchstring=document.getElementById("searchcontext").value;
            var searchitem = document.getElementById("searchitem").value;
            var findobjname="";
            switch(searchitem)
            {
                case "container":
                    findobjname="集装箱";
                    break;
                case "vehicle":
                    findobjname = "货车";
                    break;
            }
            //查找集装箱
            for(var i=0;i<scene.children.length;i++)
            {
                var targetobj=scene.children[i];
                if(targetobj instanceof THREE.Group)
                {
                    if(targetobj.name=="container" && targetobj.name == searchitem)                                      
                    {
                        if(targetobj.boxnumber== searchstring)
                        {
                            FocusObjectChanged(targetobj);

                            var f= new THREE.Vector3(0,0,0);
                            f.copy( targetobj.position);                            
                            controls.target= f;
                            return;
                        }
                    }

                    if(targetobj.name == "vehicle" && targetobj.name == searchitem)
                    {
                        if (targetobj.vehicleid == searchstring) {
                            FocusObjectChanged(targetobj);     

                             var f = new THREE.Vector3(0, 0, 0);
                            f.copy(targetobj.position);
                            
                            controls.target = f;
                            
                            return;
                        }
                    }
                }
            }
            alert("未找到"+searchstring+ findobjname+"!")
        }
        
        /* 场景 */
        function initScene() {

            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x050505);
            //scene.background = new THREE.Color(0xcccccc);
            
        }

        function initraycaster(){
             /*
                   7、添加光投射器 及 鼠标二维向量 用于捕获鼠标移入物体

                       下次渲染时,通过mouse对于的二维向量判断是否经过指定物体
               */
            raycaster = new THREE.Raycaster();//光线投射器
            mouse = new THREE.Vector2();//二维向量 
            document.addEventListener('mousemove', function () {
                event.preventDefault();
                mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
                mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

                {
                    //焦点信息跟随鼠标
                    if(document.getElementById("focusinfofollowmouse").checked)
                    {
                        var objinfo = document.getElementById('focusobjinfo');
                        objinfo.style.top= event.clientY+10+'px';
                        objinfo.style.left= event.clientX+2+'px';
                    }else
                    {

                    }
                }

            }, false);
        }

        function initboxhelper(){          
           
            focushelper = new THREE.BoxHelper(camera, 0xff0000);                    
            scene.add(focushelper);


            selectedhelper= new THREE.BoxHelper(camera, 0xffff00);
            scene.add(selectedhelper);
          
        }

        function initax(){
            //显示坐标轴
            axes = new THREE.AxesHelper(8000);
            scene.add(axes);
        }
  

        function initlandgrid(){

            
                    /*
                        5、添加地面网格
                    */
                    /**
                     * size 网格总边长
                     * step 网格个数
                     * colorCenterLine  网格中心线颜色
                     * colorGrid    网格其他线颜色
                     */
                    var gridHelper = new THREE.GridHelper(8000, 100, 'green', '#093909');
                   // var gridHelper = new THREE.GridHelper(8000, 100, 'green', 'silver');
                    gridHelper.position.y = -2;
                    gridHelper.position.x = 0;
                    scene.add(gridHelper);
        }

        /* 相机 */
        function initCamera() {

            camera = new THREE.PerspectiveCamera(120, window.innerWidth / window.innerHeight, 0.1, 100000);
            camera.position.set(0, 150, 150);
            camera.lookAt(new THREE.Vector3(0, 0, 0));

            smallcamera= new THREE.PerspectiveCamera(120, 1, 0.1, 100000);
            smallcamera.position.set(0, 1100, 0);
            smallcamera.lookAt(new THREE.Vector3(0, 0, 0));

            var yourgeo=new THREE.SphereGeometry(30,30,30);
           // yourposition=new THREE.Mesh(yourgeo,new THREE.MeshLambertMaterial({ color:0xffffff, transparent: false, opacity: 0.0, side: THREE.DoubleSide }));
           var yourmaterial =  new THREE.MeshPhongMaterial({color: 0x00ffff });
            //添加高光颜色
            //yourmaterial.specular = new THREE.Color(0x00ffff);
            //添加高光的平滑度,默认为30,值越高越强烈
            yourmaterial.shininess = 30;
            
            yourposition=new THREE.Mesh(yourgeo,yourmaterial);
            yourposition.name="yourposition";
            scene.add(yourposition);

        }

        /* 渲染器 */
        function initRender() {

            renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: false });
            renderer.setSize(window.innerWidth, window.innerHeight);
            //renderer.shadowMap.Enabled=true;
            document.body.appendChild(renderer.domElement);     
            renderer.autoClear = true;

            

            //小窗口
            smallrender = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: false });
            smallrender.setSize(320,320);
            smallrender.autoClear=false;
            document.getElementById("smallscreen").appendChild(smallrender.domElement);
            
        }

        /* 灯光 */
        function initLight() {

            
            scene.add(new THREE.AmbientLight(0xFFFFFF, 5));

            directionalLight = new THREE.DirectionalLight(0xcccccc, 2);
            directionalLight.castShadow = true;             
            directionalLight.position.set(0, 1000, 1000);
            scene.add(directionalLight);
           

        }

        /* 控制器 */
        function initControls() {

            // /* 轨迹球控件 */
            // controls = new THREE.TrackballControls(camera, renderer.domElement);
            // /* 属性参数 */
            // controls.rotateSpeed = 0.8;// 旋转速度
            // controls.zoomSpeed = 0.8;// 缩放速度
            // controls.panSpeed = 0.8;// 平controls
            // controls.staticMoving = false;// 静止移动,为 true 则没有惯性
            // controls.dynamicDampingFactor = 0.2;// 阻尼系数 越小 则滑动越大
            // controls.minDistance = 30; // 最小视角
            // controls.maxDistance = 1000;// 最大视角 Infinity 无穷大

            controls = new THREE.OrbitControls(camera, renderer.domElement);
            //controls.addEventListener( 'change', render );
            controls.autoRotateSpeed = 0.02;//自动旋转速度
            controls.autoRotate = false;
            controls.rotateSpeed = 0.5;// 旋转速度
            controls.zoomSpeed = 0.5;// 缩放速度
            controls.panSpeed = 0.5;// 平移速度

            controls.enableDamping = true;// 有惯性
            controls.dampingFactor = 0.25;// 阻尼系数 越小 则滑动越大

           // controls.staticMoving = true;// 静止移动,为 true 则没有惯性
          //  controls.dynamicDampingFactor = 0.1;// 阻尼系数 越小 则滑动越大

            controls.minDistance = 30; // 最小视角
            controls.maxDistance = 900;// 最大视角 Infinity 无穷大
            
        }

        /* 调试插件 */
        function initGui() {

            guiControls = new function () {
                this.rotateSpeed = controls.rotateSpeed;
                this.zoomSpeed = controls.zoomSpeed;
                this.panSpeed = controls.panSpeed;
                this.enableDamping = controls.enableDamping;
                this.dampingFactor = controls.dampingFactor;
                this.minDistance = controls.minDistance;
                this.maxDistance = controls.maxDistance;
                this.自动旋转= controls.autoRotate;
                this.距离=smallcamera.position.y;                
            };

            var booldropdown = { 显示:'是' };
            var boolstats = ['否', '是'];

            var backaudiodropdown={背景音乐:'关'};
            var switchstats=['关','开'];

            var videosourcedropdown={视频源:"场站高点"};
            var sourcelist=['场站高点','集卡入口','集卡出口'];

            let gui = new dat.GUI();

            var maincontrol=gui.addFolder("主视控制")

            maincontrol.add(guiControls, 'rotateSpeed', 0, 1).onChange(function (e) {
                controls.rotateSpeed = e;
            });
            maincontrol.add(guiControls, 'zoomSpeed', 0, 1).onChange(function (e) {
                controls.zoomSpeed = e;
            });
            maincontrol.add(guiControls, 'panSpeed', 0, 1).onChange(function (e) {
                controls.panSpeed = e;
            });
            maincontrol.add(guiControls, 'enableDamping').onChange(function (e) {
                controls.enableDamping = e;
            });
            maincontrol.add(guiControls, 'dampingFactor', 0, 1).onChange(function (e) {
                controls.dampingFactor = e;
            });
            maincontrol.add(guiControls, 'minDistance', 0, 500).onChange(function (e) {
                controls.minDistance = e;
            });
            maincontrol.add(guiControls, 'maxDistance', 100, 1800).onChange(function (e) {
                controls.maxDistance = e;
            });
            maincontrol.add(guiControls, '自动旋转', 0, 1).onChange(function (e) {
                controls.autoRotate = e;
               
            });
            maincontrol.add(backaudiodropdown, '背景音乐').options(switchstats).onChange(function (e) {
                 if (e=="开") {
                      audiobackground.play();
                  } else {
                      audiobackground.stop();
                  }
            });

            var smallcontrol = gui.addFolder("俯视控制")
             smallcontrol.add(guiControls, "距离", 300, 2000).onChange(function (e) {
                smallcamera.position.y = e;
               
            });
            
            smallcontrol.add(booldropdown, '显示').options(boolstats).onChange(function(e){
                document.getElementById("smallscreen").style.visibility=e=="是"?"visible":"hidden";
            });

            var capturecontrol = gui.addFolder("云台控制")
            capturecontrol.add(booldropdown, '显示').options(boolstats).onChange(function (e) {
                document.getElementById("capturescreen").style.visibility = e == "是" ? "visible" : "hidden";
            });
             capturecontrol.add(videosourcedropdown, '视频源').options(sourcelist).onChange(function (e) {
                 var source;
                switch(e)
                {
                    case "场站高点":
                        source="capture.mp4"
                        break;
                    case "集卡入口":
                        source = "capture1.mp4"
                        break;
                    case "集卡出口":
                        source = "capture2.mp4"
                        break;
                }
                changemovesource(source);
            });
            
            
            gui.closed=true;//控制面板默认打开            

        }

        /* 场景中的内容 */
        function initContent() {

           Container("TBJU123411", "J510010071", "20", true, -900);
           Container("TBJU123412", "J510010081", "20", false, -800);
           Container("TBJU123413", "J510010091", "20", false, -700);
           Container("TBJU123414", "J510010101", "20", false, -600);
           Container("TBJU123415", "J510010111", "20", false, -500);
          
           Container("TBJU123416", "J510010121", "20", false, -400);
           Container("TBJU123678", "J510010151", "20",false,-100);
           Container("TBJU123567", "J510010141", "20",true,-200);
           Container("TBJU123456", "J510010131", "20",true,-300);
           
           Container("TBJU234678", "J510020151", "20",false, -100,0,30);
           Container("TBJU234567", "J510020141", "20",false, -200,0,30);
           Container("TBJU234456", "J510020131", "20",false, -300,0,30);
           
           Container("TBJU123789","J510010161","20",false);
           Container("TBJU123678", "J510010162", "20",false,0,26,0);
           Container("TBJU123890", "J510010171","40",false,100,0);            
           Container("TBJU123901", "J510010181","40",false, 250, 0);
           Container("TBJU123902", "J510020171", "40", true,100, 0,30);
           Container("TBJU123904", "J510020191", "40", true, 250, 30, 0);
           Container("TBJU123903", "J510020201", "40", false, 400, 0, 30);
           
           Container("TBJU123904", "J510020201", "40", false, 550, 0, 30);
           Container("TBJU123905", "J510020201", "40", false, 700, 0, 30);
           Container("TBJU123906", "J510020201", "40", false, 850, 0, 30);


           Vehicle("128", "哈尔滨", "天津",false, -1050, 0, 80);
           Vehicle("127", "哈尔滨", "天津",false, -900, 0, 80);
           Vehicle("126", "哈尔滨", "天津",false, -750, 0, 80);
           Vehicle("125", "哈尔滨", "天津",false, -600, 0, 80);
           Vehicle("124", "哈尔滨", "天津",false, -450, 0, 80);
           Vehicle("123","哈尔滨","天津",false ,-300, 0, 80);
           Vehicle("456", "哈尔滨", "南京",false, -150, 0, 80);
           Vehicle("789", "哈尔滨", "上海",false,  0, 0, 80);
           Vehicle("345", "哈尔滨", "福建",false,  150, 0, 80);
           Vehicle("234", "哈尔滨", "广州",false, 300, 0, 80);
           Vehicle("235", "哈尔滨", "广州",false, 450, 0, 80);
           Vehicle("236", "哈尔滨", "广州",true, 600, 0, 80);
           Vehicle("237", "哈尔滨", "广州",false, 750, 0, 80);
           Vehicle("238", "哈尔滨", "广州",false, 900, 0, 80);


           
           

            document.getElementById('loading').style.display = 'none';
        }

        /*
            ContainerType:20 or 40
            boxid:箱号
            dockerid:容器号,车厢号、集卡号、箱位号
        */
        function Container(boxnumber,dockerid,ContainerType, isempty=false,x=0,y=0,z=0)
        {
           var objname="";
           var height=0;
            switch(ContainerType)
            {
                case "40":
                    objname="container40";
                    height=28;
                    break;
                case "20":
                    objname="container20";
                    height=25;
                    break;
            }

            let mtlLoader = new THREE.MTLLoader();
            mtlLoader.load(objname+'.mtl', function (materials) {
                
                new THREE.OBJLoader()
                .setMaterials(materials)
                .load(objname+'.obj', function (object) {                    
                    object.scale.set(0.01, 0.01, 0.01);
                    object.position.x=x;
                    object.position.y=y;
                    object.position.z=z;
                    object.name= "container"; //对象名
                    object.containertype= ContainerType; //箱型
                    object.boxnumber= boxnumber; //箱号         
                    object.dockerid = dockerid; //容器号     
                    object.isempty=isempty;
                    //object.castShadow=true;
                    //object.receiveShadow=true;   
                    object.selfheight=height;
                    if(isempty){
                        setobjopacity(object,0.6);     
                    }   

                    scene.add(object);                                       
                    //return object;
                });
            });
            
        }

        function Vehicle(vehicleid,fromstation,tostation,iserror=false,x=0,y=0,z=0)
        {
               let mtlLoader = new THREE.MTLLoader();
            mtlLoader.load('vehiclenowheel.mtl', function (materials) {

                new THREE.OBJLoader()
                    .setMaterials(materials)
                    .load('vehiclenowheel.obj', function (object) {
                        object.scale.set(0.03, 0.035, 0.045);
                        object.position.x = x;
                        object.position.y = y;
                        object.position.z = z;
                        object.name = "vehicle"; //对象名          
                        object.fromstation= fromstation;            
                        object.tostation= tostation;
                        object.vehicleid = vehicleid; //容器号     
                        object.iserror= iserror;
                        object.selfheight=12;
                        scene.add(object);
                        if(iserror)
                        {
                            setobjcolor(object,0x000000);
                        }
                        //return object;
                    });
            });
        }



        function setobjopacity(obj,opacity)
        {
            /*
              设置对象透明度
            */
            if(obj instanceof THREE.Group)
            {

                for(var i=0;i<obj.children[0].material.length;i++)
                {
                    obj.children[0].material[i].transparent=true;
                    obj.children[0].material[i].opacity=opacity;
                    //obj.children[0].material[i].wireframe=true;
                    //obj.children[0].material[i].depthTest = false;
                }

                return;
            }
            if(obj instanceof THREE.Mesh)
            {
                return;
            }
        }

         function setobjcolor(obj, color) {
                /*
                  设置对象颜色
                */
                if (obj instanceof THREE.Group) {

                    for (var i = 0; i < obj.children[0].material.length; i++) {
                        obj.children[0].material[i].color.set(color);                       
                    }

                    return;
                }
                if (obj instanceof THREE.Mesh) {
                    return;
                }
            }

        /* 性能插件 */
        function initStats() {

            let stats = new Stats();

            document.body.appendChild(stats.domElement);

            return stats;

        }

        /* 窗口变动触发 */
        function onWindowResize() {

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

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

        }
        /* 数据更新 */
        function update() {

            stats.update();            
            controls.update();

           yourposition.position.x=camera.position.x;
           yourposition.position.z=camera.position.z;
            
            
        }

        /* 初始化 */
        function init() {

            initScene();
            initaudio();
            //initax();
            initlandgrid();
            initCamera();            
            initraycaster();
            initRender();
            initLight();
            initControls();
            initContent();
            initGui();

            initboxhelper();
            
           



            /* 监听事件 */
            window.addEventListener('resize', onWindowResize, false);

            window.addEventListener('click', function (event) {

                if (projectiveObj) {

                    if (projectiveObj.hasChecked ) {

                        projectiveObj.hasChecked = false;
                        selectobject = null;
                        
                    }
                    else {
                        if(selectobject != null && selectobject != projectiveObj)
                        {
                            selectobject.position.x=projectiveObj.position.x;
                            selectobject.position.y=projectiveObj.position.y+ projectiveObj.selfheight;
                            selectobject.position.z=projectiveObj.position.z;
                            //selectobject = null;
                        }else
                        {
                            projectiveObj.hasChecked = true;
                            selectobject = projectiveObj;
                        }
                      
                    }
                    

                     SelectObjectChanged(selectobject);
                }

            }, false);
            
        }



        
        /**
         * 根据光投射器判断鼠标所在向量方向是否穿过物体,穿过则改变物体材质
         * @param {*} raycaster 光投射器
         * @param {*} scene     场景
         * @param {*} camera    相机
         * @param {*} mouse     鼠标位置对应的二维向量
         */
        function renderRaycasterObj(raycaster, scene, camera, mouse) {

            raycaster.setFromCamera(mouse, camera);
          
            var intersects = raycaster.intersectObjects(scene.children, true);

            //检查射线指向物体集合是否不为空
            if (intersects.length > 0) {
                  var currentProjectiveObjT= intersects[0].object;

                if((currentProjectiveObjT instanceof THREE.AxisHelper) || (currentProjectiveObjT instanceof THREE.GridHelper))
                {
                    return;
                }
                

                if(currentProjectiveObjT instanceof THREE.Mesh)
                {
                    if(currentProjectiveObjT.name=="yourposition"){return;/*忽略定位指示标*/}
                   
                    if (projectiveObj != currentProjectiveObjT) {
                        projectiveObj = currentProjectiveObjT.parent;
                        FocusObjectChanged(projectiveObj);
                    }
                }
            }
            else
            {
                projectiveObj = null;
            }
           

        }

        function SelectObjectChanged(object)
        {
            audioclick.play(); //play播放、stop停止、pause暂停

            if(object == null)
            {
                selectedhelper.visible=false;
            }
            else
            {
                selectedhelper.setFromObject(object);
                selectedhelper.visible=true;
            }
        }

        function FocusObjectChanged(object) {

            
                if (object === undefined) object = null;
                if (object === null) {
                    focushelper.visible = false;
                   
                    
                } else {
                    focushelper.setFromObject(object);                    
                    focushelper.visible = true;          
                          
                    if(object.name=="container")
                    {
                        document.getElementById("focusobjinfo").innerText = "集装箱:" + object.boxnumber+","+object.containertype+","+ object.dockerid+","+(object.isempty?"空":"重");
                    }
                    else if(object.name=="vehicle")
                    {
                        document.getElementById("focusobjinfo").innerText = "货车:" + object.vehicleid +","+object.fromstation+">>>>"+object.tostation +","+(object.iserror?"坏":"好");
                        
                    }
                    
                    
                }
                

            }


        /* 循环渲染 */
        function animate() {

            
            requestAnimationFrame(animate);                  

            renderRaycasterObj(raycaster, scene, camera, mouse);//渲染光投射器投射到的对象
           
            yourposition.visible=false;
            renderer.render(scene, camera);

            yourposition.visible = true;
            smallrender.render(scene, smallcamera);

            update();

        }

        /* 初始加载 */
        (function () {
            console.log("three init start...");        
            
            init();           
                      
            animate();

            console.log("three init end...");
        }       
        )();

    </script>
</body>

</html>

结束

threejs后期可做更多特效处理,结合音效可实现更好视听觉体验,弄不好就是玩,希望有喜欢这块的同行不吝拍砖。
示例代码下载

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以给你介绍一下微信小程序如何使用Three.js来创建示例。 首先,你需要在微信小程序中引入Three.js库。你可以通过在小程序的app.json文件中的"usingComponents"字段中添加以下代码来引入Three.js库: ```json "usingComponents": { "canvas": "/path/to/three.js" } ``` 接下来,在你的小程序页面中,你可以使用`<canvas>`标签来创建一个画布,用于渲染Three.js场景。在页面的wxml文件中添加以下代码: ```html <canvas id="myCanvas"></canvas> ``` 然后,在页面的js文件中,你可以使用以下代码来初始化Three.js场景并在画布上渲染: ```javascript const canvas = wx.createCanvasContext('myCanvas'); const renderer = new THREE.WebGLRenderer({ canvas: canvas.canvas }); // 创建场景 const scene = new THREE.Scene(); // 创建相机 const camera = new THREE.PerspectiveCamera(75, canvas.canvas.width / canvas.canvas.height, 0.1, 1000); camera.position.z = 5; // 创建几何体 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 渲染循环 function animate() { requestAnimationFrame(animate); // 旋转几何体 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // 渲染场景 renderer.render(scene, camera); } // 开始渲染循环 animate(); ``` 这是一个简单的示例,它创建了一个旋转的立方体并在画布上渲染。你可以根据自己的需求修改和扩展这个示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值