新闻详情

新闻详情

首页 / 资讯中心 / 详情

3D正方形颜色和信息展示练习

发布时间:2026/9/30 11:12:50来源:尧图网络
3D正方形颜色和信息展示练习
3D正方形颜色和信息展示练习一个小功能把知识点串起来使用写一个中间正方形模型我可以使用按钮改变它的颜色并且点击模型利用射线拾取获取模型信息弹框粗略的展示一下信息增加记忆点。涉及代码template div classcontainer div classdialogBox v-iftextShow div stylefont-size: 20px; font-weight: bold;margin: 5px 0;物体信息/div div选中物体: {{ selectedObject.name }}/div div选中物体位置: {{ selectedObject.position }}/div /div div classbtnBox div classbtn v-foritem in btnList :keyitem.name :style{ backgroundColor: item.color } clickhandleColorClick(item.color) {{ item.name }} /div /div /div /template script setup import { ref, onMounted } from vue; import * as THREE from three; import { OrbitControls } from three/examples/jsm/controls/OrbitControls; // 轨道控制器 let scene null; //场景 let camera null; //相机 let renderer null; //渲染器 let controls null; //控制器 const cubes []; const textShow ref(false); //是否显示弹框 const btnList ref([ { name: 红色, color: #ff0000, }, { name: 绿色, color: #00ff00, }, { name: 蓝色, color: #0000ff, }, ]); //按钮列表 import imgUrl from ../assets/img/backImg.png; const initThreeMap () { scene new THREE.Scene(); //场景 scene.background new THREE.Color(black); //设置场景背景色 const fog new THREE.Fog(0xffffff, 0.005, 1000); //雾 scene.fog fog; //添加雾 // 添加光源 const ambientLight new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); setCamera(); //设置相机 setRenderer(); //设置渲染器 initMesh(); //初始化网格 window.addEventListener(resize, () { //监听窗口大小变化 camera.aspect window.innerWidth / window.innerHeight; //设置相机纵横比 camera.updateProjectionMatrix(); //更新相机投影矩阵 renderer.setSize(window.innerWidth, window.innerHeight); //设置渲染器大小 }); setControls(); //设置控制器 }; const setCamera () { camera new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); //透视相机 camera.position.z 10; //设置相机位置 camera.position.y 5; //设置相机位置 camera.lookAt(0, 0, 0); //设置相机目标点 }; const setRenderer () { renderer new THREE.WebGLRenderer({ antialias: true }); //渲染器 renderer.setSize(window.innerWidth, window.innerHeight); //设置渲染器大小 // 【关键步骤1】开启渲染器的阴影映射功能 renderer.shadowMap.enabled true; // 可选使用柔和阴影边缘更自然 renderer.shadowMap.type THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); //将渲染器添加到页面中 }; let cubeMesh null; //立方体网格 const initMesh () { const cubeGeometry new THREE.BoxGeometry(3, 3, 3); //立方体 const cubeMaterial new THREE.MeshStandardMaterial({ color: 0xff0000, metalness: 0.5, roughness: 0.0, }); //材质 cubeMesh new THREE.Mesh(cubeGeometry, cubeMaterial); //网格 cubeMesh.position.set(0, 1.5, 2); //设置网格位置 cubeMaterial.transparent true; //设置透明度 // cubeMaterial.opacity 0.5; //设置透明度 cubeMesh.castShadow true; //设置网格投射阴影 cubeMesh.name 测试模型; //设置立方体网格名称 console.log(cubeMesh); const light new THREE.DirectionalLight(0xffffff, 2, 100); //点光源 light.position.set(0, 5, 10); //设置点光源位置 light.castShadow true; scene.add(light); //添加到场景 const lightHelper new THREE.DirectionalLightHelper(light, 1); // scene.add(lightHelper); // 4. 创建阴影接收平面 (地面) const planeGeometry new THREE.PlaneGeometry(20, 20); const planeMaterial new THREE.MeshStandardMaterial({ color: 0xcccccc, roughness: 0.8, metalness: 1, side: THREE.DoubleSide, }); const plane new THREE.Mesh(planeGeometry, planeMaterial); // 【关键步骤3】旋转平面使其水平 plane.rotation.x -Math.PI / 2; plane.position.y 0; // 位于 y0 高度 // 【关键步骤4】允许平面接收阴影 plane.receiveShadow true; scene.add(plane); scene.add(cubeMesh); //添加到场景 }; const raycaster new THREE.Raycaster(); //射线投射器 const mouse new THREE.Vector2(); //鼠标 let selectedObject ref(null); //选中物体 const handleClick (event) { // 获取 Canvas 在页面中的位置 const rect renderer.domElement.getBoundingClientRect(); console.log(rect , rect); // 计算归一化设备坐标 (NDC) mouse.x ((event.clientX - rect.left) / rect.width) * 2 - 1; mouse.y -((event.clientY - rect.top) / rect.height) * 2 1; checkIntersection(event); }; window.addEventListener(click, handleClick, false); const checkIntersection (event) { raycaster.setFromCamera(mouse, camera); const intersects raycaster.intersectObjects(scene.children, true); console.log(intersects , intersects); if (intersects.length 0) { console.log(选中物体:, intersects[0].object); textShow.value true; if (intersects[0].object.name 测试模型) { selectedObject.value intersects[0].object; } } }; const handleColorClick (color) { console.log(color); cubeMesh.material.color.set(color); cubeMesh.material.needsUpdate true; cubeMesh.name 测试模型: color; cubeMesh.color2 color; textShow.value false; }; const setControls () { controls new OrbitControls(camera, renderer.domElement); //控制器 controls.minPolarAngle 0; controls.maxPolarAngle Math.PI / 2; controls.enableDamping true; // 给控制器添加阻尼必须在动画循环里调用.update()。 controls.update(); //更新控制器 }; const animate () { requestAnimationFrame(animate); //请求动画帧 renderer.render(scene, camera); //渲染场景和相机 controls.update(); //更新控制器 }; onMounted(() { initThreeMap(); //初始化 animate(); //动画 }); /script style scoped .container { width: 100%; height: 100vh; position: relative; } .dialogBox { position: absolute; top: 30%; left: 50%; width: 400px; height: 100px; color: #000; background-color: #fff; z-index: 9999; } .btnBox { position: absolute; bottom: 80px; left: 50%; right: 50%; } .btn { display: inline-block; margin: 10px; width: 100px; height: 30px; line-height: 30px; text-align: center; border-radius: 5px; background-color: #ff0000; color: #fff; cursor: pointer; } /style
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SQLAlchemy ORM实战指南:从模型设计到查询优化与排坑 2026/9/30 11:58:54

SQLAlchemy ORM实战指南:从模型设计到查询优化与排坑

写SQLAlchemy之前,先聊聊我这几年的感受。Python世界里,如果你和数据库打过交道,SQLAlchemy ORM几乎是绕不开的名字。它不是一个简单的“python 连接数据库”库,而是一套完整的数据访问工具链,底层帮你处理连接池、SQL…

阅读更多 →
同城O2O系统架构实战:中台化设计与Kubernetes部署实践 2026/9/30 11:58:54

同城O2O系统架构实战:中台化设计与Kubernetes部署实践

做同城O2O系统架构这几年,我最大的感受是:真正难的不是某个接口怎么写,而是整条链路从下单到履约怎么在设计层面就保持清晰、可控、可扩展。你打开外卖App点一份餐,背后涉及用户、商家、支付、调度、骑手、售后等多个系统的协作&a…

阅读更多 →
使用Docker容器化Python应用:从Dockerfile到docker-compose实战 2026/9/30 11:58:54

使用Docker容器化Python应用:从Dockerfile到docker-compose实战

1. 为什么要用Docker来跑Python应用先说个我自己的经历。几年前我接了一个爬虫项目,本地跑得好好的,一到服务器上就各种报错。一会儿是Python版本不对,一会儿是缺少某个系统依赖库,最离谱的一次是对方服务器上已经装了Python 3.6&…

阅读更多 →
拖拽式H5编辑器部署实战:从Nginx托管到Docker交付 2026/9/30 11:58:20

拖拽式H5编辑器部署实战:从Nginx托管到Docker交付

做前端这行,最不缺的就是“帮我做个H5活动页”这种需求。市场部要一个秒杀页,产品经理要一个抽奖落地页,运营今天改文案明天换Banner,每次改起来比新建还慢。后来我给自己找了个一劳永逸的办法:部署一套拖拽式H5页面制…

阅读更多 →
ChatGPT 提示词工程实战:11 种 AI 指令把大模型变成你的私人学习教练 2026/9/30 11:58:18

ChatGPT 提示词工程实战:11 种 AI 指令把大模型变成你的私人学习教练

简介:这份docx文档收录了11个可直接套用的ChatGPT学习指令,聚焦思维导图、费曼技巧、精细提问、间隔重复、SQ3R法、双编码、类比隐喻、故事叙述、交错学习等主流高效学习法,适合需要借助AI辅助自学新技能、备考或系统攻克某一领域知识的学习者…

阅读更多 →
车辆路径优化实战:从TSP到VRP的Python求解指南 2026/9/30 11:58:18

车辆路径优化实战:从TSP到VRP的Python求解指南

最近在折腾一个配送调度的小项目,白天上班跟业务方对需求,晚上回家写算法,满脑子都是车辆路径优化这几个字。等我真正把一条条路线在图上铺开的时候,才发现车辆路径优化这件事,真的是既奇妙又折磨人。今天想从我的实战…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉