当前位置: 首页 > news >正文

Threejs 实现 VR 看房完结

效果:

threejs 3d Vr 看房

gitee 地址:

threejs-3d-map: 1、threejs 实现3d 地图效果链接:https://blog.csdn.net/qq_57952018/article/details/1430539902、threejs 实现 vr 看房

主要代码:

src/views/PanoramicView/index.vue

<script setup>
import {computed, onMounted, onUnmounted, reactive, ref} from 'vue'
import * as THREE from 'three'
// 引入轨道控制器扩展库OrbitControls.js
import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
import {rooms} from './data.js';
import TWEEN from 'three/examples/jsm/libs/tween.module.js';
import Animations from "@/utils/animations.js";let animationId
let tick;
const data = reactive({renderer: null,camera: null,scene: null,controls: null,cameraZAxis: 2,currentRoom: 'living-room',
});// 获取交互点的信息
const interactivePoints = computed(() => {const res = [];rooms.forEach((room) => {if (room.interactivePoints && room.interactivePoints.length > 0) {room.interactivePoints.forEach((point) => {point = {room: room.key,...point,};res.push(point);});}});return res;
});const container = ref(null)
// 拿到页面的宽高
const width = window.innerWidth, height = window.innerHeight;// 创建场景
let scene = new THREE.Scene();
// 将背景颜色设置为白色
scene.background = new THREE.Color("#000000");
data.scene = scene;// 创建相机
let camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 1000);
// 设置相机位置
camera.position.z = data.cameraZAxis;
data.camera = camera;// // 辅助线 AxesHelper
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);// 初始化渲染器
let renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
data.renderer = renderer;// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
//阻尼 更真实
controls.enableDamping = true
// controls.enablePan = false;
// 缩放限制
controls.maxDistance = 12;
data.controls = controls;// 监听浏览器窗口的大小变化 重新调整渲染器的大小
window.addEventListener('resize', onWindowResize);// 更新渲染器大小以匹配新的浏览器窗口尺寸
function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);
}const textLoader = new THREE.TextureLoader();// 加载每个房间 (客厅、卧室、书房)
const createRoom = (name, position, map) => {// 创建球状 为了做全景const geometry = new THREE.SphereGeometry(16, 256, 256);// z轴的-1 代表将外面的体图放在内侧geometry.scale(1, 1, -1);const material = new THREE.MeshBasicMaterial({// 加载纹理贴图map: textLoader.load(map),side: THREE.DoubleSide,});const room = new THREE.Mesh(geometry, material);room.name = name;room.position.set(position.x, position.y, position.z);room.rotation.y = Math.PI / 2;scene.add(room);return room;
}const initRoom = () => {
// 创建网格对象rooms.map((item) => {return createRoom(item.key, item.position, item.map);});// 添加交互点const raycaster = new THREE.Raycaster();// 室内悬浮标记物const _points = interactivePoints.value.map((item, index) => ({...item,element: document.querySelector(`.point-${index}`),}));// 动画tick = () => {if (renderer) {for (const point of _points) {// 获取2D屏幕位置const screenPosition = point.position.clone();const pos = screenPosition.project(camera);raycaster.setFromCamera(screenPosition, camera);const intersects = raycaster.intersectObjects(scene.children, true);if (intersects.length === 0) {// 未找到相交点,显示point.element.classList.add('visible');} else {// 找到相交点// 获取相交点的距离和点的距离const intersectionDistance = intersects[0].distance;const pointDistance = point.position.distanceTo(camera.position);// 相交点距离比点距离近,隐藏;相交点距离比点距离远,显示intersectionDistance < pointDistance? point.element.classList.remove('visible'): point.element.classList.add('visible');}pos.z > 1? point.element.classList.remove('visible'): point.element.classList.add('visible');const translateX = screenPosition.x * window.innerWidth * 0.5;const translateY = -screenPosition.y * window.innerHeight * 0.5;point.element.style.transform = `translateX(${translateX}px) translateY(${translateY}px)`;}}controls && controls.update();TWEEN && TWEEN.update();// 更新渲染器renderer && renderer.render(scene, camera);// 页面重绘时调用自身window.requestAnimationFrame(tick);};tick();
}// 点击交互点
const handleReactivePointClick = (point) => {window.alert('你点击了' + point.value)
};// 点击切换场景
const handleSwitchButtonClick = async (key) => {const room = rooms.filter((item) => item.key === key)[0];if (data.camera) {const x = room.position.x;const y = room.position.y;const z = room.position.z;// 加载切换动画Animations.animateCamera(data.camera, data.controls, { x, y, z: data.cameraZAxis }, { x, y, z }, 1600, () => {});data.controls.update();}await sleep(1600);data.currentRoom = room.key;
};const sleep = (duration) => new Promise((resolve) => {setTimeout(resolve, duration);
});// 渲染页面
const render = () => {if (!renderer) return// 将场景(scene)和摄像机(camera 加入进来)renderer.render(scene, camera)// 渲染下一帧的时候会调用render函数animationId = requestAnimationFrame(render)controls.update()
}const initLight = () => {// 基本光源const ambLight = new THREE.AmbientLight('#ffffff', 0.3)/*** 设置聚光灯相关的的属性*/const spotLight = new THREE.SpotLight(0xFFFFFF); // 聚光灯spotLight.position.set(40, 200, 10);spotLight.castShadow = true; // 只有该属性为true时,该点光源允许产生阴影,并且下列属性可用scene.add(ambLight, spotLight); // 向场景中添加光源
}onMounted(() => {// 添加物体到场景initRoom()// 渲染// render()// 设置环境光initLight()// 将渲染加入到页面上container.value.appendChild(renderer.domElement);
})
onUnmounted(() => {window.removeEventListener('resize', onWindowResize)// 销毁 Three.js 实例,清理内存if (renderer) {if (renderer.domElement && renderer.domElement.parentNode) {renderer.domElement.parentNode.removeChild(renderer.domElement);}renderer.dispose();renderer = null;}if (data.scene) {data.scene.traverse((object) => {if (object.geometry) object.geometry.dispose();if (object.material) {if (Array.isArray(object.material)) {object.material.forEach((material) => material.dispose());} else {object.material.dispose();}}});data.scene = null;}if (data.controls) {data.controls = null}data.camera = null;
})
</script><template><div class="home"><div ref="container"></div><div class="vr"><span class="box"><i class="icon"></i><b class="text">全景漫游</b></span></div><!-- 场景切换点 --><div class="switch"><span class="button" v-for="(room, index) in rooms" :key="index" @click="handleSwitchButtonClick(room.key)"v-show="room.key !== data.currentRoom"><b class="text">{{ room.name }}</b><i class="icon"></i></span></div><!-- 交互点 --><divclass="point"v-for="(point, index) in interactivePoints":key="index":class="[`point-${index}`, `point-${point.key}`]"@click="handleReactivePointClick(point)"v-show="point.room === data.currentRoom"><div class="label" :class="[`label-${index}`, `label-${point.key}`]"><label class="label-tips"><div class="cover"><iclass="icon":style="{background: `url(${point.cover}) no-repeat center`,'background-size': 'contain',}"></i></div><div class="info"><p class="p1">{{ point.value }}</p><p class="p2">{{ point.description }}</p></div></label></div></div></div>
</template><style lang="css" scoped>
.home {position: relative;.vr {position: fixed;top: 0;left: 0;z-index: 11;-webkit-animation: slideInLeft 1s .15s;animation: slideInLeft 1s .15s;-webkit-animation-fill-mode: both;animation-fill-mode: both;.box {background: rgba(0, 0, 0, .3);-webkit-backdrop-filter: blur(8px);backdrop-filter: blur(8px);display: flex;align-items: center;justify-content: space-around;overflow: hidden;padding: 4px 20px;border-radius: 0 0 16px 0;border: 1px groove rgba(255, 255, 255, .3);border-top: none;border-left: none;box-shadow: 0 1px 4px rgba(0, 0, 0, .1);.icon {display: inline-block;height: 64px;width: 64px;background: url('@/assets/images/home/vr.png') no-repeat center;background-size: contain;margin-right: 12px;}.text {font-size: 24px;color: #ffffff;display: inline-block;font-weight: 500;}}}.switch {position: fixed;right: 24px;top: 40%;z-index: 11;-webkit-animation: slideInRight 1s .3s;animation: slideInRight 1s .3s;-webkit-animation-fill-mode: both;animation-fill-mode: both;.button {display: block;background: rgba(27, 25, 24, .5);border-radius: 12px;display: flex;align-items: center;padding: 12px 8px 12px 24px;-webkit-backdrop-filter: blur(4px);-moz-backdrop-filter: blur(4px);backdrop-filter: blur(4px);cursor: pointer;transition: all .25s ease-in-out;.text{color: rgba(255, 255, 255, 1);font-size: 24px;font-weight: 600;}&:not(last-child) {margin-bottom: 48px;}.icon {display: inline-block;height: 30px;width: 30px;background: url('@/assets/images/home/icon_arrow.png') no-repeat center;background-size: 100% 100%;transform: rotate(180deg);margin-left: 8px;}&:hover {background: rgba(27, 25, 24, .2);box-shadow: 1px 1px 2px rgba(0, 0, 0, .2);}}}.point {position: fixed;top: 50%;left: 50%;z-index: 10;.label {position: absolute;top: -16px;left: -16px;width: 20px;height: 20px;border-radius: 50%;background: rgba(255, 255, 255, 1);text-align: center;line-height: 32px;font-weight: 100;font-size: 14px;cursor: help;transform: scale(0, 0);transition: all 0.3s ease-in-out;backdrop-filter: blur(4px);&::before, &::after {display: inline-block;content: '';background: rgba(255, 255, 255, 1);;height: 100%;width: 100%;border-radius: 50%;position: absolute;left: 50%;top: 50%;margin-left: -10px;margin-top: -10px;}&::before {animation: bounce-wave 1.5s infinite;}&::after {animation: bounce-wave 1.5s -0.4s infinite;}.label-tips {height: 88px;width: 200px;overflow: hidden;position: absolute;top: -32px;right: -220px;font-size: 32px;background: rgba(255, 255, 255, .6);border: 1px groove rgba(255, 255, 255, .5);-webkit-backdrop-filter: blur(4px);-moz-backdrop-filter: blur(4px);backdrop-filter: blur(4px);border-radius: 16px;display: flex;justify-content: space-between;align-content: center;box-shadow: 1px 1px 2px rgba(0, 0, 0, .1);.cover {width: 80px;height: 100%;.icon {display: inline-block;height: 100%;width: 100%;filter: drop-shadow(1px 1px 4px rgba(0, 0, 0, .1));}}.info {width: calc(100% - 80px);height: 100%;overflow: hidden;padding-left: 12px;p {overflow: hidden;text-overflow: ellipsis;text-align: left;text-shadow: 0 1px 1px rgba(0, 0, 0, .1);&.p1 {font-size: 24px;color: #1D1F24;font-weight: 800;margin: 12px 0 2px;}&.p2 {font-size: 18px;color: #00aa47;font-weight: 500;}}}}&.label-sofa {.label-tips {left: -220px;flex-direction: row-reverse;.info {padding: 0 12px 0 0;p {text-align: right}}}}}.text {position: absolute;top: 30px;left: -120px;width: 200px;padding: 20px;border-radius: 4px;background: rgba(0, 0, 0, .6);border: 1px solid #ffffff;color: #ffffff;line-height: 1.3em;font-weight: 100;font-size: 14px;opacity: 0;transition: opacity 0.3s;pointer-events: none;text-align: justify;text-align-last: left;}&:hover .text {opacity: 1;}&.visible .label {transform: scale(1, 1)}}
}.animate-point-wave::before {content: '';animation: bounce-wave 1.5s infinite;
}
.animate-point-wave::after {content: '';animation: bounce-wave 1.5s -0.4s infinite;
}@keyframes bounce-wave {0% {transform: scale(1);opacity: 1;}100% {transform: scale(3.6);opacity: 0;}
}
</style>

src/views/PanoramicView/data.js

/* eslint-disable */
import { Vector3 } from 'three';export const rooms = [{name: '客厅',key: 'living-room',map: new URL('@/assets/images/map/map_living_room.jpg', import.meta.url).href,showSwitch: true,position: new Vector3(0, 0, 0),interactivePoints: [{key: 'tv',value: '电视机',description: '智能电视',cover: new URL('@/assets/images/home/cover_living_room_tv.png', import.meta.url).href,position: new Vector3(-6, 2, -8),},{key: 'fridge',value: '冰箱',description: '豪华冰箱',cover: new URL('@/assets/images/home/cover_living_room_fridge.png', import.meta.url).href,position: new Vector3(-12, 4, 9),},{key: 'sofa',value: '沙发',description: '舒适沙发',cover: new URL('@/assets/images/home/cover_living_room_sofa.png', import.meta.url).href,position: new Vector3(6, 0, -8),},],},{name: '卧室',key: 'bed-room',map: new URL('@/assets/images/map/map_bed_room.jpg', import.meta.url).href,showSwitch: true,position: new Vector3(-32, 0, 0),interactivePoints: [{key: 'bed',value: '床',description: '温暖的床',cover: new URL('@/assets/images/home/cover_bed_room_bed.png', import.meta.url).href,position: new Vector3(-38, 2, -14),},],},{name: '书房',key: 'study-room',map: new URL('@/assets/images/map/map_study_room.jpg', import.meta.url).href,showSwitch: true,position: new Vector3(32, 0, 0),interactivePoints: [{key: 'art',value: '艺术品',description: '绝版作品',cover: new URL('@/assets/images/home/cover_study_room_art.png', import.meta.url).href,position: new Vector3(42, 6, -8),},]},
];

部分内容借鉴:

https://juejin.cn/post/7215268204062490679

相关文章:

Threejs 实现 VR 看房完结

效果&#xff1a; threejs 3d Vr 看房 gitee 地址&#xff1a; threejs-3d-map: 1、threejs 实现3d 地图效果链接&#xff1a;https://blog.csdn.net/qq_57952018/article/details/1430539902、threejs 实现 vr 看房 主要代码&#xff1a; src/views/PanoramicView/index.vu…...

找出目标值在数组中的开始和结束位置(二分查找)

给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示例 1&#xff1a…...

VSCode进阶之路

VSCode进阶之路&#xff1a;从入门到高效率开发 &#x1f680; Hey&#xff0c;朋友们好&#xff01;还在为VSCode的海量功能感到眼花缭乱吗&#xff1f;咱们一起来解锁VSCode的超神技能吧&#xff01; 开篇碎碎念 &#x1f3af; 第一次用VSCode时&#xff0c;就像个闯入魔法世…...

leetcode-21-合并两个有序链表

题解&#xff1a; 1、初始化哑节点dum 2、 3、 代码&#xff1a; 参考&#xff1a;leetcode-88-合并两个有序数组...

SSM项目部署到服务器

将SSM&#xff08;Spring Spring MVC MyBatis&#xff09;项目部署到服务器上&#xff0c;通常需要以下步骤&#xff1a; 打包项目 生成一个WAR文件&#xff0c;通常位于target目录下 配置Tomcat&#xff1a; 将生成的WAR文件复制到Tomcat的webapps目录下。 配置conf/se…...

【Linux】网络编程:初识协议,序列化与反序列化——基于json串实现,网络通信计算器中简单协议的实现、手写序列化与反序列化

目录 一、什么是协议&#xff1f; 二、为什么需要有协议呢&#xff1f; 三、协议的应用 四、序列化与反序列化的引入 什么是序列化和反序列化&#xff1f; 为什么需要序列化和反序列化&#xff1f; 五、序列化推荐格式之一&#xff1a;JSON介绍 六、网络版计算器编程逻…...

Educational Codeforces Round 171 (Rated for Div. 2)(A~D) 题解

Problem - A - Codeforces--PerpendicularSegments 思路:正方形对角线最长,并且相互垂直.直接输出即可. int x,y,k; void solve(){ //Acin>>x>>y>>k;int resmin(x,y);cout<<"0 0"<<" "<<res<<" &q…...

【教程】Git 标准工作流

目录 前言建仓&#xff0c;拉仓&#xff0c;关联仓库修改代码更新本地仓库&#xff0c;并解决冲突提交代码&#xff0c;合入代码其他常用 Git 工作流删除本地仓库和远程仓库中的文件日志打印commit 相关 前言 Git 是日常开发中常用的版本控制工具&#xff0c;配合代码托管仓库…...

Nico,从零开始干掉Appium,移动端自动化测试框架实现

开头先让我碎碎念一波~去年差不多时间发布了一篇《 UiAutomator Nico&#xff0c;一个基于纯 adb 命令实现的安卓自动化测试框》&#xff08;https://testerhome.com/topics/37042&#xff09;&#xff0c; 由于种种原因 (详见此篇帖子) 当时选择了用纯 adb 命令来实现安卓自动…...

PHP合成图片,生成海报图,poster-editor使用说明

之前写过一篇使用Grafika插件生成海报图的文章&#xff0c;但是当我再次使用时&#xff0c;却发生了错误&#xff0c;回看Grafika文档&#xff0c;发现很久没更新了&#xff0c;不兼容新版的GD&#xff0c;所以改用了intervention/image插件来生成海报图。 但是后来需要对海报…...

微信小程序 - 数组 push / unshift 追加后数组返回内容为数字(数组添加后打印结果为 Number 数值类型)

前言 假设一个空数组,通过 push 方法追加了一个项,控制台打印的结果竟然是 Number 数值。 例如,以下微信小程序代码: // 源数组 var arr = [] // 追加数据 var tem = arr.push(数据)...

1、DevEco Studio 鸿蒙仓颉应用创建

1. 仓颉鸿蒙应用简介 因为仓颉是静态编译型语言&#xff0c;使用仓颉开发的应用执行效率更高。而且主打全场景&#xff0c;后续可并入仓颉生态&#xff0c;其和ArkTS都是基于ArkUI进行开发&#xff0c;最大的区别是typescript和仓颉语法间的差异。 2. 应用创建 前置条件&…...

从头开始学PHP之面向对象

首先介绍下最近情况&#xff0c;因为最近入职了且通勤距离较远&#xff0c;导致精力不够了&#xff0c;而且我发现&#xff0c;人一旦上了班&#xff0c;下班之后就不想再进行任何脑力劳动了&#xff08;对大部分牛马来说&#xff0c;精英除外&#xff09;。 话不多说进入今天的…...

C++ | Leetcode C++题解之第519题随机翻转矩阵

题目&#xff1a; 题解&#xff1a; class Solution { public:Solution(int m, int n) {this->m m;this->n n;this->total m * n;srand(time(nullptr));}vector<int> flip() {int x rand() % total;vector<int> ans;total--; // 查找位置 x 对应的…...

vrrp和mstp区别

思路 vrrp是用来虚拟网关&#xff0c;噢&#xff0c;是虚拟一条虚拟网关 优先级&#xff0c;priority越大越优先&#xff0c;优先级相同&#xff0c;哪个的路由器的vrrp先起来&#xff0c;谁就是主 mstp是快速生成树协议&#xff0c;防止环路用的 优先级越小越优先 华为命令…...

前端页面整屏滚动fullpage.js简单使用

官网CSS,JS地址 fullPage.js/dist/fullpage.min.js at master alvarotrigo/fullPage.js GitHub fullPage.js/dist/fullpage.min.css at master alvarotrigo/fullPage.js GitHub <!DOCTYPE html> <html lang"en"><head><meta charset"…...

JQuery基本介绍和使用方法

JQuery基本介绍和使用方法 W3C 标准给我们提供了⼀系列的函数, 让我们可以操作: ⽹⻚内容⽹⻚结构⽹⻚样式 但是原⽣的JavaScript提供的API操作DOM元素时, 代码⽐较繁琐, 冗⻓. 我们可以使⽤JQuery来操作⻚⾯对象. jQuery是⼀个快速、简洁且功能丰富的JavaScript框架, 于20…...

【案例】旗帜飘动

开发平台&#xff1a;Unity 6.0 开发工具&#xff1a;Shader Graph 参考视频&#xff1a;Unity Shader Graph 旗帜飘动特效   一、效果图 二、Shader Graph 路线图 三、案例分析 核心思路&#xff1a;顶点偏移计算 与 顶点偏移忽略 3.1 纹理偏移 视觉上让旗帜保持动态飘动&a…...

大模型思维链推理的综述:进展、前沿和未来

转自公众号AIRoobt A Survey of Chain of Thought Reasoning: Advances, Frontiers and Future 思维链推理的综述&#xff1a;进展、前沿和未来 摘要&#xff1a;思维链推理&#xff0c;作为人类智能的基本认知过程&#xff0c;在人工智能和自然语言处理领域引起了极大的关注…...

项目一:使用 Spring + SpringMVC + Mybatis + lombok 实现网络五子棋

一&#xff1a;系统展示: 二&#xff1a;约定前后端接口 2.1 登陆 登陆请求&#xff1a; GET /login HTTP/1.1 Content-Type: application/x-www-form-urlencodedusernamezhangsan&password123登陆响应&#xff1a; 正常对象&#xff1a;正常对象会在数据库中存储&…...

openEuler 系统中 Samba 文件共享服务器管理(windows、linux文件共享操作方法)

一、Samba 简介 Samba 是在 Linux 和 Unix 系统上实现 SMB/CIFS 协议的一个免费软件&#xff0c;使得这些系统可以与 Windows 系统进行文件和打印机共享。通过 Samba&#xff0c;可以将 openEuler 系统配置为文件服务器&#xff0c;让 Windows、Linux 和其他支持 SMB/CIFS 协议…...

使用 Elasticsearch 进行语义搜索

Elasticsearch 是一款功能强大的开源搜索引擎&#xff0c;可用于全文搜索、分析和数据可视化。传统上&#xff0c;Elasticsearch 以其执行基于关键字/词汇的搜索的能力而闻名&#xff0c;其中文档基于精确或部分关键字匹配进行匹配。然而&#xff0c;Elasticsearch 已经发展到支…...

软考:中间件

中间件 中间件是一类位于操作系统软件与用户应用软件之间的计算机软件&#xff0c;它包括一组服务&#xff0c;以便于运行在一台或多台机器上的多个软件通过网络进行交互。 中间件的主要功能包括通信支持和应用支持。 通信支持为应用软件提供平台化的运行环境&#xff0c;屏蔽…...

银行家算法(Banker’s Algorithm)

银行家算法&#xff08;Banker’s Algorithm&#xff09;是计算机操作系统中一种避免死锁发生的著名算法。该算法由艾兹格迪杰斯特拉&#xff08;Edsger Dijkstra&#xff09;在1965年为T.H.E系统设计&#xff0c;其核心理念基于银行借贷系统的分配策略&#xff0c;以确保系统的…...

用魔数严谨的判别文件类型:杜绝上传风险

在文件处理和管理中&#xff0c;确定文件的类型是一个常见的需求。虽然文件扩展名可以提供一些信息&#xff0c;但并不总是可靠的。魔数&#xff08;Magic Numbers&#xff09;是一种更为准确的方法&#xff0c;通过检查文件开头的特定字节序列来识别文件类型。本文将介绍如何在…...

【MacOS实操】如何基于SSH连接远程linux服务器

MacOS上远程连接linux服务器&#xff0c;可以使用ssh命令pem秘钥文件连接。 一、准备pem秘钥文件 如果已经有pem文件&#xff0c;则跳过这一步。如果手上有ppk文件&#xff0c;那么需要先转换为pem文件。 macOS 的默认 SSH 客户端不支持 PPK 格式&#xff0c;你需要将 PPK 文…...

EXPLAIN 针对性优化 SQL 查询

在数据库管理和应用中&#xff0c;高效的 SQL 查询是确保系统性能的关键。随着数据量的不断增长和业务需求的日益复杂&#xff0c;优化 SQL 查询变得尤为重要。而 EXPLAIN 命令是一种强大的工具&#xff0c;可以帮助我们深入了解 SQL 查询的执行计划&#xff0c;从而进行有针对…...

MR30分布式IO:石化行业的智能化革新

在浩瀚的工业领域中&#xff0c;石化行业如同一座巨大的化工厂&#xff0c;将自然界的原始资源转化为人们日常生活中不可或缺的各种产品。然而&#xff0c;随着生产规模的扩大和工艺复杂度的提升&#xff0c;石化行业面临着前所未有的挑战&#xff1a;如何在保证生产效率的同时…...

linux图形化X窗口

【linux图形化协议框架】 X、X11系统&#xff1a;X协议&#xff0c;X服务器&#xff0c;窗口管理器&#xff0c;X客户端&#xff08;客户端库Xcb&#xff0c;Xlib库等&#xff09;&#xff0c;输入、绘制 Wayland系统&#xff1a;Wayland 协议&#xff0c;合成器、客户端&#…...

练习LabVIEW第三十五题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十五题&#xff1a; 使用labview模拟一个3-8译码器 开始编写&#xff1a; 用LabVIEW做3-8译码器首先要知道它是个啥…...