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>

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

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

相关文章

202410读书笔记|《半小时漫画青春期》——成为自己世界的星星,这才是最要紧的事儿

202410读书笔记|《半小时漫画青春期&#xff1a;心理篇》——成为自己世界的星星&#xff0c;这才是最要紧的事儿 一、一到考试就焦虑&#xff0c;怎么办&#xff1f;二、以前情绪挺淡定&#xff0c;现在咋动不动就爆发&#xff1f;三、追星那么开心&#xff0c;为啥还要我小心…

ajax点击搜索返回所需数据

html 中body设置&#xff08;css设置跟进自身需求&#xff09; <p idsearch_head>学生信息查询表</p> <div id"div_1"> <div class"search_div"> <div class"search_div_item"> …

数据库设计的一些原则

文章目录 数据库设计原则表之间的关系一对一关系&#xff08;了解&#xff09;一对多&#xff08;多对一&#xff09;多对多联合主键和复合主键 数据库设计准则-范式1、函数依赖2、完全函数依赖3、部分函数依赖4、传递函数依赖5、码 第一范式第二范式第三范式第三范式 数据库设…

【原神游戏开发日志3】登录和注册有何区别?

版权声明&#xff1a; ● 本文为“优梦创客”原创文章&#xff0c;您可以自由转载&#xff0c;但必须加入完整的版权声明 ● 文章内容不得删减、修改、演绎 ● 本文视频版本&#xff1a;见文末 ● 相关学习资源&#xff1a;见文末 前言 ● 这是我们原神游戏开发日记的第三期 ●…

TensorFlow2实战-系列教程1:回归问题预测

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、环境测试 import tensorflow as tf import numpy as np tf.__version__打印结果 ‘…

2024年材料、控制工程与制造技术国际学术会议(ICMCEMT 2024)

2024年材料、控制工程与制造技术国际学术会议(ICMCEMT 2024) 2024 International Conference on Materials, Control Engineering, and Manufacturing Technology (ICMCEMT 2024) 会议简介&#xff1a; 2024年材料、控制工程与制造技术国际学术会议(ICMCEMT 2024)定于2024年在…

分布式因果推断在美团履约平台的探索与实践

美团履约平台技术部在因果推断领域持续的探索和实践中&#xff0c;自研了一系列分布式的工具。本文重点介绍了分布式因果树算法的实现&#xff0c;并系统地阐述如何设计实现一种分布式因果树算法&#xff0c;以及因果效应评估方面qini_curve/qini_score的不足与应对技巧。希望能…

ERROR Failed to get response from https://registry.npm.taobao.org/ 错误的解决

这个问题最近才出现的。可能跟淘宝镜像的证书到期有关。 解决方式一&#xff1a;更新淘宝镜像&#xff08;本人测试无效&#xff0c;但建议尝试&#xff09; 虽然无效&#xff0c;但感觉是有很大关系的。还是设置一下比较好。 淘宝镜像的地址&#xff08;registry.npm.taobao…

【计算机网络】协议,电路交换,分组交换

定义了在两个或多个通信实体之间交换的报文格式和次序,以及报文发送和/或接收一个报文或其他事件所采取的动作.网络边缘: 端系统 (因为处在因特网的边缘) 主机 端系统 客户 client服务器 server今天大部分服务器都属于大型数据中心(data center)接入网(access network) 指将端…

Visual Studio 2022 C++ 生成dll或so文件在windows或linux下用C#调用

背景 开发中我们基本使用windows系统比较快捷&#xff0c;但是部署的时候我们又希望使用linux比较便宜&#xff0c;硬件产商还仅提供了c sdk&#xff01;苦了我们做二次开发的码农。 方案 需要确认一件事&#xff0c;目前c这门语言不是跨平台的 第一个问题【C生成dll在window…

nav02 学习03 机器人传感器

机器人传感器 移动机器人配备了大量传感器&#xff0c;使它们能够看到和感知周围的环境。这些传感器获取的信息可用于构建和维护环境地图、在地图上定位机器人以及查看环境中的障碍物。这些任务对于能够安全有效地在动态环境中导航机器人至关重要。 机器人的传感器类似人的感官…

二极管漏电流对单片机ad采样偏差的影响

1&#xff0c;下图是常规的单片机采集电压电路&#xff0c;被测量电压经过电阻分压&#xff0c;给到mcu采集&#xff0c;反向二极管起到钳位作用&#xff0c;避免高压打坏mcu。 2&#xff0c;该电路存在的问题 二极管存在漏电流&#xff0c;会在100k电阻上产生叠加电压&#x…

qt 坦克大战游戏 GUI绘制

关于本章节中使用的图形绘制类&#xff0c;如QGraphicsView、QGraphicsScene等的详细使用说明请参见我的另一篇文章&#xff1a; 《图形绘制QGraphicsView、QGraphicsScene、QGraphicsItem、Qt GUI-CSDN博客》 本文将模仿坦克大战游戏&#xff0c;目前只绘制出一辆坦克&#…

Oracle RAC 集群的安装(保姆级教程)

文章目录 一、安装前的规划1、系统规划2、网络规划3、存储规划 二、主机配置1、Linux主机安装&#xff08;rac01&rac02&#xff09;2、配置yum源并安装依赖包&#xff08;rac01&rac02&#xff09;3、网络配置&#xff08;rac01&rac02&#xff09;4、存储配置&#…

c语言实现—动态通讯录

一.前言 上次带大家认识了一下顺序表&#xff0c;其实我们可以在顺序表的基础上实现一个通讯录的小项目&#xff0c;通讯录的本质仍然是顺序表&#xff0c;所以如果下面的代码你有问题的话&#xff0c;先去看看我的上篇文章哦~。 通讯录的功能大家应该都知道吧&#xff0c;这次…

chroot: failed to run command ‘/bin/bash’: No such file or directory

1. 问题描述及原因分析 在busybox的环境下&#xff0c;执行 cd rootfs chroot .报错如下&#xff1a; chroot: failed to run command ‘/bin/bash’: No such file or directory根据报错应该rootfs文件系统中缺少/bin/bash&#xff0c;进入查看确实默认是sh&#xff0c;换成…

【微信小程序】浮动按钮拖动功能

在开发过程中无意间想到了这个功能。一番查询之后找到这个功能相关的代码片段。拷贝过来之后各种报错&#xff0c;经过自己的整改以可以使用。 功能图片&#xff1a; 中间的微信按钮可以拖动 wxml&#xff1a;页面代码 <button catchtouchmove"buttonMove" cat…

五、Kotlin 函数进阶

1. 高阶函数 1.1 什么是高阶函数 以下 2 点至少满足其一的函数称为高阶函数&#xff1a; 形参列表中包含函数类型的参数 //参数 paramN 可以是&#xff1a;函数引用、函数类型变量、或 Lambda 表达式。 fun funName(param1: Type1, param2: Type2, ... , paramN: (p1: T1, p2…

2.数据结构 顺序表(自留笔记)

文章目录 一.静态顺序表&#xff1a;长度固定二.动态顺序表1.下面证明原地扩容和异地扩容代码如下&#xff1a;2.下面是写一段Print&#xff0c;打印数字看看&#xff1a;3.头插4.尾删5.头删6.越界一定会报错吗7.下标插入8.下标删除9.查找数字10.应用&#xff1a;利用顺序表写一…

Linux:用户切换指令su

相关文章 Linux专栏https://blog.csdn.net/weixin_45791458/category_12234591.html su是一个常用的用户切换命令&#xff0c; 用于在不同的用户身份之间切换&#xff0c;下面是它的用法。 用法&#xff1a; su [-] [-lmpVh] [-s shell] [-c command] [-w list] [username] 选…