From 430b4048e7b60d5748276fad2beac8c7fe8adee7 Mon Sep 17 00:00:00 2001 From: hzz Date: Fri, 8 Nov 2024 17:05:21 +0800 Subject: [PATCH] update --- .../R_D_Environment/component/ThreeBG.vue | 99 ++++++++++++++++++- src/views/screen/R_D_Environment/index.vue | 8 +- 2 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/views/screen/R_D_Environment/component/ThreeBG.vue b/src/views/screen/R_D_Environment/component/ThreeBG.vue index fea9960..e45f7e6 100644 --- a/src/views/screen/R_D_Environment/component/ThreeBG.vue +++ b/src/views/screen/R_D_Environment/component/ThreeBG.vue @@ -7,13 +7,14 @@ import * as THREE from 'three'; import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'; import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; -import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer'; +import { CSS3DObject, CSS3DRenderer } from 'three/examples/jsm/Addons.js'; import { onMounted, ref } from 'vue'; const threeContainer = ref(null); -let camera, scene, renderer, model, controls; +let camera, scene, renderer, model, controls, cssRenderer; let width = 1920; let height = 1080; +let text = ref('标注1'); const init = () => { scene = new THREE.Scene(); // scene.background = new THREE.Color(null);//0x100c2a @@ -28,6 +29,7 @@ const init = () => { renderer.setSize(width, height); threeContainer.value.appendChild(renderer.domElement); + cssRenderer = initLabelRenderer(threeContainer.value); const objLoader = new OBJLoader(); let mtlLoader = new MTLLoader(); mtlLoader.load('/src/assets/obj/goats_R&D.mtl', function (materials) { @@ -47,7 +49,7 @@ const init = () => { cm.emissive = cm.color; cm.emissiveMap = cm.map; }); - + addMarks(text.value); scene.add(model); animate(); }); @@ -71,20 +73,109 @@ const init = () => { // } // ); - controls = new OrbitControls(camera, renderer.domElement); + controls = new OrbitControls(camera, cssRenderer.domElement); controls.enableDamping = true; animate(); }; +// 初始化标注渲染器 +const initLabelRenderer = boxElement => { + const labelRenderer = new CSS3DRenderer(); + labelRenderer.setSize(width, height); + labelRenderer.domElement.style.position = 'absolute'; + labelRenderer.domElement.style.top = 0; + boxElement.appendChild(labelRenderer.domElement); + return labelRenderer; +}; + + +function addMarks(text) { + //把传入的标注文字通过 canvas 修改为可以添加到场景中的 texture + const offScreenCanvas = document.createElement('canvas'); + const offScreenCtx = offScreenCanvas.getContext('2d'); + // 配置字体、大小、颜色等 + offScreenCtx.font = '16px 黑体'; + const txt = text; + const textWidth = offScreenCtx.measureText(txt).width; + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + if (ctx !== null) { + // pixelRatio: 像素密度 + canvas.width = (5 + textWidth + 5) * 2; + canvas.height = 18 * 2; + ctx.setTransform(2, 0, 0, 2, 0, 0); + ctx.font = '16px 黑体'; + ctx.fillStyle = '#fff'; //标注背景颜色 + ctx.fillRect(0, 0, 5 + textWidth + 5, 18); + ctx.fillStyle = '#000'; //标注字体颜色 + ctx.fillText(txt, 5, 16); + } + + // 将标注变成可以添加到场景中的 texture 对象 + const texture = new THREE.CanvasTexture(canvas); + + + var geometry2 = new THREE.BufferGeometry(); + var material = new THREE.LineBasicMaterial({ vertexColors: true }); + var color1 = new THREE.Color(0xffffff), color2 = new THREE.Color(0xffffff); + //定义第一条线 + var p3 = new THREE.Vector3(0, 50, 40); + var p4 = new THREE.Vector3(4, 23.5, 10); + const points = []; + points.push(p3); + points.push(p4); + // geometry2.vertices.push(p3); + // geometry2.vertices.push(p4); + // geometry2.colors.push(color1, color2); + geometry2.setFromPoints(points); + //把线条添加到场景中 + var line2 = new THREE.Line(geometry2, material, THREE.LinePieces); + scene.add(line2); + //定义第一个标签 + /**精灵图 */ + // var spriteMaterial2 = new THREE.SpriteMaterial({ map: texture, color: 0xffffff }); + // var sprite2 = new THREE.Sprite(spriteMaterial2); + // sprite2.position.set(0, 50, 40); + // sprite2.scale.set(15, 5, 0); + // scene.add(sprite2); + + + /** CSS3D */ + const label = new CSS3DObject(document.createElement('div')); + label.position.set(0, 50, 40); + label.scale.set(0.5, 0.5, 0.5); + label.element.style.backgroundColor = '#fff'; + label.element.innerText = text; + scene.add(label); + + + //定义标记点 + var radius = 0.5, segemnt = 16, rings = 16; + var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x9afc00 }); + var sphere101 = new THREE.Mesh(new THREE.SphereGeometry(radius, segemnt, rings), sphereMaterial); + sphere101.position.set(4, 23.5, 10); + scene.add(sphere101); + + // var group = new THREE.Object3D(); + // group.add(line2); + // group.add(sphere101); + // group.add(sprite2); + // scene.add(group); + + +} + const animate = () => { requestAnimationFrame(animate); renderer.render(scene, camera); + cssRenderer.render(scene, camera); controls.update(); }; onMounted(() => { init(); + window.addEventListener('resize', onWindowResize); }); diff --git a/src/views/screen/R_D_Environment/index.vue b/src/views/screen/R_D_Environment/index.vue index be825cd..bb4090b 100644 --- a/src/views/screen/R_D_Environment/index.vue +++ b/src/views/screen/R_D_Environment/index.vue @@ -55,7 +55,7 @@ - + @@ -100,6 +100,12 @@ let sensor_list = reactive([ value: 20, unit: 'mg/m³' }, + { + name:'粉尘', + component:SvgFenchen, + value: 20, + unit: 'mg/m³' + }, { name:'噪声', component:SvgZaosheng,