机房项目

49 阅读1分钟

一个可以监测机房的系统 image.png

image.png

image.png

主要使用的是three.js可以使用代码如下:

  <div id="container" @dblclick="toggleFullscreen"></div>
</template>

<script setup>
import * as Three from 'three';
//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { onMounted } from 'vue';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

let scene = null;      // 场景
let camera = null;     // 相机
let renderer = null;   // 渲染器
let controls = null;   // 3D控制器
const maps = new Map();

// 初始化Three.js场景
const init = () => {
  const container = document.getElementById('container');
  if (!container) {
    console.error("Container element not found.");
    return;
  }

  // 创建透视相机
  camera = new Three.PerspectiveCamera(70, container.clientWidth / container.clientHeight, 0.01, 100);
  camera.position.set(0, 0, 2);

  // 创建场景
  scene = new Three.Scene();
  const loader = new GLTFLoader();
  loader.load('./models/machineRoom.gltf', function (gltf) {
    const { children } = gltf.scene;
    children.forEach((obj) => {
      const { map, color } = obj.material;
      changeMat(obj, map, color);
    });
    scene.add(...children);
  });

  // 创建WebGL渲染器并添加到容器
  renderer = new Three.WebGLRenderer();
  renderer.setSize(container.clientWidth, container.clientHeight);
  container.appendChild(renderer.domElement);

  // 创建 OrbitControls 控制器
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.minDistance = 1;
  controls.maxDistance = 100;
};

// 修改材质
const changeMat = (obj, map, color) => {
  if (map) {
    obj.material = new Three.MeshBasicMaterial({
      map: crtTexture(map.name),
    });
  } else {
    obj.material = new Three.MeshBasicMaterial({ color });
  }
};

// 创建或获取纹理
const crtTexture = (imgName) => {
  let curTexture = maps.get(imgName);
  if (!curTexture) {
    // 使用 TextureLoader 以 Image 对象加载纹理
    curTexture = new Three.TextureLoader().load('./models/' + imgName, (texture) => {
      texture.flipY = false;
      texture.wrapS = Three.RepeatWrapping;
      texture.wrapT = Three.RepeatWrapping;
    });

    maps.set(imgName, curTexture);
  }
  return curTexture;
};

// 处理窗口大小变化
const handleResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  updateRendererSize();
};

// 设置渲染器的尺寸和像素比
const updateRendererSize = () => {
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
};

//双击进入3D模型
const toggleFullscreen = () => {
  const fullscreenElement = document.fullscreenElement;

  if (!fullscreenElement) {
    // 进入全屏
    renderer.domElement.requestFullscreen();
  } else {
    // 退出全屏
    document.exitFullscreen();
  }
};

// 动画函数,用于更新和渲染场景
const animate = () => {
  requestAnimationFrame(animate);
  controls.update()
  renderer.render(scene, camera);
};

// 当Vue组件挂载后执行初始化和动画
onMounted(() => {
  // 初始化Three.js场景
  init();
  // 启动动画循环
  animate();
  // 监听窗口大小变化,更新渲染画面
  window.addEventListener("resize", handleResize);
});
</script>

<style scoped>
#container {
  width: 1100px;
  height: 400px;
}
</style>