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

three.js 鼠标选中模型弹出标签

效果:请关注抖音


 

代码:

<template><div><el-container><el-main><div class="box-card-left"><div id="threejs" style="border: 1px solid red;position: relative;"></div></div></el-main></el-container></div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
// 效果制作器
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
// 渲染通道
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
// 发光描边OutlinePass
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js";
import { CSS2DObject, CSS2DRenderer } from "three/examples/jsm/renderers/CSS2DRenderer.js";export default {data() {return {name: "",scene: null,camera: null,renderer: null,css2DRenderer: null,effectComposer: null,mesh: null,geometry: null,group: null,material: null,texture: null,position: null,outlinePass: null,canvasWidth: 1000,canvasHeight: 800,color: [],meshArr: [],};},created() {},mounted() {this.name = this.$route.query.name;this.init();},methods: {goBack() {this.$router.go(-1);},init() {// 思路:有六个模型,分别代表人的头,身体,左右手臂,左右腿;当点击某一个模型时,高亮,并且显示标签名称this.scene = new this.$three.Scene();const axesHelper = new this.$three.AxesHelper(300);this.scene.add(axesHelper);this.group = new this.$three.Group();this.group.translateY(150);this.creatMesh_tou();this.creatMesh_body();this.creatMesh_hand();this.creatMesh_foot();this.scene.add(this.group);// 创建相机对象this.camera = new this.$three.PerspectiveCamera(60,1,0.01,2000);this.camera.position.set(300,300,300);this.camera.lookAt(0,0,0);// 创建渲染器对象this.renderer = new this.$three.WebGLRenderer();this.renderer.setSize(this.canvasWidth, this.canvasHeight);this.renderer.render(this.scene, this.camera);window.document.getElementById("threejs").appendChild(this.renderer.domElement);// this.css2DRenderer = new CSS2DRenderer();this.css2DRenderer.setSize(this.canvasWidth, this.canvasHeight);this.css2DRenderer.render(this.scene, this.camera);this.css2DRenderer.domElement.style.position = "absolute";this.css2DRenderer.domElement.style.top = 0;this.css2DRenderer.domElement.style.pointerEvents = 'none';window.document.getElementById("threejs").appendChild(this.css2DRenderer.domElement);// 创建空间轨道控制器对象const controls = new OrbitControls(this.camera, this.renderer.domElement);controls.addEventListener("change", () => {this.renderer.render(this.scene, this.camera);})this.rayCasterFn();this.effectComposerFn();},renderFun() {// 调用后处理对象的render方法进行渲染,this.effectComposer.render();this.css2DRenderer.render(this.scene, this.camera);window.requestAnimationFrame(this.renderFun);},rayCasterFn() {// 画布添加事件监听document.getElementById("threejs").addEventListener("click", e => {this.scene.traverse(one => {if(one.isCSS2DObject) {this.scene.remove(one);}})// 坐标转换const p_x = e.offsetX;const p_y = e.offsetY;const x = (p_x / this.canvasWidth) * 2 - 1;const y = -(p_y / this.canvasHeight) * 2 + 1;// 创建射线拾取器对象const raycaster = new this.$three.Raycaster();// 射线计算raycaster.setFromCamera(new this.$three.Vector2(x, y), this.camera);// 射线交叉计算const intersects = raycaster.intersectObjects(this.group.children);if(intersects.length > 0) {let obj = intersects[0].object;this.outlinePass.selectedObjects = [obj];let dom = this.createDiv(obj.name);let css2_obj = new CSS2DObject(dom);const wp = new this.$three.Vector3();obj.getWorldPosition(wp)css2_obj.position.set(wp.x, wp.y, wp.z);this.scene.add(css2_obj);this.renderFun();} else {this.outlinePass.selectedObjects = [];}})},effectComposerFn() {// 创建后处理对象this.effectComposer = new EffectComposer(this.renderer);// 创建后处理通道const renderPass = new RenderPass(this.scene, this.camera);this.effectComposer.addPass(renderPass);// 创建发光描边对象this.outlinePass = new OutlinePass(new this.$three.Vector2(this.canvasWidth, this.canvasHeight), this.scene, this.camera);this.outlinePass.edgeStrength = 20;this.outlinePass.edgeThickness = 5;this.outlinePass.visibleEdgeColor.set(0xffaadd);this.outlinePass.pulsePeriod = 2;this.effectComposer.addPass(this.outlinePass);},createDiv(name) {let dom = document.createElement("div");dom.style.padding = '5px 10px';dom.style.border = '1px solid skyblue';dom.style.color = 'red';dom.style.background = '#2FF885';dom.style.borderRadius = '15px';dom.innerHTML = name;// dom.innerHTML = "龙年大吉";return dom;},creatMesh_tou() {const geometry = new this.$three.SphereGeometry(30,64,64);const material = new this.$three.MeshBasicMaterial({color: 0xdfdf});const mesh = new this.$three.Mesh(geometry, material);mesh.name = "头";this.group.add(mesh);},creatMesh_body() {const geometry = new this.$three.BoxGeometry(50,100,80);const material = new this.$three.MeshBasicMaterial({color: 0xdaafdf});const mesh = new this.$three.Mesh(geometry, material);mesh.translateY(-80);mesh.name = "身体";this.group.add(mesh);},creatMesh_hand() {const geometry = new this.$three.BoxGeometry(10,10,120);const material = new this.$three.MeshBasicMaterial({color: 0x11afdf});const mesh = new this.$three.Mesh(geometry, material);mesh.translateY(-60);mesh.translateZ(-100);mesh.name = "右手";this.group.add(mesh);const mesh2 = mesh.clone();mesh2.translateZ(200);mesh2.name = "左手";this.group.add(mesh2);},creatMesh_foot() {const geometry = new this.$three.BoxGeometry(10,190,10);const material = new this.$three.MeshBasicMaterial({color: 0xD63DF0});const mesh = new this.$three.Mesh(geometry, material);mesh.translateY(-220);mesh.translateZ(-30);mesh.name = "右腿";this.group.add(mesh);const mesh2 = mesh.clone();mesh2.translateZ(60);mesh2.name = "左腿";this.group.add(mesh2);},},
};
</script>
//
<style lang="less" scoped>
.box-card-left {display: flex;align-items: flex-start;flex-direction: row;position: relative;width: 100%;.box-right {img{width:500px;user-select: none;}}
}
</style>

相关文章:

  • Spring Boot3整合Druid(监控功能)
  • 极简Matlab快速傅里叶变换FFT
  • 顶顶通呼叫中心中间件机器人压力测试配置(mod_cti基于FreeSWITCH)
  • Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
  • 缓存技术—redis
  • 网络安全03---Nginx 解析漏洞复现
  • LightDB 24.1 UNION支持null类型匹配
  • 光明之盒:揭开可解释性人工智能的神秘面纱
  • 一种解决常用存储设备无法被电脑识别的方法
  • 【开源】基于JAVA语言的二手车交易系统
  • js中的内置对象、数学对象、日期对象、数组对象、字符串对象
  • spark-flink设计思想之吸星大法-1
  • jQuery HTML - 设置 —— W3school 详解 简单易懂(十二)
  • 【go】Ubuntu 22.04 LTS golang go-ethereum编译安装
  • C#使用TimeSpan对象获取时间间隔
  • 「面试题」如何实现一个圣杯布局?
  • Date型的使用
  • JavaScript新鲜事·第5期
  • k8s如何管理Pod
  • MySQL的数据类型
  • node-glob通配符
  • php面试题 汇集2
  • Python3爬取英雄联盟英雄皮肤大图
  • session共享问题解决方案
  • Spring核心 Bean的高级装配
  • tweak 支持第三方库
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 程序员最讨厌的9句话,你可有补充?
  • 官方解决所有 npm 全局安装权限问题
  • 提醒我喝水chrome插件开发指南
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​香农与信息论三大定律
  • $.ajax()
  • (09)Hive——CTE 公共表达式
  • (31)对象的克隆
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (二)学习JVM —— 垃圾回收机制
  • (六)激光线扫描-三维重建
  • (论文阅读40-45)图像描述1
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)C#调用WebService 基础
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .net Application的目录
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core WebAPI中封装Swagger配置
  • .NET DataGridView数据绑定说明
  • .Net Web窗口页属性
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NET开源项目介绍及资源推荐:数据持久层
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递