|
@@ -0,0 +1,296 @@
|
|
|
+<template>
|
|
|
+ <div class="screen">
|
|
|
+ <div style="height: 10px"></div>
|
|
|
+ <div class="titleImage">
|
|
|
+ <el-image :src="titleUrl" />
|
|
|
+ <span class="Heading">龙弛智慧隧道系统</span>
|
|
|
+ </div>
|
|
|
+ <div class="coreBox">
|
|
|
+ <div ref="container" class="three-container"></div>
|
|
|
+ <div class="formBox">
|
|
|
+ <div class="panel">
|
|
|
+ <span class="panel-title">亮度调整</span>
|
|
|
+ <el-slider
|
|
|
+ v-model="transparency"
|
|
|
+ :step="50"
|
|
|
+ show-stops
|
|
|
+ :show-tooltip="false"
|
|
|
+ class="panel-slider"
|
|
|
+ @change="changeTransparency"
|
|
|
+ />
|
|
|
+ <div class="brightness" style="margin: 90px 0 0 25px;">
|
|
|
+ <span>低</span>
|
|
|
+ <span>中</span>
|
|
|
+ <span>高</span>
|
|
|
+ </div>
|
|
|
+ <el-slider
|
|
|
+ v-model="transparencyTwo"
|
|
|
+ :step="50"
|
|
|
+ show-stops
|
|
|
+ :show-tooltip="false"
|
|
|
+ class="panel-slider2"
|
|
|
+ @change="changeTransparencyTwo"
|
|
|
+ />
|
|
|
+ <div class="brightness" style="margin: 50px 0 0 25px;">
|
|
|
+ <span>低</span>
|
|
|
+ <span>中</span>
|
|
|
+ <span>高</span>
|
|
|
+ </div>
|
|
|
+ <div class="panel-bottom"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import * as THREE from 'three';
|
|
|
+import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
|
+import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
|
|
+import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
|
|
+import { useScreenStore } from '@/pinia/modules/screen'
|
|
|
+// 单灯控制
|
|
|
+// import { updateTunnelLamp } from "@/api/tunnel";
|
|
|
+// 四路控制
|
|
|
+// import { deviceSwitch } from "@/api/device";
|
|
|
+// 标题图片
|
|
|
+import titleUrl from '@/assets/title_bg.png'
|
|
|
+// import {ElMessage} from "element-plus";
|
|
|
+
|
|
|
+const useScreen = useScreenStore()
|
|
|
+// 获取容器引用
|
|
|
+const container = ref(null);
|
|
|
+
|
|
|
+// 定义 Three.js 相关变量
|
|
|
+let scene, camera, renderer, controls;
|
|
|
+
|
|
|
+// 创建场景
|
|
|
+scene = new THREE.Scene();
|
|
|
+
|
|
|
+// 添加环境光
|
|
|
+const ambientLight = new THREE.AmbientLight(0xffffff, 1);
|
|
|
+
|
|
|
+// 初始化 Three.js 场景
|
|
|
+const initThree = () => {
|
|
|
+ scene.background = null;
|
|
|
+ // textureLoader.load('@/assets/OIP-C.jpg', (texture) => {
|
|
|
+ // // 将图片设置为场景的背景
|
|
|
+ // scene.background = texture;
|
|
|
+ // });
|
|
|
+ // 创建相机
|
|
|
+ camera = new THREE.PerspectiveCamera(
|
|
|
+ 75,
|
|
|
+ container.value.clientWidth / container.value.clientHeight,
|
|
|
+ 0.1,
|
|
|
+ 1000
|
|
|
+ );
|
|
|
+ camera.position.set(30, 20, 30);
|
|
|
+
|
|
|
+ // 创建渲染器
|
|
|
+ renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
|
+ renderer.setSize(container.value.clientWidth, container.value.clientHeight);
|
|
|
+ renderer.setClearAlpha(0);
|
|
|
+ // renderer.setClearColor(222842);
|
|
|
+ container.value.appendChild(renderer.domElement);
|
|
|
+
|
|
|
+ // 添加轨道控制器
|
|
|
+ controls = new OrbitControls(camera, renderer.domElement);
|
|
|
+ controls.enableDamping = true; // 启用阻尼效果
|
|
|
+ controls.dampingFactor = 0.05;
|
|
|
+
|
|
|
+ scene.add(ambientLight);
|
|
|
+
|
|
|
+ // 添加平行光
|
|
|
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
|
|
|
+ directionalLight.position.set(5, 5, 5).normalize();
|
|
|
+ scene.add(directionalLight);
|
|
|
+};
|
|
|
+
|
|
|
+// 存储模型数据
|
|
|
+let materialOne = reactive({})
|
|
|
+let materialTwo = reactive({})
|
|
|
+
|
|
|
+
|
|
|
+// 加载 GLB 模型
|
|
|
+const loadModel = () => {
|
|
|
+ const loader = new GLTFLoader();
|
|
|
+ loader.load('../../public/隧道1.glb', function (gltf){
|
|
|
+ let object = gltf.scene
|
|
|
+ materialOne = object.children[0].children[3].material
|
|
|
+ materialTwo = object.children[19].children[3].material
|
|
|
+ //gltf.scene获取gltf文件包含的模型数据
|
|
|
+ scene.add(gltf.scene)
|
|
|
+ }, function (xhr) {
|
|
|
+ // 加载进度回调
|
|
|
+ console.log((xhr.loaded / xhr.total * 100) + '% loaded');
|
|
|
+ }, function (error) {
|
|
|
+ // 加载错误回调
|
|
|
+ // console.error('An error happened', error);
|
|
|
+ }
|
|
|
+ )
|
|
|
+};
|
|
|
+
|
|
|
+// 动画循环
|
|
|
+const animate = () => {
|
|
|
+ requestAnimationFrame(animate);
|
|
|
+ controls.update(); // 更新控制器
|
|
|
+ renderer.render(scene, camera);
|
|
|
+};
|
|
|
+
|
|
|
+// 亮度调整
|
|
|
+const transparency = ref(0)
|
|
|
+const changeTransparency = (e) => {
|
|
|
+ console.log(e)
|
|
|
+}
|
|
|
+
|
|
|
+const transparencyTwo = ref(0)
|
|
|
+const changeTransparencyTwo = (e) => {
|
|
|
+ console.log(e)
|
|
|
+}
|
|
|
+
|
|
|
+// 灯光数据
|
|
|
+const lampData = reactive({})
|
|
|
+
|
|
|
+// 组件挂载时初始化
|
|
|
+onMounted(() => {
|
|
|
+ Object.assign(lampData, useScreen.controllerData)
|
|
|
+ initThree();
|
|
|
+ loadModel();
|
|
|
+ animate();
|
|
|
+});
|
|
|
+
|
|
|
+// 组件卸载时清理资源
|
|
|
+onUnmounted(() => {
|
|
|
+ if (renderer) {
|
|
|
+ renderer.dispose();
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="less">
|
|
|
+.horn {
|
|
|
+ position: absolute;
|
|
|
+ content: "";
|
|
|
+ width: 10px;
|
|
|
+ height: 10px;
|
|
|
+}
|
|
|
+.screen{
|
|
|
+ width: 100%;
|
|
|
+ height: 900px;
|
|
|
+ //background-image: url("@/assets/back.jpeg");
|
|
|
+ background-size:100% 100%;
|
|
|
+ background: #1d2b56 url("@/assets/line.png");
|
|
|
+
|
|
|
+ .titleImage {
|
|
|
+ width: 100%;
|
|
|
+ height: 70px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ position: relative;
|
|
|
+ .Heading{
|
|
|
+ position: absolute;
|
|
|
+ left: 42%;
|
|
|
+ top: 25%;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 1.7vw;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #0EFCFF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .coreBox{
|
|
|
+ width: 100%;
|
|
|
+ height: 800px;
|
|
|
+ margin-top: 20px;
|
|
|
+ position: relative;
|
|
|
+ .three-container {
|
|
|
+ z-index: 1;
|
|
|
+ position: absolute;
|
|
|
+ height: 800px;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ .formBox{
|
|
|
+ position: absolute;
|
|
|
+ right: 20px;
|
|
|
+ z-index:2;
|
|
|
+ }
|
|
|
+ .panel{
|
|
|
+ position: relative;
|
|
|
+ width: 300px;
|
|
|
+ height: 200px;
|
|
|
+ border: 1px solid rgba(25,186,139,0.17);
|
|
|
+ padding: 0 0.1875rem 0.5rem;
|
|
|
+ margin-bottom: 0.1875rem;
|
|
|
+ background: url(@/assets/line.png) rgba(255,255,255,0.04);
|
|
|
+ &::before{
|
|
|
+ .horn;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ border-left: 2px solid #02a6b5;
|
|
|
+ border-top: 2px solid #02a6b5;
|
|
|
+ }
|
|
|
+ &::after{
|
|
|
+ .horn;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ border-right: 2px solid #02a6b5;
|
|
|
+ border-top: 2px solid #02a6b5;
|
|
|
+ }
|
|
|
+ .panel-bottom{
|
|
|
+ &::before{
|
|
|
+ .horn;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ border-left: 2px solid #02a6b5;
|
|
|
+ border-bottom: 2px solid #02a6b5;
|
|
|
+ }
|
|
|
+ &::after{
|
|
|
+ .horn;
|
|
|
+ bottom: 0;
|
|
|
+ right: 0;
|
|
|
+ border-right: 2px solid #02a6b5;
|
|
|
+ border-bottom: 2px solid #02a6b5;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .panel-title{
|
|
|
+ position: absolute;
|
|
|
+ left: 110px;
|
|
|
+ top: 10px;
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #0EFCFF;
|
|
|
+ }
|
|
|
+ .panel-slider{
|
|
|
+ width: 250px;
|
|
|
+ position: absolute;
|
|
|
+ top: 60px;
|
|
|
+ left: 25px;
|
|
|
+ }
|
|
|
+ .panel-slider2{
|
|
|
+ width: 250px;
|
|
|
+ position: absolute;
|
|
|
+ top: 120px;
|
|
|
+ left: 25px;
|
|
|
+ }
|
|
|
+ .brightness{
|
|
|
+ width: 250px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* ::v-deep是vue3提供的深度选择器,.el-form-item__label是element-plus官方定义的类 */
|
|
|
+/deep/ .el-form-item__label{
|
|
|
+ color: white;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.el-slider__runway{ // 滑块的进度条颜色
|
|
|
+ background-color: #000000;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|