three.js CSS2DRenderer、CSS2DObject渲染HTML标签

 有空的老铁关注一下我的抖音:

效果:

<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();
      // 调用方法创建盒模型 1
      this.careateBox1();
      // 调用方法创建盒模型 2
      this.careateBox2();
      this.createCone();
      // 创建辅助坐标轴对象
      const axesHelper = new this.$three.AxesHelper(200);
      this.scene.add(axesHelper);
      // 创建透视投影相机对象
      this.camera = new this.$three.PerspectiveCamera(60,1,0.01, 2000);
      // 设置相机位置
      this.camera.position.set(200,200,200);
      // 设置相机指向
      this.camera.lookAt(0,0,0);
      // 创建WebGL渲染器对象
      this.renderer = new this.$three.WebGLRenderer();
      // 设置渲染器渲染的尺寸
      this.renderer.setSize(1000,800);
      // 调用渲染器的render方法开始渲染,参数是 场景,相机 对象
      this.renderer.render(this.scene, this.camera);
      // 获取id 是 threejs 的元素并添加domElement
      window.document.getElementById("threejs").appendChild(this.renderer.domElement);
      // 创建 CSS2D 渲染器对象(主要:)
      this.css2DRenderer = new CSS2DRenderer();
      this.css2DRenderer.setSize(1000,800);
      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);

      this.renderFun();
      // 创建空间轨道控制器对象
      const controls = new OrbitControls(this.camera, this.renderer.domElement);
      controls.addEventListener("change", () => {
        this.renderer.render(this.scene, this.camera);
      })
    },
    // 创建一个盒模型,父组件是 scene 场景;盒模型设置了位置
    careateBox1() {
      // 创建立方缓存几何体对象
      this.geometry = new this.$three.BoxGeometry(50,50,60);
      // 创建网格基础材质对象
      this.material = new this.$three.MeshBasicMaterial({
        color: 0xfafa,
      });
      // 创建网格对象
      this.mesh = new this.$three.Mesh(this.geometry, this.material);
      // 设置网格对象位置
      this.mesh.position.set(-50,60,60);
      // 调用方法创建html元素
      let dom = this.createDiv("父对象是Scene的模型的标签");
      // 创建 CSS2DObject对象,参数是html元素,作用:将html元素转为threejs的css2模型对象
      const tag = new CSS2DObject(dom);
      // 创建Vector3对象
      const wp = new this.$three.Vector3();
      // 获得this.mesh的世界坐标
      this.mesh.getWorldPosition(wp);
      tag.position.set(wp.x, wp.y, wp.z);
      // this.mesh.add(tag);
      this.scene.add(this.mesh);
      this.scene.add(tag);
    },
    // 创建一个盒模型,父组件是 组对象,盒模型与组对象都设置了位置
    careateBox2() {
      const group = new this.$three.Group();
      group.position.set(30,0,0);
      const geometry = new this.$three.BoxGeometry(50,50,60);
      const material = new this.$three.MeshBasicMaterial({
        color: 0xfaf33a,
      });
      const mesh = new this.$three.Mesh(geometry, material);
      // 网格模型设置了位置,且父对象是组对象,这样css2模型对象添加到mesh中后,会直接继承mesh的世界坐标
      mesh.position.set(50,60,-60);
      let dom = this.createDiv("父对象是Group的模型标签");
      const obj = new CSS2DObject(dom);
      mesh.add(obj);
      group.add(mesh);
      this.scene.add(group);
    },
    // 标注模型几何体的某个顶点
    createCone() {
      // 创建圆锥缓冲几何体对象
      const coneGeometry = new this.$three.ConeGeometry(20,100,32);
      // 创建材质对象
      const material = new this.$three.MeshBasicMaterial({
        color: 0xffaadd
      });
      // 创建网格模型对象
      const cone_mesh = new this.$three.Mesh(coneGeometry, material);
      const pos = coneGeometry.attributes.position;
      const dom = this.createDiv("我是圆锥的标注标签");
      const tag = new CSS2DObject(dom);
      cone_mesh.add(tag);
      cone_mesh.translateY(50); // 圆锥几何体Y轴平移50
      tag.position.y += 50; //  css2模型对象
      this.scene.add(cone_mesh);

    },
    createDiv(innerText='盒子模型标签') {
      let dom = window.document.createElement("div");
      dom.innerHTML = innerText;
      dom.style.border = '1px solid blue';
      dom.style.height = '20px';
      dom.style.color = '#0A58F6';
      dom.style.padding = '5px 10px';
      dom.style.borderRadius = "5px";
      dom.style.top = '-20px';
      dom.style.background = "#F7F2EE";
      return dom;
    },
    renderFun() {
      this.renderer.render(this.scene, this.camera);
      this.css2DRenderer.render(this.scene, this.camera);
      window.requestAnimationFrame(this.renderFun);
    },
  },
};
</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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django响应(一)

一、HttpResponse与JsonResponse 1.1、HttpResponse 官网:https://docs.djangoproject.com/zh-hans/4.1/ref/request-response/#django.http.HttpResponse 返回给浏览器端的响应对象 from django.http import HttpResponse response = HttpResponse("Heres the text o…

数据结构+算法(第09篇):菜鸟也能“种”好二叉树!

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

2023年网信办约谈了上万家网站

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 网信办发布公告&#xff1a; 网信办在共约谈网站 10646 家;责令 453 家网站暂停功能或更新;下架移动应用程序 259 款;关停小程序 119 款;取消违法网站许可或备案、关闭违法网站 14624 家;关闭违法违规账号 127878 个…

windows 谷歌浏览器Chrome 怎么禁止更新

1.首先把任务管理器里的谷歌浏览器程序结束&#xff1a; &#xff08;鼠标在任务栏右击&#xff0c;出现任务管理器&#xff09; 2.windowr&#xff0c;输入services.msc 带有Google Update的服务&#xff0c;选择禁用。 3.windowr&#xff0c;输入taskschd.msc 任务计划程序…

CTF-WEB进阶与学习

PHP弱类型 在进行比较的时候&#xff0c;会先判断两种字符串的类型是否相等&#xff0c;再比较 在进行比较的时候&#xff0c;会先将字符串类型转化成相同&#xff0c;再比较 如果比较一个数字和字符串或者比较涉及到数字内容的字符串&#xff0c;则字符串会被转换成数值 并且…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--大模型、扩散模型、视觉

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起…

如何分辨坏信息?

每当有社会热点&#xff0c;大家也许都会遇到一个困扰&#xff1a; 铺天盖地的信息&#xff0c;实在是太多了。究竟哪一些值得信任&#xff0c;哪些不值得信任&#xff1f;哪些可以接受&#xff0c;哪些最好保持怀疑&#xff1f; 我想用这篇文章&#xff0c;彻底把这个问题讲清…

day32 买卖股票的最佳时机Ⅱ 跳跃游戏 跳跃游戏Ⅱ

题目1&#xff1a;122 买卖股票的最佳时机Ⅱ 题目链接&#xff1a;122 买卖股票的最大时机Ⅱ 题意 整数数组prices[i]表示某股票的第i天的价格&#xff0c;每天可买卖股票且最多持有1股股票&#xff0c;返回最大利润 利润拆分&#xff0c;拆分为每天的利润 每天的正利…

【演讲比赛流程管理系统(C++版)】

一、演讲比赛程序需求 1.1、比赛规则 学校举行一场演讲比赛&#xff0c;共有12个人参加。比赛共两轮&#xff0c;第一轮为淘汰赛&#xff0c;第二轮为决赛 每名选手都有对应的编号&#xff0c;如10001~10012 比赛方式:分组比赛&#xff0c;每组6个人 第一轮分为两个小组&a…

银行数据仓库体系实践(18)--数据应用之信用风险建模

信用风险 银行的经营风险的机构&#xff0c;那在第15节也提到了巴塞尔新资本协议对于银行风险的计量和监管要求&#xff0c;其中信用风险是银行经营的主要风险之一&#xff0c;它的管理好坏直接影响到银行的经营利润和稳定经营。信用风险是指交易对手未能履行约定契约中的义务而…

力扣热门100题刷题笔记 - 2.两数相加

力扣热门100题 - 2.两数相加 题目链接&#xff1a;2.两数相加 题目描述&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。请你将两个数相加&#xff0c;并以相同形式返…

Python入门到精通(七)——Python文件操作

Python文件操作 一、文件的编码 二、文件的读取 1、操作汇总 2、model 常用的三种基础访问模式 三、文件的写入 四、文件的追加 五、综合案例 一、文件的编码 1、什么是编码&#xff1f; 编码就是一种规则集合&#xff0c;记录了内容和二进制间进行相互转换的逻辑。编…

强化学习 - Monte Carlo Tree Search (MCTS)

什么是机器学习 强化学习中的Monte Carlo Tree Search (MCTS) 是一种用于决策制定和搜索的算法&#xff0c;特别在不确定环境下表现出色。 1. 强化学习背景 在强化学习中&#xff0c;一个智能体通过与环境的交互学习&#xff0c;以便在某个任务上获得最大的奖励。MCTS是一种…

01- k8s基础网络知识 之 underlay与overlay网络

前言&#xff1a; 我们在学习k8s网络之前&#xff0c;必须要了解k8s网络相关的一些基础知识&#xff0c;比如什么是underlay网络、overlay网络等&#xff0c;只有把基础知识掌握之后&#xff0c;后续学习k8s网络的时候&#xff0c;一些知识点就不会再云里雾里了。 1 underlay与…

关于字符串处理

文章目录 关于字符串处理1、取字符串的长度2、跳过前面的字符3、取字符串右边的字符4、掐头去尾5、取倒数的范围6、删左留右7、删右留左8、查找替换9、大小写转换 关于字符串处理 1、取字符串的长度 [rootlocalhost ~]#strabcd1128 #定义变量 [rootlocalhost ~]#echo ${#str}…

React实现组件扩展机制

在java中&#xff0c;SPI机制是Java中提供的一种服务发现机制。同样&#xff0c;前端也很需要这种机制&#xff0c;这样可以做到组件可插拔&#xff0c;可替换&#xff0c;减少相互冗余。 快速使用 1.扩展点使用 通过使用Extension组件定义扩展点&#xff0c;通过name标记扩展…

血细胞分类项目

血细胞分类项目 数据集&#xff1a;血细胞分类数据集数据处理 dataset.py网络 net.py训练 train.py拿训练集的几张图进行预测 数据集&#xff1a;血细胞分类数据集 https://aistudio.baidu.com/datasetdetail/10278 数据处理 dataset.py from torchvision import transfor…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起…

Task05:PPO算法

本篇博客是本人参加Datawhale组队学习第五次任务的笔记 【教程地址】https://github.com/datawhalechina/joyrl-book 【强化学习库JoyRL】https://github.com/datawhalechina/joyrl/tree/main 【JoyRL开发周报】 https://datawhale.feishu.cn/docx/OM8fdsNl0o5omoxB5nXcyzsInGe…

【QT+QGIS跨平台编译】之二十二:【FontConfig+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、FontConfig介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、FontConfig介绍 FontConfig 是一个用于配置和定制字体的库&#xff0c;广泛应用于基于X Window系统的操作系统中&#xff0c;尤其是在Linux和Unix-like系统中。它为应用程序提供了一种统一的…