VUE Three.js 加载FBX模型并根据模型大小定位摄像机初始位置并可以全屏并可以有测量长度功能....并封装成组件

知识点:1.VUE 的 three.js 安装 直接cnpm install three 就好

至于FBX导入 相机控制 就单独引入就好比如:

import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader'         

import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'

2.FBX模型加载 

 var loader = new FBXLoader();
        // modelsrc为模型路径
	loader.load(this.modelsrc,geometry =>{
    this.scene.add (geometry) }

3.根据模型大小定位摄像机初始位置

var boxHelper = new THREE.BoxHelper();
var camera = new THREE.PerspectiveCamera( 50, 1, 1, 100000 );
boxHelper.setFromObject(mod);
var center = boxHelper.geometry.boundingSphere.center;
var radius = boxHelper.geometry.boundingSphere.radius;
var cameraPos = new THREE.Vector3(center.x+mod.position.x,center.y+mod.position.y,radius * 2.2 + center.z + mod.position.z);
var lookPos = new THREE.Vector3(center.x+mod.position.x,center.y+mod.position.y,center.z+mod.position.z);
camera.position.copy(cameraPos);
//这里有个需要注意的地方:如果使用了THREE.OrbitControls进行鼠标控制,那么一定要加上controls.target = lookPos;并在OrbitControls创建了之后加上camera.lookAt(lookPos);

var controls = new THREE.OrbitControls( camera, domElement );
controls.target = lookPos;
camera.lookAt(lookPos);

4 .raycaster 的偏移问题 

raycaster就是鼠标的点击事件可以获得位置 两点确定一条线 再求长度就是测距离了 但有时会偏移 所以用这个方法最好能规避

let container = document.getElementById('container3d');
        var mouse = new Three.Vector2();
        var raycaster = new Three.Raycaster();

        let getBoundingClientRect = container.getBoundingClientRect()
        let x = ((event.clientX - getBoundingClientRect .left) / container.offsetWidth) * 2 - 1;// 标准设备横坐标
        let y = -((event.clientY - getBoundingClientRect .top) / container.offsetHeight) * 2 + 1;// 标准设备纵坐标
        let standardVector = new Three.Vector3(x, y, 1);// 标准设备坐标
        // 标准设备坐标转世界坐标
        let worldVector = standardVector.unproject(this.camera);
        // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
        let ray = worldVector.sub(this.camera.position).normalize();
        // 创建射线投射器对象
        let rayCaster = new Three.Raycaster(this.camera.position, ray);
        // 返回射线选中的对象 第二个参数如果不填 默认是false
        let intersects = rayCaster.intersectObjects(this.modelmesh.children, true);

5.全屏事件  但要注意要再加个检测事件 可以初始化所做的操作  (因为我是封装成组件 弹窗是个小窗口)

fillwindow(){
                let element = document.getElementById('fullcontent')
                let content = document.getElementById('container3d')
                // document.getElementById('container3d').innerHTML = "";
                if (this.fullscreen) {
                    // content.style.height = "500px"
                    if (document.exitFullscreen) {
                        document.exitFullscreen();
                    } else if (document.webkitCancelFullScreen) {
                        document.webkitCancelFullScreen();
                    } else if (document.mozCancelFullScreen) {
                        document.mozCancelFullScreen();
                    } else if (document.msExitFullscreen) {
                        document.msExitFullscreen();
                    }
                } else {
                    // content.style.height = "94vh"
                    console.log(element.style.width)
                    if (element.requestFullscreen) {
                        element.requestFullscreen();
                    } else if (element.webkitRequestFullScreen) {
                        element.webkitRequestFullScreen();
                    } else if (element.mozRequestFullScreen) {
                        element.mozRequestFullScreen();
                    } else if (element.msRequestFullscreen) {
                        // IE11
                        element.msRequestFullscreen();
                    }
                }
               


      },
mounted() {
    var that = this
    window.onresize = function(){
      if(that.modelopen==true){
        console.log('eeeeessssccc')
         document.getElementById('container3d').innerHTML = "";
          setTimeout(function()  {
  
              that.init3d()
          
            }, 1000);
            
            
                setTimeout(function()  {
                
                    that.animate3d()
                
                }, 1000);
          that.fullscreen = !that.fullscreen;
          if (that.fullscreen==true) {
            document.getElementById('container3d').style.height = "94vh";
          }else{
            document.getElementById('container3d').style.height = "500px";
          }
      }    
    };
},

 6.画线 两点确认一条线 就可以画线了 并获得两点距离换算成毫米

drawLine( p1, p2) {
 
        var directionVector = new Three.Vector3();
        var p3 = new Three.Vector3();
        directionVector.x = p2.x - p1.x;
        directionVector.y = p2.y - p1.y;
        directionVector.z = p2.z - p1.z;
        //两点距离换算成毫米
        var length = Math.sqrt( directionVector.x * directionVector.x
            + directionVector.y * directionVector.y
            + directionVector.z * directionVector.z);
        var text = Math.round( length*10 ) + "";
        var geometry = new Three.Geometry();
        var material = new Three.LineBasicMaterial( { opacity:1,color:0x00ff00 } );
        geometry.vertices.push(p1);
        geometry.vertices.push(p1);
        geometry.vertices.push(p2);
        var geo = new Three.Line(geometry, material)
        this.alllinearr.push(geo)
        this.scene.add(geo)
        p3.x = (p1.x+p2.x)/2
        p3.y = (p1.y+p2.y)/2
        p3.z = (p1.z+p2.z)/2
        console.log(p3)
        this.initText( text, p3 );
 
        
 
    },

7.根据 线条长度加上文字标注 要引用import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'

然后再定义个渲染器再init 初始化的时候

// 标签render

                    this.labelRenderer = new CSS2DRenderer();

                    this.labelRenderer.setSize( container.clientWidth,container.clientHeight );

                    this.labelRenderer.domElement.style.position = 'absolute';

                    this.labelRenderer.domElement.style.top = '0px';

                    container.appendChild( this.labelRenderer.domElement );

animate上也要加上this.labelRenderer.render(this.scene,this.camera)

initText( wordFont, p1){
      
        var font = this.makeTextSprite(wordFont,{
          fontsize: 30,
          borderColor: {r:255, g:0, b:0, a:0.4},/* 边框黑色 */
          backgroundColor: {r:255, g:255, b:255, a:0.9}/* 背景颜色 */
        });
        font.center = new Three.Vector2(0,0)
        
        // console.log(font)
        font.position.copy( p1 );
        this.scene.add(font)
        this.alltextarr.push(font)


 
    },
    makeTextSprite(message, parameters) {

        if ( parameters === undefined ) parameters = {};

        var fontface = parameters.hasOwnProperty("fontface") ?
            parameters["fontface"] : "Arial";

        /* 字体大小 */
        var fontsize = parameters.hasOwnProperty("fontsize") ?
            parameters["fontsize"] : 16;

        /* 边框厚度 */
        var borderThickness = parameters.hasOwnProperty("borderThickness") ?
            parameters["borderThickness"] : 3;

        /* 边框颜色 */
        var borderColor = parameters.hasOwnProperty("borderColor") ?
            parameters["borderColor"] : { r:0, g:0, b:0, a:1.0 };

        /* 背景颜色 */
        var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
            parameters["backgroundColor"] : { r:255, g:255, b:255, a:1.0 };

        /* 创建画布 */
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');

        /* 字体加粗 */
        context.font = "Bold " + fontsize + "px " + fontface;

        /* 获取文字的大小数据,高度取决于文字的大小 */
        var metrics = context.measureText( message );
        var textWidth = metrics.width;

        /* 背景颜色 */
        context.fillStyle   = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
            + backgroundColor.b + "," + backgroundColor.a + ")";

        /* 边框的颜色 */
        context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
            + borderColor.b + "," + borderColor.a + ")";
        context.lineWidth = borderThickness;

        /* 绘制圆角矩形 */
        this.roundRect(context, 150/2, 125/2, textWidth + 50,  50,1);
        // this.roundRect(context, borderThickness/2, borderThickness/2, textWidth + borderThickness, fontsize * 1.4 + borderThickness,1);

        /* 字体颜色 */
        context.fillStyle = "rgba(0, 0, 0, 1.0)";
        console.log(borderThickness)
        console.log(fontsize + borderThickness)
        context.fillText( message, 100, 100);
        // console.log(context)
        // 创建标签
        
        
				var moonLabel = new CSS2DObject( canvas );
				return moonLabel



    },

    roundRect(ctx, x, y, w, h, r) {

        ctx.beginPath();
        ctx.moveTo(x+r, y);
        ctx.lineTo(x+w-r, y);
        ctx.quadraticCurveTo(x+w, y, x+w, y+r);
        ctx.lineTo(x+w, y+h-r);
        ctx.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
        ctx.lineTo(x+r, y+h);
        ctx.quadraticCurveTo(x, y+h, x, y+h-r);
        ctx.lineTo(x, y+r);
        ctx.quadraticCurveTo(x, y, x+r, y);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();

    },

 8.画线区分直线模式和非直线  直线第第二个三维向量点与第一个三维向量点相减就正 哪个最大就是朝哪个位置 

var xx = Math.abs(this.points[0].x - intersects[ 0 ].point.x)
                  var yy = Math.abs(this.points[0].y - intersects[ 0 ].point.y)
                  var zz = Math.abs(this.points[0].z - intersects[ 0 ].point.z)
                  
                  if (xx>yy&&xx>zz) {
                    var location = new Three.Vector3(intersects[ 0 ].point.x, this.points[0].y,this.points[0].z)
                    
                  }else if (yy>xx&&yy>zz) {
                    var location = new Three.Vector3(this.points[0].x,intersects[ 0 ].point.y, this.points[0].z)
                    
                  }
                  else if (zz>xx&&zz>yy) {
                    var location = new Three.Vector3(this.points[0].x,this.points[0].y,intersects[ 0 ].point.z)
                    
                  }

9.组件化 父子组件调用 不BB了

全部代码 懵B的话 就问我吧 

<template>
<div>
    <el-dialog
    title="模型预览"
    :visible.sync="modelopen"
    width="60%"
    @open="opendialog"
    class="yzqmodeldialog"
    >
    <div id="fullcontent">
      <div style="display:flex;text-align:right">
          <!-- 测量连线模式 -->
          <div style="text-align:right;margin:10px 0;width:100%;margin-right:10px;opacity: 0;" @click="measuretypeclick(0)" id="zhixian">
            <i class="iconfont icon-zhixian" ></i>
          </div>
          <div style="text-align:right;margin:10px 0;margin-right:10px;opacity: 0;" @click="measuretypeclick(1)" id="quxian">
            <i class="iconfont icon-quxian" ></i>
          </div>

          <div style="text-align:right;margin:10px 0;margin-right:10px" @click="measure">
            <i class="iconfont icon-chizi" id="chiziicon"></i>
          </div>
          <div style="text-align:right;margin:10px 0" @click="fillwindow">
            <i class="iconfont icon-quanping"></i>
          </div>
          
      </div>
      
      <div id="container3d" v-loading="vloading" style="height: 500px;
        width: 100%;position:relative"  @mousedown="onMouseDown" @mouseup="onMouseUp">
        </div>
    </div>
    
   </el-dialog>

  
  
  
  
   
</div>

   
</template>
<script>
import * as Three from 'three'
import {STLLoader} from 'three/examples/jsm/loaders/STLLoader'       
import {FBXLoader} from 'three/examples/jsm/loaders/FBXLoader'         
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'
export default {
  props: {
    open: {
      type: Boolean,
      default: false
      
    },
    src: {
      type: String,
      default: ''
    }
    
  },
  data() {
    return {
        vloading:true,
      modelopen:false,
      modelsrc:'',
      // 三维three.js
      camera: null,
        scene: null,
        renderer: null,
        labelRenderer:null,
        mesh: null,
        light:null,
        mixer:null,
        controls:null,
        length:200,
        fullscreen: false,

        pointsArray : [],
        window_mouse : true,

        mouseclick:false,
        measurebool:false,
        measuretype:0,
        objects:[],
        points:[],
        modelmesh:null,
        particleMaterial:null,


        leftmousecdownlocation:null,

        // 缓存所有测量信息
        allpointarr:[],
        alllinearr:[],
        alltextarr:[]



      
    }
  },
  watch: {
      open:{
          handler:function(e){
            this.modelopen = e
          }
      },
      modelopen:{
          handler:function(e){
              console.log(e)
              if (e==false) {
                
                this.$emit('modelopen', false)
                this.vloading = true
                document.getElementById('container3d').innerHTML = "";
                this.measurebool=false
                this.allpointarr=[]
                this.alllinearr=[]
                this.alltextarr=[]
                this.points=[]
                this.pointsArray=[]
                document.getElementById('chiziicon').style.color=""
                document.getElementById('zhixian').style.opacity="0"
                document.getElementById('quxian').style.opacity="0"
                for (let index = 0; index < this.allpointarr.length; index++) {
                  this.scene.remove(this.allpointarr[index])
                }
                for (let index = 0; index < this.alllinearr.length; index++) {
                  this.scene.remove(this.alllinearr[index])
                }
                for (let index = 0; index < this.alltextarr.length; index++) {
                  this.scene.remove(this.alltextarr[index])
                }


            }
          }
      },
      src:{
          handler:function(e){
              console.log(e)
              this.modelsrc=e

          }
      }
  },
  mounted() {
    var that = this
    window.onresize = function(){
      if(that.modelopen==true){
        console.log('eeeeessssccc')
         document.getElementById('container3d').innerHTML = "";
          setTimeout(function()  {
  
              that.init3d()
          
            }, 1000);
            
            
                setTimeout(function()  {
                
                    that.animate3d()
                
                }, 1000);
          that.fullscreen = !that.fullscreen;
          if (that.fullscreen==true) {
            document.getElementById('container3d').style.height = "94vh";
          }else{
            document.getElementById('container3d').style.height = "500px";
          }
      }    
    };
},

  methods: {
      opendialog(){
        console.log(11111112)
        var _this = this
        
        setTimeout(function()  {
        
            _this.init3d()
        
        }, 1000);
            
              
        
      },
    // 三维three.js
    init3d: function(){
                let container = document.getElementById('container3d');
                console.log(container)
                
        this.vloading=true       

				this.scene = new Three.Scene();
				this.scene.background = new Three.Color( 0xa0a0a0 );
				
				this.light = new Three.HemisphereLight(0xffffff, 0x444444);
				this.light.position.set( 0, 200, 0 );
				this.scene.add( this.light );

				this.light = new Three.DirectionalLight( 0xffffff );
				this.light.position.set( 0, 200, 100 );
				this.light.castShadow = true;
				this.light.shadow.camera.top = 180;
				this.light.shadow.camera.bottom = - 100;
				this.light.shadow.camera.left = - 120;
				this.light.shadow.camera.right = 120;
				this.scene.add( this.light );

        var PI2 = Math.PI * 2;
        this.particleMaterial = new Three.SpriteMaterial( {
 
            color: 0xff0000,
            program: function ( context ) {
 
                context.beginPath();
                context.arc( 0, 0, 0.5, 0, PI2, true );
                context.fill();
 
            }
 
        } );
        var loader = new FBXLoader();
        // modelsrc为模型路径
				loader.load(this.modelsrc,geometry =>{
					console.log(geometry)
                    this.scene.add (geometry) 
                    this.modelmesh = geometry


                    // 相机随着模型的大小初始化位置
                    var boxHelper = new Three.BoxHelper()
                    this.camera = new Three.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 1, 10000);
                    boxHelper.setFromObject(geometry)
                    var center = boxHelper.geometry.boundingSphere.center
                    var radius = boxHelper.geometry.boundingSphere.radius
                    var cameraPos = new Three.Vector3(center.x+geometry.position.x,radius * .8 +center.y+geometry.position.y,radius * 1.5 + center.z + geometry.position.z)
                    var lookPos = new Three.Vector3(center.x+geometry.position.x,center.y+geometry.position.y,center.z+geometry.position.z);
                    this.camera.position.copy(cameraPos)

                    this.renderer = new Three.WebGLRenderer({antialias:true})

                    this.renderer.setSize( container.clientWidth,container.clientHeight );

                    container.appendChild( this.renderer.domElement );

                    // 标签render
                    this.labelRenderer = new CSS2DRenderer();
                    this.labelRenderer.setSize( container.clientWidth,container.clientHeight );
                    this.labelRenderer.domElement.style.position = 'absolute';
                    this.labelRenderer.domElement.style.top = '0px';
                    container.appendChild( this.labelRenderer.domElement );
                    
                    window.addEventListener( 'resize', this.onWindowResize(), false );
                    this.controls = new OrbitControls( this.camera, this.labelRenderer.domElement );
                    this.controls.target = lookPos
                    this.camera.lookAt(lookPos)

                    // 全屏切换的时候如果开着测量模式先初始化
                    if(this.measurebool==true){
                      for (let index = 0; index < this.allpointarr.length; index++) {
                        this.scene.add(this.allpointarr[index])
                      }
                      for (let index = 0; index < this.alllinearr.length; index++) {
                        this.scene.add(this.alllinearr[index])
                      }
                      for (let index = 0; index < this.alltextarr.length; index++) {
                        this.scene.add(this.alltextarr[index])
                      }
                    }
                    var _this = this
                    setTimeout(function()  {
            
                        _this.animate3d()
                        _this.vloading = false
                    
                    }, 1000);
                    
					
				})

		
				
		
		  },
		animate3d: function() {
        requestAnimationFrame(this.animate3d);
        this.renderer.render(this.scene,this.camera)
        this.labelRenderer.render(this.scene,this.camera)
			  this.controls.update()
	},
	 onWindowResize() {
        let container = document.getElementById('container3d');
				this.camera.aspect = container.clientWidth / container.clientHeight;
				this.camera.updateProjectionMatrix();

				this.renderer.setSize( container.clientWidth, container.clientHeight );

			},
      fillwindow(){
                let element = document.getElementById('fullcontent')
                let content = document.getElementById('container3d')

                if (this.fullscreen) {

                    if (document.exitFullscreen) {
                        document.exitFullscreen();
                    } else if (document.webkitCancelFullScreen) {
                        document.webkitCancelFullScreen();
                    } else if (document.mozCancelFullScreen) {
                        document.mozCancelFullScreen();
                    } else if (document.msExitFullscreen) {
                        document.msExitFullscreen();
                    }
                } else {

                    console.log(element.style.width)
                    if (element.requestFullscreen) {
                        element.requestFullscreen();
                    } else if (element.webkitRequestFullScreen) {
                        element.webkitRequestFullScreen();
                    } else if (element.mozRequestFullScreen) {
                        element.mozRequestFullScreen();
                    } else if (element.msRequestFullscreen) {
                        // IE11
                        element.msRequestFullscreen();
                    }
                }
               


      },
      // 测量模式
      measure(){
        console.log(11111111111111111)
        this.measurebool = !this.measurebool
        if (this.measurebool==true) {
          document.getElementById('chiziicon').style.color="red"
          document.getElementById('zhixian').style.opacity="1"
          document.getElementById('quxian').style.opacity="1"
          if (this.measuretype==0) {
            document.getElementById('zhixian').style.color="red"
          }else{
            document.getElementById('quxian').style.color="red"
          }

        }else{
          document.getElementById('chiziicon').style.color=""
          document.getElementById('zhixian').style.opacity="0"
          document.getElementById('quxian').style.opacity="0"
          for (let index = 0; index < this.allpointarr.length; index++) {
            this.scene.remove(this.allpointarr[index])
          }
          for (let index = 0; index < this.alllinearr.length; index++) {
            this.scene.remove(this.alllinearr[index])
          }
          for (let index = 0; index < this.alltextarr.length; index++) {
            this.scene.remove(this.alltextarr[index])
          }
          this.allpointarr=[]
          this.alllinearr=[]
          this.alltextarr=[]
          this.points=[]
          this.pointsArray=[]


        }
        
      },
      measuretypeclick(e){
        if (this.measurebool==true) {
            this.measuretype = e
            if (e==0) {
              document.getElementById('zhixian').style.color="red"
              document.getElementById('quxian').style.color=""
            }else{
              document.getElementById('zhixian').style.color=""
              document.getElementById('quxian').style.color="red"
            }
        }
        
      },

      // 获得射线与平面相交的交点
      getIntersects(event){
        let container = document.getElementById('container3d');
        var raycaster = new Three.Raycaster();
        var mouse = new Three.Vector2();
        mouse.x = (event.clientX/container.clientWidth) * 2 - 1;
        mouse.y = -(event.clientY/container.clientWidth) * 2 + 1;
        var normal = new Three.Vector3(0,1,0);

        var planeGround = new Three.Plane(normal,0);

        raycaster.setFromCamera(mouse,this.camera);

        var ray = raycaster.ray;

        var intersects = ray.intersectPlane(planeGround);
        return intersects;

      },

      /* 鼠标按下事件 */
    onMouseDown(event) {
      if (this.measurebool==true) {
        if (event.button===0) {
          let container = document.getElementById('container3d');
          var mouse = new Three.Vector2();
          var raycaster = new Three.Raycaster();

          let getBoundingClientRect = container.getBoundingClientRect()
          let x = ((event.clientX - getBoundingClientRect .left) / container.offsetWidth) * 2 - 1;// 标准设备横坐标
          let y = -((event.clientY - getBoundingClientRect .top) / container.offsetHeight) * 2 + 1;// 标准设备纵坐标
          let standardVector = new Three.Vector3(x, y, 1);// 标准设备坐标
          // 标准设备坐标转世界坐标
          let worldVector = standardVector.unproject(this.camera);
          // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
          let ray = worldVector.sub(this.camera.position).normalize();
          // 创建射线投射器对象
          let rayCaster = new Three.Raycaster(this.camera.position, ray);
          // 返回射线选中的对象 第二个参数如果不填 默认是false
          let intersects = rayCaster.intersectObjects(this.modelmesh.children, true);


          if ( intersects.length > 0 ) {
                this.leftmousecdownlocation = intersects[ 0 ].point

    
            }
        }
        
      }
      

 
    },
    drawLine( p1, p2) {
 
        var directionVector = new Three.Vector3();
        var p3 = new Three.Vector3();
        directionVector.x = p2.x - p1.x;
        directionVector.y = p2.y - p1.y;
        directionVector.z = p2.z - p1.z;
        var length = Math.sqrt( directionVector.x * directionVector.x
            + directionVector.y * directionVector.y
            + directionVector.z * directionVector.z);
        var text = Math.round( length*10 ) + "";
        var geometry = new Three.Geometry();
        var material = new Three.LineBasicMaterial( { opacity:1,color:0x00ff00 } );
        geometry.vertices.push(p1);
        geometry.vertices.push(p1);
        geometry.vertices.push(p2);
        var geo = new Three.Line(geometry, material)
        this.alllinearr.push(geo)
        this.scene.add(geo)
        p3.x = (p1.x+p2.x)/2
        p3.y = (p1.y+p2.y)/2
        p3.z = (p1.z+p2.z)/2
        console.log(p3)
        this.initText( text, p3 );
 
        
 
    },
    initText( wordFont, p1){
      
        var font = this.makeTextSprite(wordFont,{
          fontsize: 30,
          borderColor: {r:255, g:0, b:0, a:0.4},/* 边框黑色 */
          backgroundColor: {r:255, g:255, b:255, a:0.9}/* 背景颜色 */
        });
        font.center = new Three.Vector2(0,0)
        
        // console.log(font)
        font.position.copy( p1 );
        this.scene.add(font)
        this.alltextarr.push(font)


 
    },
    makeTextSprite(message, parameters) {

        if ( parameters === undefined ) parameters = {};

        var fontface = parameters.hasOwnProperty("fontface") ?
            parameters["fontface"] : "Arial";

        /* 字体大小 */
        var fontsize = parameters.hasOwnProperty("fontsize") ?
            parameters["fontsize"] : 16;

        /* 边框厚度 */
        var borderThickness = parameters.hasOwnProperty("borderThickness") ?
            parameters["borderThickness"] : 3;

        /* 边框颜色 */
        var borderColor = parameters.hasOwnProperty("borderColor") ?
            parameters["borderColor"] : { r:0, g:0, b:0, a:1.0 };

        /* 背景颜色 */
        var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?
            parameters["backgroundColor"] : { r:255, g:255, b:255, a:1.0 };

        /* 创建画布 */
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');

        /* 字体加粗 */
        context.font = "Bold " + fontsize + "px " + fontface;

        /* 获取文字的大小数据,高度取决于文字的大小 */
        var metrics = context.measureText( message );
        var textWidth = metrics.width;

        /* 背景颜色 */
        context.fillStyle   = "rgba(" + backgroundColor.r + "," + backgroundColor.g + ","
            + backgroundColor.b + "," + backgroundColor.a + ")";

        /* 边框的颜色 */
        context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + ","
            + borderColor.b + "," + borderColor.a + ")";
        context.lineWidth = borderThickness;

        /* 绘制圆角矩形 */
        this.roundRect(context, 150/2, 125/2, textWidth + 50,  50,1);
        // this.roundRect(context, borderThickness/2, borderThickness/2, textWidth + borderThickness, fontsize * 1.4 + borderThickness,1);

        /* 字体颜色 */
        context.fillStyle = "rgba(0, 0, 0, 1.0)";
        console.log(borderThickness)
        console.log(fontsize + borderThickness)
        context.fillText( message, 100, 100);
        // console.log(context)
        // 创建标签
        
        
				var moonLabel = new CSS2DObject( canvas );
				return moonLabel



    },

    roundRect(ctx, x, y, w, h, r) {

        ctx.beginPath();
        ctx.moveTo(x+r, y);
        ctx.lineTo(x+w-r, y);
        ctx.quadraticCurveTo(x+w, y, x+w, y+r);
        ctx.lineTo(x+w, y+h-r);
        ctx.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
        ctx.lineTo(x+r, y+h);
        ctx.quadraticCurveTo(x, y+h, x, y+h-r);
        ctx.lineTo(x, y+r);
        ctx.quadraticCurveTo(x, y, x+r, y);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();

    },

 
    
    // 鼠标松开
    onMouseUp(event){
      // this.mouseclick=false
      // this.window_mouse = false;
      if (this.measurebool==true) {
        if(event.button===0){
          if (this.leftmousecdownlocation != null) {
            let container = document.getElementById('container3d');
            var mouse = new Three.Vector2();
            var raycaster = new Three.Raycaster();

            let getBoundingClientRect = container.getBoundingClientRect()
            let x = ((event.clientX - getBoundingClientRect .left) / container.offsetWidth) * 2 - 1;// 标准设备横坐标
            let y = -((event.clientY - getBoundingClientRect .top) / container.offsetHeight) * 2 + 1;// 标准设备纵坐标
            let standardVector = new Three.Vector3(x, y, 1);// 标准设备坐标
            // 标准设备坐标转世界坐标
            let worldVector = standardVector.unproject(this.camera);
            // 射线投射方向单位向量(worldVector坐标减相机位置坐标)
            let ray = worldVector.sub(this.camera.position).normalize();
            // 创建射线投射器对象
            let rayCaster = new Three.Raycaster(this.camera.position, ray);
            // 返回射线选中的对象 第二个参数如果不填 默认是false
            let intersects = rayCaster.intersectObjects(this.modelmesh.children, true);
            // console.log(intersects)
            if ( intersects.length > 0 ) {
              console.log(this.leftmousecdownlocation)
              console.log(intersects[ 0 ].point)
              var downnum = this.leftmousecdownlocation.x+this.leftmousecdownlocation.y+this.leftmousecdownlocation.z
              var upnum = intersects[ 0 ].point.x+intersects[ 0 ].point.y+intersects[ 0 ].point.z
              if (downnum==upnum) {
                //创建粒子,便于标识点击位置
                console.log('createspi')
                var particle = new Three.Sprite( this.particleMaterial );
                if (this.measuretype==0 && this.points.length>0) {
                  console.log(11222)
                  var xx = Math.abs(this.points[0].x - intersects[ 0 ].point.x)
                  var yy = Math.abs(this.points[0].y - intersects[ 0 ].point.y)
                  var zz = Math.abs(this.points[0].z - intersects[ 0 ].point.z)
                  
                  if (xx>yy&&xx>zz) {
                    var location = new Three.Vector3(intersects[ 0 ].point.x, this.points[0].y,this.points[0].z)
                    
                  }else if (yy>xx&&yy>zz) {
                    var location = new Three.Vector3(this.points[0].x,intersects[ 0 ].point.y, this.points[0].z)
                    
                  }
                  else if (zz>xx&&zz>yy) {
                    var location = new Three.Vector3(this.points[0].x,this.points[0].y,intersects[ 0 ].point.z)
                    
                  }
                  particle.position.copy(location);
                  //保存选中点
                  // var point = intersects[ 0 ].point
                  // point = location
                  this.points.push( location );
                }else{
                  particle.position.copy( intersects[ 0 ].point );
                  //保存选中点
                  this.points.push( intersects[ 0 ].point );
                }
                
                particle.scale.x = particle.scale.y = 10;
                this.scene.add( particle );
                this.allpointarr.push(particle)
                this.leftmousecdownlocation = null
                
                
    
                if( this.points.length >1 ) {
    
                    var p2 = this.points[this.points.length-1];
                    var p1 = this.points[this.points.length-2];
                    this.points = []
                    //动画的形式画线
                    this.drawLine( p1, p2);
                    
                }
    
              }
            }
          }
        }
      }
    },
 
    

  }
}
</script>
  <style   scoped>
    #container3d{
        /* height: 500px;
        width: 100%; */
        /* background: red; */
    }
    
    
   </style>
   <style >
   .yzqmodeldialog .el-dialog__body{
      padding-top: 0;
    }
   </style>

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值