參考資料
- CSS2DRenderer(HTML標簽)
- …
- 單擊按鈕關閉HTML標簽
知識點
注:基于Three.jsv0.155.0
- CSS2DRenderer(HTML標簽)
- HTML標簽遮擋Canvas畫布事件
- Canvas尺寸變化(HTML標簽)
- 標簽位置不同設置方式
- 標簽位置(標注工廠設備)
- 標簽指示線或箭頭指向標注點
- 鼠標選中模型彈出標簽(工廠)
- 單擊按鈕關閉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>