自学内容网 自学内容网

如何在 Three.js 场景中创建可点击展开的标签

在这里插入图片描述

在复杂的可视化场景中,经常需要为 3D 对象添加可交互的标签,以便用户点击时可以查看详细信息。这篇文章将通过一个简单的案例展示,如何在 Three.js 中为对象创建可点击的标签,点击标签可以展开详细信息,再次点击可以关闭这些信息。

实现思路
  1. 创建护罩对象:我们在 Three.js 中生成护罩(类似于 3D 球体),这些护罩将承载标签。
  2. 创建 2D 标签:使用 Three.js 的 CSS2DRenderer 创建 HTML 标签,并附加到护罩对象上。
  3. 实现点击交互:点击标签时,显示更多信息,再次点击时隐藏这些信息。
第一步:创建基本的 Three.js 场景

我们首先需要在项目中创建一个基本的 Three.js 场景,并在其中生成几个护罩对象。以下代码展示了如何设置 Three.js 场景和护罩:

import * as THREE from 'three'; 
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';

// 创建基本的 Three.js 场景
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 10);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(labelRenderer.domElement);

// 添加灯光
const ambientLight = new THREE.AmbientLight(0x404040, 2); 
scene.add(ambientLight);

// 创建护罩对象
const geometry = new THREE.SphereGeometry(1.5, 32, 32);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const shield = new THREE.Mesh(geometry, material);
scene.add(shield);

这个代码片段中,我们创建了一个基础的 Three.js 场景,设置了相机、灯光,并添加了一个简单的护罩对象(一个球体)。还初始化了一个 CSS2DRenderer 用于接下来渲染 HTML 标签。

第二步:为护罩添加 2D 标签

接下来,我们将使用 CSS2DRenderer 来为护罩添加一个标签。这个标签将包含护罩的名称,并且初始状态下显示基本信息,更多信息隐藏。

// 创建标签元素
const div = document.createElement('div');
div.className = 'label';
div.textContent = 'Shield 1';
div.style.fontSize = '14px';
div.style.color = 'white';
div.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
div.style.padding = '5px';
div.style.borderRadius = '5px';
div.style.cursor = 'pointer';

// 创建隐藏的详细信息元素
const moreContent = document.createElement('div');
moreContent.className = 'more-content';
moreContent.style.display = 'none';
moreContent.textContent = '更多关于 Shield 1 的内容...';
moreContent.style.marginTop = '5px';
moreContent.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
moreContent.style.color = 'black';
moreContent.style.padding = '10px';
moreContent.style.borderRadius = '5px';

// 将详细信息嵌入标签中
div.appendChild(moreContent);

// 为护罩添加点击事件,控制显示和隐藏详细信息
div.addEventListener('click', () => {
  moreContent.style.display = moreContent.style.display === 'none' ? 'block' : 'none';
});

// 创建 CSS2DObject,将标签附加到护罩上
const label = new CSS2DObject(div);
label.position.set(0, 2, 0); // 标签位置在护罩上方
shield.add(label);

在这段代码中,我们:

  1. 创建了 HTML 标签,并设置了样式,包括护罩名称和背景颜色。
  2. 创建了详细信息的部分,初始状态下隐藏。
  3. 通过点击事件实现了点击标签时展开或收起详细信息。
第三步:渲染场景并添加交互

最后,我们将把标签添加到 Three.js 的渲染循环中,同时确保标签随 3D 场景中的对象移动。

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  labelRenderer.render(scene, camera); // 渲染标签
}
animate();

现在,运行这个代码时,会看到一个带有标签的护罩对象。点击标签时,会显示详细信息,再次点击时会隐藏详细信息。

第四步:为什么标签没有显示在边缘?

生成的标签附加在护罩的顶部,护罩的分布范围可能会限制标签在屏幕中的可见位置。在我们的项目中,护罩是以屏幕中心为基准进行分布,因此没有分布到屏幕边缘。为了将护罩分布得更广,可以调整护罩的位置逻辑,确保护罩覆盖到屏幕的边缘区域。

总结

在这篇文章中,我们展示了如何使用 Three.js 的 CSS2DRenderer 为 3D 场景中的对象添加 2D 标签,并实现点击显示或隐藏详细信息的交互效果。这个功能可以应用于各种 3D 数据可视化场景中,为用户提供直观的交互体验。

ps:最近的项目使用three.js的地方很多,且拓展了很多功能,我会将一个个的功能点拆分出来。因为之前查找相关博客发现很多都是整个一起的,对于只想要其中一部分而言会增加很多不必要的时间成本,所以我会将功能点拆解出来。想了解更多关于three.js的文章可以看我的three专栏

跳转连接:【Three.js】实现护罩(防御罩、金钟罩、护盾)效果


原文地址:https://blog.csdn.net/wanghaoyingand/article/details/141997679

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!