three.js如何实现简易3D机房?(三)显示信息弹框/标签

接上一篇:

three.js如何实现简易3D机房?(二)模型加载的过渡动画:http://t.csdnimg.cn/onbWY

目录

七、创建信息展示弹框

1.整体思路

(1)需求:

(2)思路:

(3)具体步骤:

创建3D渲染器

 弹框标签和样式

 创建3D弹框的公共函数

创建常亮(报警设备红色)信息框

创建随机(正常设备绿色)信息框


七、创建信息展示弹框

1.整体思路
(1)需求:

默认在模型加载完之后,报警设备的红色信息框持续展示;正常设备的绿色信息框,每3s轮换展示

(2)思路:

创建3D信息框的内容是相同的,只需要区分报警设备和正常设备两种情况即可,这里我是通过CSS3DObject来实现的

(3)具体步骤:
创建3D渲染器

在threeD/init.js文件中

// 引入CSS3渲染器CSS3DRenderer
import { CSS3DRenderer } from 'three/addons/renderers/CSS3DRenderer.js';
export let scene, camera, renderer, controls, css3DRenderer, width, height// 创建CSS3D渲染器
export const createCSS3DRenderer = (dom) => {// 创建一个CSS3渲染器CSS3DRenderercss3DRenderer = new CSS3DRenderer();css3DRenderer.setSize(180, 200);// HTML标签<div id="dialog"></div>外面父元素叠加到canvas画布上且重合css3DRenderer.domElement.style.position = 'absolute';css3DRenderer.domElement.style.top = '0';// css3DRenderer.domElement.style.left = '0px';//设置.pointerEvents=none,解决HTML元素标签对threejs canvas画布鼠标事件的遮挡css3DRenderer.domElement.style.pointerEvents = 'none';// threeDemoRef.value.appendChild(css3DRenderer.domElement);dom.appendChild(css3DRenderer.domElement);
};

 

 弹框标签和样式

以下内容都是在index.vue文件中,便于功能交互的实现,我没有单独封装,大项目可以结合情况自行抽离封装

在HTML中准备好需要用的弹框标签和样式(根据实际项目来),需要注意的是一定要用深度选择器 :deep(),不然不生效

	:deep(#myDialog) {font-size: 8px;.box-container {display: flex;flex-direction: column;align-items: center;justify-content: center;animation: moveUpDown 3s infinite;.title {font-family: Source Han Sans CN, Source Han Sans CN;font-weight: bold;color: #fff;}.label-text {font-family: Source Han Sans CN, Source Han Sans CN;color: #ccddff;.label-value-green {color: #5cdd2e;font-weight: bold;}.label-value-red {color: #ff4a4a;font-weight: bold;}}.tip-green {width: 80px;height: 40px;padding: 5px;display: flex;flex-direction: column;justify-content: center;background-color: rgba(22, 29, 38, 0.5);opacity: 0.9;border: 1px solid #329550;box-shadow: inset 0px 0px 15px 0px #329550;}.tip-red {width: 80px;height: 40px;padding: 5px;display: flex;flex-direction: column;justify-content: center;background-color: rgba(22, 29, 38, 0.5);opacity: 0.9;border: 1px solid #882c2c;box-shadow: inset 0px 0px 15px 0px #882c2c;}.line-green {width: 1px;height: 35px;background: linear-gradient(to bottom, rgba(28, 107, 51, 0.3), rgb(20, 195, 93), rgba(1, 165, 75, 0.89));}.line-red {width: 1px;height: 35px;background: linear-gradient(to bottom, rgba(123, 44, 28, 0.3), rgba(255, 82, 82, 1), rgba(255, 48, 48, 0.89));}}}// 动画
@keyframes moveUpDown {0% {transform: translateY(0);}50% {transform: translateY(8px);}100% {transform: translateY(0);}
}
 创建3D弹框的公共函数
const insertDialogHtml = (obj: any, item: any) => {// 多个标签-需要克隆复制一份const div: any = dialogRef.value.cloneNode();div.innerHTML = `<div class="box-container"><div class=${item.status == 0 ? 'tip-green' : 'tip-red'} ><div class="title">设备名称 : ${item.name}</div><div class="label-text">温度 :<span class="mr5" class=${item.tempState == '0' ? 'label-value-green' : 'label-value-red'}>${item.temperature}</span><span class=${item.tempState == '0' ? 'label-value-green' : 'label-value-red'}>${item.tempState == '0' ? '正常' : '报警'}</span></div><div class="label-text">漏水 :<span class="mr5" class=${item.leakageState == '0' ? 'label-value-green' : 'label-value-red'}>${item.leakage}</span><span class=${item.leakageState == '0' ? 'label-value-green' : 'label-value-red'}>${item.leakageState == '0' ? '正常' : '报警'}</span></div></div><div class=${item.status == 0 ? 'line-green' : 'line-red'}></div></div>`;// HTML元素转化为threejs的CSS3对象const dialog = new CSS3DObject(div);//避免标签遮挡canvas鼠标事件div.style.pointerEvents = 'none';dialog.name = obj.name + 'dialog';dialog.scale.set(0.1, 0.1, 1);dialog.position.set(0, 6, 0);// 判断是否需要旋转// const nameList = ['AU04', 'AU07', 'AU08', 'AU09', 'AU10', 'AU11', 'AU16', 'AU17', 'AU18', 'AU19', 'AU20'];// if (nameList.includes(obj.name)) {// 	dialog.rotation.set(0, -Math.PI / 2, 0);// }obj.add(dialog);
};

准备好需要用的变量,为了方便展示,我这里简单写了一些假数据,实际需要从后端接口获取

const state: any = reactive({loading: true, // 是否开启加载动画progress: 0, // 模型加载进度randomObject: null, // 随机正常设备selectedDevice: null, // 点击选中的设备intervalId: null, // 定时器allDeviceObjList: [], // 所有设备obj// 报警设备alarmInfo: [{name: 'AU02',temperature: '35℃', // 温度tempState: '1', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '1', // 漏水报警状态 0正常 1报警status: 1,},{name: 'AU08',temperature: '38℃', // 温度tempState: '1', // 温度报警状态 0正常 1报警leakage: '60', // 漏水leakageState: '1', // 漏水报警状态 0正常 1报警status: 1,},{name: 'AU18',temperature: '40℃', // 温度tempState: '1', // 温度报警状态 0正常 1报警leakage: '72', // 漏水leakageState: '1', // 漏水报警状态 0正常 1报警status: 1,},],// 正常设备normalInfo: [{name: 'AU01',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU03',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU04',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU05',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU06',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU07',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU09',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU10',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU11',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU12',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU13',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU14',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU15',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU16',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU17',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU19',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU20',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU21',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},{name: 'AU22',temperature: '35℃', // 温度tempState: '0', // 温度报警状态 0正常 1报警leakage: '58', // 漏水leakageState: '0', // 漏水报警状态 0正常 1报警status: 0,},],
});
创建常亮(报警设备红色)信息框
import { createCSS3DRenderer } from './component/threeD/init.js';onMounted(async () => {init(threeDemoRef.value);importModel();createControls();initLight();createCSS3DRenderer(threeDemoRef.value);watchDom(threeDemoRef.value);renderResize(threeDemoRef.value);renderLoop();
});const createAlarmDialog = () => {state.allDeviceObjList = [];model.traverse((obj: any) => {// 筛选出报警设备if (obj.name.includes('AU')) {state.allDeviceObjList.push(obj);// 报警数据持续展示state.alarmInfo.forEach((item: any) => {if (item.name == obj.name) {insertDialogHtml(obj, item);}});}});
};
创建随机(正常设备绿色)信息框
const createNormalDialog = () => {// 过滤出正常设备的objconst filteredEquipment = state.allDeviceObjList.filter((item: any) => !['AU02', 'AU08', 'AU18'].includes(item.name));let index = state.normalInfo.length - 1;state.intervalId = setInterval(() => {// 移除上一个dialogclearDialog();index = index == state.normalInfo.length - 1 ? 0 : ++index;const randomInfo = state.normalInfo[index];const randomObject = filteredEquipment.filter((item: any) => item.name == randomInfo.name);state.randomObject = randomObject[0];insertDialogHtml(state.randomObject, randomInfo);}, 3000);
};// 清除前一个随机框
const clearDialog = () => {if (state.randomObject) {const currentRandomObject = model.getObjectByName(state.randomObject.name + 'dialog');currentRandomObject ? currentRandomObject.parent.remove(currentRandomObject) : '';state.randomObject = null;}
};

在模型加载函数中调用

// 创建3D弹框
const create3DDialog = () => {createAlarmDialog();createNormalDialog();
};

接下一篇:

three.js如何实现简易3D机房?(四)点击事件:http://t.csdnimg.cn/Fzpxk 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726578.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网康科技 NS-ASG 应用安全网关 SQL注入漏洞复现(CVE-2024-2022)

0x01 产品简介 网康科技的NS-ASG应用安全网关是一款软硬件一体化的产品,集成了SSL和IPSec,旨在保障业务访问的安全性,适配所有移动终端,提供多种链路均衡和选择技术,支持多种认证方式灵活组合,以及内置短信认证、LDAP令牌、USB KEY等多达13种认证方式。 0x02 漏洞概述 …

C语言第三十六弹---文件操作(中)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 文件操作 1、文件的顺序读写 1.1、顺序读写函数介绍 1.1.1、fgetc 与 fputc 1.1.2、fgets 与 fputs 1.1.3、fscanf 与 fprintf 1.1.4、fread 与 fwrite 1.…

全志D1s开发板裸机开发之坏境搭建

环境搭建 开发板介绍 张天飞老师编写的《RISC-V体系结构编程与实践》&#xff0c;里面的源码是基于 QEMU 模拟器的&#xff0c;可以认为它是一款虚拟的开发板。如果需要在真实开发板上学习&#xff0c;可以使用百问网的 DongshanPI-D1S 开发板。 DongshanPI-D1S 是百问网推出…

Python web自动化测试 —— 文件上传!

​文件上传三种方式&#xff1a; &#xff08;一&#xff09;查看元素标签&#xff0c;如果是input&#xff0c;则可以参照文本框输入的形式进行文件上传 方法&#xff1a;和用户输入是一样的&#xff0c;使用send_keys 步骤&#xff1a;1、找到定位元素&#xff0c;2&#…

Git分支操作

Git分支操作 理解分支查看当前分支git branch 查看有几个分支git branch 新分支的名字 创建新分支git checkout -b 分支名 直接创建并切换到该分支下 切换分支git checkout 分支名 切换到指定分支 合并分支git merge 分支名 合并指定名字的分支 删除分支git branch -d 分支 删…

Linux:kubernetes(k8s)探针的简介(7)

相当于我们用于监控容器的一个东西&#xff0c;通过给我们的不同探针来判断容器内的状态情况&#xff0c;实现故障的一个自动恢复。 我们在上一章的yaml文件中写入了一个这个东西 那么他什么情况下重启&#xff0c;就是通过探针进行一个监控&#xff0c;加入监控某一个端口&…

云原生(一)、linux快速上手

Linux是一种开源的Unix-like操作系统内核。它是由Linus Torvalds于1991年首次发布&#xff0c;其后经过全球的自由软件社区的持续开发和改进。Linux内核是操作系统的核心部分&#xff0c;但通常与GNU项目合作&#xff0c;以形成完整的操作系统&#xff0c;被称为Linux发行版&am…

ROS从入门到精通4-2:Docker安装ROS、可视化仿真与终端复用

目录 0 专栏介绍1 Docker安装ROS2 Docker可视化仿真2.1 显示配置2.2 启动容器 3 终端复用工具3.1 session操作3.2 window操作3.3 pane操作3.4 其他操作 0 专栏介绍 本专栏旨在通过对ROS的系统学习&#xff0c;掌握ROS底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS…

机器学习项目的流程:从数据到部署

目录 前言1 数据收集1.1 任务定义与数据需求明确1.2 数据采集与清洗 2 模型训练2.1 数据预处理2.2 选择适当的模型2.3 模型训练与调优2.4 模型评估 3 模型部署3.1 部署环境准备3.2 模型集成3.3 测试和优化 4 模型维护和更新4.1 模型性能监测4.2 数据漂移处理4.3 定期更新模型 结…

Unity 整体界面淡入淡出效果

在Unity中&#xff0c;如果我们要实现控制多个组件同时淡出&#xff0c;同时淡入的效果&#xff0c;可以使用DOTween插件实现。 如图&#xff0c;一个页面中带有背景&#xff0c;一张图片&#xff0c;一个文本&#xff0c;一个滑动条。 要实现以上界面的整体淡入淡出&#xff…

PolarDB for PostgreSQL-概述

阿里云数据库的概述 本篇罗列了一些知识点和结构。 日志 2. 同步复制&#xff1a;下降20% 异步复制&#xff1a;数据丢失风险&#xff0c; 部署 1.示例&#xff1a; vim polarx.toml 1.测试主库和备库数据一致性 备库是否一致性读 一个节点荡掉&#xff0c;提供服务。 GMS CN…

【DAY08 软考中级备考笔记】机组:计算机组成和数据转换

机组&#xff1a;计算机组成和数据转换 3月2日 – 天气&#xff1a;晴 1. 计算机的基本组成结构 计算机的硬件由运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入和输出设备组成其中&#xff0c;控制器和运算器成为CPU控制器又分为了内部存储器和外部存储器。内部…

应用监控 eBPF 版:实现 Golang 微服务的无侵入应用监控

作者&#xff1a;古琦 在现代软件架构中&#xff0c;微服务已成为构建可扩展和灵活应用程序的流行方式。每个微服务负责应用程序的一部分功能&#xff0c;它们共同工作以提供完整的服务。由于微服务架构的分散特性&#xff0c;监控变得至关重要&#xff0c;有效的微服务监控是…

AI预测福彩3D第4弹【2024年3月7日预测】

经过前面几次的预测&#xff0c;7码命中率已经有了明显提高&#xff0c;今天&#xff0c;继续咱们的预测。 老规矩&#xff0c;先给各位展示下百十个的神经网络蒙特卡洛统计频次图及部分号码的冷温热走势图。 最终&#xff0c;经过研判分析&#xff0c;2024年3月7日福彩3D的七…

sql 注入 之sqli-labs/less-5 双注入,也称:报错注入

该关卡返回正确或者错误页面,还有错误的代码&#xff0c;所以可以使用报错注入。报错注入的方式&#xff1a; updatexml 函数注入&#xff1a; mysql5.1.5 版本以上支持该函数&#xff0c;返回数据限制32位 模板&#xff1a;select * from user where id1 and (updatexml(&q…

一次一对一服务引起的沉思和笑话(微信号Stefan)

前情提要 客户需求&#xff1a; 分析页面代码和接口请求协议和参数需求&#xff0c;将人工下载视频怎么获得最终的视频链接&#xff0c;这一逻辑清晰的展示并讲解清除。我询问了是否需要成品爬虫&#xff0c;他说代码他自己能搞定。 我给的价格选择&#xff1a; 第一种、首…

超好用的golang工具分享

go-callvis-代码调用关系的可视化工具 go-callvis是一个代码调用关系的可视化工具&#xff0c;它可以帮助我们了解指定项目代码的结构&#xff0c;以达到更快的理解代码意图的目的。 工具使用简单&#xff0c;步骤如下&#xff1a; // 1. 安装 git clone https://github.com…

蓝桥杯练习系统(算法训练)ALGO-983 最大获利

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 Chakra是一位年轻有为的企业家&#xff0c;最近他在进军餐饮行业。他在各地开拓市场&#xff0c;共买下了N个饭店。在初期的…

python 爬虫爬取知乎LOL图片(亲测)

获取信息 访问url后按f12调试 点击network 定位图片信息&#xff1a; 可以看到&#xff0c;每个图片的名字和下载地址在标红处&#xff0c;示例如下&#xff1a; data-actualsrc“https://pic4.zhimg.com/v2-1681ff26afbd5f92aa5790b4dee6a63f_b.jpg” 现在就是requests访问…

Linux之线程概念

目录 一、细粒度划分 1、堆区细粒度划分 2、物理内存和可执行程序细粒度划分 3、虚拟地址到物理地址的转化 二、线程的概念 1、基本概念 2、线程的优点 3、线程的缺点 4、线程异常 5、线程用途 三、Linux下的进程和线程 一、细粒度划分 1、堆区细粒度划分 在语言…