Threejs之場景標注標簽信息CSS2DRenderer

參考資料

  • CSS2DRenderer(HTML標簽)
  • 單擊按鈕關閉HTML標簽

知識點

注:基于Three.jsv0.155.0

  • CSS2DRenderer(HTML標簽)
  1. HTML標簽遮擋Canvas畫布事件
  2. Canvas尺寸變化(HTML標簽)
  3. 標簽位置不同設置方式
  4. 標簽位置(標注工廠設備)
  5. 標簽指示線或箭頭指向標注點
  6. 鼠標選中模型彈出標簽(工廠)
  7. 單擊按鈕關閉HTML標簽

總體思路

  • 1.HTML元素創建標簽
  • 2.CSS2模型對象CSS2DObject
  • 3.CSS2渲染器CSS2DRenderer
  • 4.CSS2Renderer.domElement重新定位

代碼實現

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Three.js</title>
</head><body><div id="container"></div><div id="tag">標簽內容</div></body><!-- 具體路徑配置,你根據自己文件目錄設置,我的是課件中源碼形式 --><script type="importmap">{"imports": {"three": "./js/three.module.js","three/addons/": "../three.js/examples/jsm/"}}</script><script type="module">import * as THREE from 'three';import { CSS2DRenderer,CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';import {OrbitControls} from 'three/addons/controls/OrbitControls.js';const width = 800const height = 500// 場景const scene = new THREE.Scene();const geometry = new THREE.BoxGeometry(25, 100, 50);geometry.translate(0, 50, 0);// 材質const material = new THREE.MeshBasicMaterial({color: 0x00ff00,transparent: true,});// mesh頂部中心添加標注,頂部中心坐標是(0,100,0)const mesh = new THREE.Mesh(geometry, material);scene.add(mesh);// mesh設置一個父對象meshGroupconst meshGroup = new THREE.Group();meshGroup.add(mesh);// mesh位置受到父對象局部坐標.positionn影響meshGroup.position.x = -100;scene.add(meshGroup);// 環境光const ambientLight = new THREE.AmbientLight( 0xffffff, 0.2);scene.add( ambientLight );// 坐標系const axes = new THREE.AxesHelper(200);scene.add(axes);const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);camera.position.set(200, 200, 200);camera.lookAt(scene.position);// 渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);// renderer.setClearColor(0x000000, 0.5);renderer.render(scene, camera);// 渲染器背景透明document.body.appendChild(renderer.domElement);// 標簽const div = document.getElementById('tag');// HTML元素轉化為threejs的CSS2模型對象const tag = new CSS2DObject(div);// tag.position.set(-50,0,50);// const worldPosition = new THREE.Vector3();// mesh.getWorldPosition(worldPosition);// tag.position.copy(worldPosition);// scene.add(tag);mesh.add(tag);scene.add(mesh);const pos = geometry.attributes.position;// 獲取幾何體頂點1的xyz坐標,設置標簽局部坐標.position屬性tag.position.set(pos.getX(0),pos.getY(0),pos.getZ(0));const group = new THREE.Group();// 最后meshGroup和tag放在同一個父對象中即可group.add(meshGroup,tag);scene.add(group);// 創建一個CSS2渲染器CSS2DRendererconst css2Renderer = new CSS2DRenderer();css2Renderer.setSize(width, height);css2Renderer.render(scene, camera);document.body.appendChild(css2Renderer.domElement);css2Renderer.domElement.style.position = 'absolute';css2Renderer.domElement.style.top = '0';// renderer.domElement.style.marginTop = '200px';// css2Renderer.domElement.style.top = '200px';css2Renderer.domElement.style.color = 'red';css2Renderer.domElement.style.fontSize = '20px';css2Renderer.domElement.style.pointerEvents  = 'none';renderer.domElement.style.zIndex  = -1;css2Renderer.domElement.style.zIndex  = 1;// 控制器const controls = new OrbitControls(camera, renderer.domElement);controls.addEventListener('change', () => {// 因為動畫渲染了,所以這里可以省略renderer.render(scene, camera);});// 畫布跟隨窗口變化window.onresize = function () {const width = window.innerWidth;const height = window.innerHeight;// cnavas畫布寬高度重新設置renderer.setSize(width,height);// HTML標簽css2Renderer.domElement尺寸重新設置css2Renderer.setSize(width,height);camera.aspect = width / height;camera.updateProjectionMatrix();};</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Three.js</title>
</head><body><div id="container"></div><div id="tag">標簽內容</div></body><!-- 具體路徑配置,你根據自己文件目錄設置,我的是課件中源碼形式 --><script type="importmap">{"imports": {"three": "./js/three.module.js","three/addons/": "../three.js/examples/jsm/"}}</script><script type="module">import * as THREE from 'three';import { CSS2DRenderer,CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';import {OrbitControls} from 'three/addons/controls/OrbitControls.js';const width = 800const height = 500// 場景const scene = new THREE.Scene();const geometry = new THREE.ConeGeometry(25, 80);// 材質const material = new THREE.MeshBasicMaterial({color: 0x00ff00,transparent: true,});const mesh = new THREE.Mesh(geometry, material);// 可視化模型的局部坐標系scene.add(mesh);// 環境光const ambientLight = new THREE.AmbientLight( 0xffffff, 0.2);scene.add( ambientLight );// 坐標系const axes = new THREE.AxesHelper(200);scene.add(axes);const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);camera.position.set(200, 200, 200);camera.lookAt(scene.position);// 渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);// renderer.setClearColor(0x000000, 0.5);renderer.render(scene, camera);// 渲染器背景透明document.body.appendChild(renderer.domElement);// 標簽const div = document.getElementById('tag');// HTML元素轉化為threejs的CSS2模型對象const tag = new CSS2DObject(div);mesh.add(tag);// scene.add(tag);//y軸正方向,平移高度一半geometry.translate(0, 40, 0); //圓錐mesh局部坐標系原點在自己底部時候,標簽需要向上偏移圓錐自身高度tag.position.y += 40; // 創建一個CSS2渲染器CSS2DRendererconst css2Renderer = new CSS2DRenderer();css2Renderer.setSize(width, height);css2Renderer.render(scene, camera);document.body.appendChild(css2Renderer.domElement);css2Renderer.domElement.style.position = 'absolute';css2Renderer.domElement.style.top = '0';css2Renderer.domElement.style.color = 'red';css2Renderer.domElement.style.fontSize = '20px';// 控制器const controls = new OrbitControls(camera, renderer.domElement);controls.addEventListener('change', () => {// 因為動畫渲染了,所以這里可以省略renderer.render(scene, camera);});// 畫布跟隨窗口變化window.onresize = function () {const width = window.innerWidth;const height = window.innerHeight;// cnavas畫布寬高度重新設置renderer.setSize(width,height);// HTML標簽css2Renderer.domElement尺寸重新設置css2Renderer.setSize(width,height);camera.aspect = width / height;camera.updateProjectionMatrix();};</script>
</html>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718092.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718092.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718092.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Microsoft PyRIT能自動化完成AI紅隊的任務

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

兩數相加的問題

題目是&#xff1a;給兩個非空的鏈表&#xff0c;表示兩個非負整數。它們每位數都是按照逆序的方式存儲&#xff0c;并且每一個節點只能存儲一位數字。現在兩個數相加&#xff0c;并且以相同的形式返回一個表示和的鏈表。 首先回顧一下&#xff0c;什么是鏈表&#xff1f;鏈表…

《異常檢測——從經典算法到深度學習》26 Time-LLM:基于大語言模型的時間序列預測

《異常檢測——從經典算法到深度學習》 0 概論1 基于隔離森林的異常檢測算法 2 基于LOF的異常檢測算法3 基于One-Class SVM的異常檢測算法4 基于高斯概率密度異常檢測算法5 Opprentice——異常檢測經典算法最終篇6 基于重構概率的 VAE 異常檢測7 基于條件VAE異常檢測8 Donut: …

使用遞歸方法和類數組兩種方法計算斐波那契數列

菲波納契數列又稱"菲波納契神奇數列"&#xff0c;是由13世紀的意大利數學家菲波納契提出的&#xff0c;當時是和兔子的繁殖問題有關的&#xff0c;它是一個很重要的數學模型。這個問題是:有小兔一對&#xff0c;若第二個月它們成年&#xff0c;第三個月生下小兔一對&…

3333666777

? 通用計算機啟動過程 1??一個基礎固件&#xff1a;BIOS 一個基礎固件&#xff1a;BIOS→基本IO系統&#xff0c;它提供以下功能&#xff1a; 上電后自檢功能 Power-On Self-Test&#xff0c;即POST&#xff1a;上電后&#xff0c;識別硬件配置并對其進行自檢&#xff0c…

阿里云倉庫

倉庫服務 (aliyun.com) maven中央倉庫&#xff1a; Central Repository: (maven.org)

Windows10 安裝Neo4j流程

1、下載并安裝ava運行環境 官網鏈接&#xff08;需要注冊Oracle賬號&#xff09;&#xff1a;https://www.oracle.com/java/technologies/downloads/ 根據自己Neo4j版本確認需要的JDK版本 百度網盤鏈接&#xff1a; 鏈接&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/…

靜態網頁和動態網頁的異同

靜態網頁和動態網頁是兩種不同類型的網頁。它們之間的主要異同點如下&#xff1a; 1. 靜態網頁&#xff1a; - 靜態網頁是指在服務器上預先準備好的網頁&#xff0c;內容固定不變。 - 靜態網頁通常由HTML、CSS和JavaScript等靜態文件組成。 - 用戶訪問靜態網頁時&#xff0c…

Sodinokibi勒索病毒最新變種,解密工具更新到2.0版本

Sodinokibi勒索病毒 Sodinokibi勒索病毒又稱REvil&#xff0c;自從2019年6月1日&#xff0c;GandCrab勒索病毒運營團伙宣布停止運營之后&#xff0c;Sodinokibi勒索病毒馬上接管了GandCrab的大部分傳播渠道&#xff0c;同時它也被稱為是GandCrab勒索病毒的“接班人”&#xff…

VMware 虛擬機安裝windows 10操作系統

先提前準備好鏡像文件 1.創建新的虛擬機 2.選擇自定義&#xff0c;然后下一步 v Windows 建議選擇2G以上&#xff0c;下一步 選擇網絡地址轉換&#xff08;NAT&#xff09;&#xff0c;下一步 這里可按自己的需求來分區&#xff0c;也可以安裝好后再分區 選擇立即重啟&#xff…

【劍指offer】C++ 翻轉字符串里面的單詞

目錄 題目: 思路: 代碼出現 結果 題目: 給定一個字符串,逐個翻轉字符串中的每個單詞。 示例 1: 輸入: "the sky is blue" 輸出: "blue is sky the" 示例 2: 輸入: " hello world! " 輸出: "world! hello" 解釋: 輸入字符…

L1-032 Left-pad(PTA)

文章目錄 L1-032 Left-pad題目描述代碼 L1-032 Left-pad 題目描述 根據新浪微博上的消息&#xff0c;有一位開發者不滿NPM&#xff08;Node Package Manager&#xff09;的做法&#xff0c;收回了自己的開源代碼&#xff0c;其中包括一個叫left-pad的模塊&#xff0c;就是這個…

使用 Object.defineProperty() 來進行數據劫持有什么缺點?

使用 Object.defineProperty() 來進行數據劫持有什么缺點&#xff1f; &#xff08;1&#xff09;在對一些屬性進行操作時&#xff0c;使用這種方法無法攔截&#xff0c;比如通過下標方式修改數組數據或者給對象新增屬性&#xff0c;這都不能觸發組件的重新渲染&#xff0c;因為…

Vue組件置底方法,ElementPlus布局

問題描述 在開發網頁時使用了elementplus的el-container組件 組件里分成了main和footer兩塊&#xff0c;但是想要將兩個按鈕置底在容器底部遇到了困難 如下圖所示&#xff0c;在網頁開發者工具可見兩個按鈕與左側的圖片沒有底部對齊 此時我的代碼是這樣 <el-footer>&…

STM32自學?串口發送+接收

一、相關函數說明&#xff1a; USART_ClockInit()和USART_ClockStructInit(); 用來配置同步時鐘輸出 USART_DMACmd(); 開啟USART到DMA的觸發通道 USART_SendData(); 發送數據 USART_ReceiveData(); 接收數據 二、程序代碼 serial.c文件 #include "stm32f10x.h" #i…

文件底層的深入理解之文件輸入輸出重定向

目錄 一、文件fd的分配規則 二、對輸出重定向現象的理解 三、輸出輸入重定向的簡單實現 1、輸出重定向 2、輸入重定向 一、文件fd的分配規則 最小的沒有被使用的數組下標&#xff0c;會被分配給最新打開的文件。 二、對輸出重定向現象的理解 正如上面這段代碼所示&#xff0…

C語言實現日本某地發生了一件謀殺案

題目 猜兇手 題目內容&#xff1a; 日本某地發生了一件謀殺案&#xff0c;警察通過排查確定殺人兇手必為4個嫌疑犯的一個。 以下為4個嫌疑犯的供詞: A說&#xff1a;不是我。 B說&#xff1a;是C。 C說&#xff1a;是D。 D說&#xff1a;C在胡說 已知3個人說了真話&…

從零開始學習Netty - 學習筆記 -Netty入門【半包,黏包】

Netty進階 1.黏包半包 1.1.黏包 服務端代碼 public class HelloWorldServer {private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());public static void main(String[] args) {NioEventLoopGroup bossGroup new NioEventL…

Ubuntu上Jenkins自動化部署Gitee上VUE項目

文章目錄 1.安裝NodeJS插件2.配置全局工具配置-NodeJS環境變量3.新建自由風格的軟件項目任務4.配置General配置丟棄舊的構建配置參數化構建過程 5.配置源碼管理6.構建觸發器7.設置構建環境8.配置構建步驟9.配置構建后操作10測試構建 前文鏈接&#xff1a; Ubuntu上Jenkins自動…