Threejs之相机基础

参考资料

知识点

注:基于Three.jsv0.155.0

  • 正投影相机
  • 正投影相机-Canvas尺寸变化
  • 包围盒Box3
  • 地图案例(包围盒、正投影)
  • 相机动画(.position和.lookAt())
  • 不同方向的投影视图
  • 旋转渲染结果(.up相机上方向)
  • 管道漫游案例
  • OrbitControls旋转缩放限制
  • 相机控件MapControls

代码实现

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Three.js</title>
</head>
  <body>
  </body>
  <!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
  <script type="importmap">
    {
      "imports": {
        "three": "./js/three.module.js",
        "three/addons/": "../three.js/examples/jsm/"
      }
    }
  </script>
  <script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { MapControls } from 'three/addons/controls/MapControls.js';

    const width = window.innerWidth
    const height = window.innerHeight

    // 场景
    const scene = new THREE.Scene();

    const data = [
      [110.3906, 34.585],
      [110.8301, 34.6289],
      [111.1816, 34.8047],
      [111.5332, 34.8486],
      [111.7969, 35.0684],
      [112.0605, 35.0684],
      [112.0605, 35.2881],
      [112.7637, 35.2002],
      [113.1152, 35.332],
      [113.6426, 35.6836],
      [113.7305, 36.3428],
      [114.873, 36.123],
      [114.9609, 36.0791],
      [115.1367, 36.2109],
      [115.3125, 36.0791],
      [115.4883, 36.167],
      [115.3125, 35.8154],
      [116.1035, 36.0791],
      [115.4883, 35.7275],
      [115.2246, 35.4199],
      [115.0488, 35.376],
      [114.7852, 35.0684],
      [115.4004, 34.8486],
      [115.5762, 34.585],
      [116.1914, 34.585],
      [116.1914, 34.4092],
      [116.543, 34.2773],
      [116.6309, 33.9258],
      [116.1914, 33.7061],
      [116.0156, 33.9697],
      [115.6641, 34.0576],
      [115.5762, 33.9258],
      [115.5762, 33.6621],
      [115.4004, 33.5303],
      [115.3125, 33.1787],
      [114.873, 33.1348],
      [114.873, 33.0029],
      [115.1367, 32.8711],
      [115.2246, 32.6074],
      [115.5762, 32.4316],
      [115.8398, 32.5195],
      [115.9277, 31.7725],
      [115.4883, 31.6846],
      [115.4004, 31.4209],
      [115.2246, 31.4209],
      [115.1367, 31.5967],
      [114.7852, 31.4648],
      [114.6094, 31.5527],
      [114.5215, 31.7725],
      [114.1699, 31.8604],
      [113.9941, 31.7725],
      [113.8184, 31.8604],
      [113.7305, 32.4316],
      [113.4668, 32.2998],
      [113.2031, 32.4316],
      [112.3242, 32.3438],
      [111.5332, 32.6074],
      [111.0059, 33.2666],
      [111.0059, 33.5303],
      [110.6543, 33.8379],
      [110.6543, 34.1455],
      [110.4785, 34.2334],
      [110.3906, 34.585]
  ]
    const pointsArr = [];// 一组二维向量表示一个多边形轮廓坐标
    data.forEach(function(e){
        // data坐标数据转化为Vector2构成的顶点数组
        const v2 = new THREE.Vector2(e[0],e[1])
        pointsArr.push(v2);
    })
    // Shape表示一个平面多边形轮廓,参数是二维向量构成的数组pointsArr
    const shape = new THREE.Shape(pointsArr);
    // 多边形shape轮廓作为ShapeGeometry参数,生成一个多边形平面几何体
    const geometry = new THREE.ShapeGeometry(shape);
    // 生成一个平面网格模型
    const mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
      color: '#0000ff',
      side: THREE.DoubleSide
    }))
    // 设置模型位置
    mesh.position.set(0, 0, 0);
    // 添加模型到场景
    scene.add(mesh);

    // 点光源
    const pointLight = new THREE.PointLight( 0xffffff, 1.0, 0, 0);
    pointLight.position.set(200, 200, 200 );
    scene.add( pointLight );
    
    // 环境光
    const ambientLight = new THREE.AmbientLight( 0xffffff, 1);
    scene.add( ambientLight );

    // 坐标系
    const axes = new THREE.AxesHelper(200);
    scene.add(axes);

    // 相机
    const s = 2.5;//控制left, right, top, bottom范围大小
    const k = width / height; //canvas画布宽高比
    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);
    // const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 3000);
    // camera.position.set(300, 300, 300); 
    // camera.lookAt(0, 0, 0); //指向坐标原点
    
    // 包围盒计算模型对象的大小和位置
    const box3 = new THREE.Box3();
    box3.expandByObject(mesh); // 计算模型包围盒
    const size = new THREE.Vector3();
    box3.getSize(size); // 计算包围盒尺寸
    console.log('模型包围盒尺寸',size);
    const center = new THREE.Vector3();
    box3.getCenter(center); // 计算包围盒中心坐标
    console.log('模型中心坐标1',center);

    const x = 113.51,y = 33.88;
    camera.position.set(x, y, 300);
    // 你可以看到模型相比原来上下颠倒  y坐标轴朝下
    camera.up.set(0,-1,0)
    camera.lookAt(x, y, 0);

    // 渲染器
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);
    renderer.render(scene, camera);
    document.body.appendChild(renderer.domElement);

    renderer.outputColorSpace = THREE.SRGBColorSpace;//设置为SRGB颜色空间

    // const controls = new OrbitControls(camera, renderer.domElement);
    // controls.target.set(x, y, 0); //与lookAt参数保持一致
    // controls.update();//update()函数内会执行camera.lookAt(controls.target)
    // // 左右旋转范围
    // controls.minAzimuthAngle = -Math.PI/2;
    // controls.maxAzimuthAngle = Math.PI/2;
    // // Vector3 {x: -49.803731395661714, y: 146.90160246353028, z: 35.47368304973255}
    // // Vector3 {x: -11.970638355445846, y: -51.0801205834488, z: 0.7429414745816755}
    // // 渲染循环
    // let angle = 0; //用于圆周运动计算的角度值
    // const R = 100; //相机圆周运动的半径
    // function render() {
    //     angle += 0.01;
    //     // 相机y坐标不变,在XOZ平面上做圆周运动
    //     camera.position.x = R * Math.cos(angle);
    //     camera.position.z = R * Math.sin(angle);
    //     renderer.render(scene, camera);
    //     camera.lookAt(0,0,0);
    //     // console.log('🚀 ~ file: 6.加载外部三维模型.html:70 ~ render ~ camera:', camera.position) // 鼠标左键改变相机位置
    //     // console.log('🚀 ~ file: 6.加载外部三维模型.html:66 ~ controls:', controls.target) // 鼠标右键改变相机观察点
    //     requestAnimationFrame(render);
    // }
    // // render();

    // 控制器

    // controls.addEventListener('change', () => {
    //   // 因为动画渲染了,所以这里可以省略
    //   renderer.render(scene, camera);
    // });

    const controls = new MapControls(camera, renderer.domElement);
    controls.addEventListener('change', function () {
      // 鼠标右键旋转时候,查看.position变化
      // 鼠标左键拖动的时候,查看.position、.target的位置会变化
      console.log('camera.position',camera.position);
      console.log('controls.target',controls.target);
    });
  </script>
</html>
相关推荐
gis分享者1 天前
学习threejs,使用MeshBasicMaterial基本网格材质
threejs·basicmaterial·基本网格材质
gis分享者5 天前
学习threejs,使用PointLight点光源
threejs·点光源·pointlight
gis分享者9 天前
学习threejs,使用HemisphereLight半球光
threejs·hemispherelight·半球光
mirrornan13 天前
web3D交互展示是什么?应用场景有哪些?
3d·web3·3d模型·web3d·3d展示
gis分享者14 天前
学习threejs,使用Lensflare模拟镜头眩光
threejs·lensflare·眩光
gis分享者16 天前
学习threejs,tga格式图片文件贴图
threejs·贴图·tga·tgaloader
gis分享者17 天前
学习threejs,pvr格式图片文件贴图
threejs·贴图·pvr
mirrornan1 个月前
3D可视化定制:开启个性化购物新时代,所见即所得
3d·3d模型·web3d
mirrornan1 个月前
产品Web3D交互展示有什么优势?
3d·3d模型·web3d·3d展示
gis分享者1 个月前
学习threejs,使用OrbitControls相机控制器
threejs·相机·相机控制器·orbitcontrols