ThreeJs如何给模型打上文字标签?
Posted IT飞牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreeJs如何给模型打上文字标签?相关的知识,希望对你有一定的参考价值。
一、概述
ThreeJs渲染中创建的网格模型,有时候我们需要给模型添加标签文字,方便识别不同的物体。
这时候我们可以使用CSS3DRenderer
、CSS2DRenderer
这两个库,里面提供了三种打标签的方式,随着相机角度的变化,三种标签的显示效果各不相同。
三种标签分别是: CSS 2DObject、CSS 3DObject 标签、CSS 3DSprite 标签
二、效果预览
1、角度不同
下面是从不同角度看同一组模型时的显示效果:
2、距离不同
这是前后两组模型的显示效果:
3、区别简述
可以看到,CSS 2DObject
、CSS 3DSprite
都可以让标签永远正对当前相机视角。不同的是,CSS 2DObject
标签的尺寸不会受远近影响;CSS 3DSprite
标签的尺寸受远近影响,远小近大;
CSS 3DObject
标签朝向固定,不会随视角变化而改变,就仿佛是创建的模型对象,但实际这三种标签都是使用html+css
来实现的,并且CSS 3DObject
标签的大小也会受远近影响,远小近大。
三、代码实现
tag2D.js【创建CSS2DObject】
import CSS2DRenderer, CSS2DObject from 'three/examples/jsm/renderers/CSS2DRenderer.js';
// 创建一个HTML标签
function tag(name)
// 创建div元素(作为标签)
var div = document.createElement('div');
div.innerHTML = name;
div.classList.add('tag');
//div元素包装为CSS2模型对象CSS2DObject
var label = new CSS2DObject(div);
div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
// 设置HTML元素标签在three.js世界坐标中位置
// label.position.set(x, y, z);
return label;//返回CSS2模型标签
// 创建一个CSS2渲染器CSS2DRenderer
function labelRenderer(container)
var labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(container.offsetWidth, container.offsetHeight);
labelRenderer.domElement.style.position = 'absolute';
// 相对标签原位置位置偏移大小
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.left = '0px';
// //设置.pointerEvents=none,以免模型标签HTML元素遮挡鼠标选择场景模型
labelRenderer.domElement.style.pointerEvents = 'none';
container.appendChild(labelRenderer.domElement);
return labelRenderer;
export tag, labelRenderer
tag3D.js【创建CSS3DObject ,CSS3DSprite】
import CSS3DRenderer, CSS3DObject ,CSS3DSprite from 'three/examples/jsm/renderers/CSS3DRenderer.js';
// 创建一个HTML标签
function tag3D(name)
// 创建div元素(作为标签)
var div = document.createElement('div');
div.innerHTML = name;
div.classList.add('tag');
//div元素包装为CSS3模型对象CSS3DObject
var label = new CSS3DObject(div);
div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
// 设置HTML元素标签在three.js世界坐标中位置
// label.position.set(x, y, z);
//缩放CSS3DObject模型对象
label.scale.set(0.2, 0.2, 0.2);//根据相机渲染范围控制HTML 3D标签尺寸
label.rotateY(Math.PI / 2);//控制HTML标签CSS3对象姿态角度
// label.rotateX(-Math.PI/2);
return label;//返回CSS3模型标签
// 创建一个HTML标签
function tag3DSprite(name)
// 创建div元素(作为标签)
var div = document.createElement('div');
div.innerHTML = name;
div.classList.add('tag');
//div元素包装为CSS3模型对象CSS3DSprite
var label = new CSS3DSprite(div);
div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
// 设置HTML元素标签在three.js世界坐标中位置
// label.position.set(x, y, z);
//缩放CSS3DSprite模型对象
label.scale.set(0.2, 0.2, 0.2);//根据相机渲染范围控制HTML 3D标签尺寸
label.rotateY(Math.PI / 2);//控制HTML标签CSS3对象姿态角度
// label.rotateX(-Math.PI/2);
return label;//返回CSS3模型标签
// 创建一个CSS2渲染器CSS2DRenderer
function labelRenderer(container)
var labelRenderer = new CSS3DRenderer();
labelRenderer.setSize(container.offsetWidth, container.offsetHeight);
labelRenderer.domElement.style.position = 'absolute';
// 相对标签原位置位置偏移大小
labelRenderer.domElement.style.top = '0px';
labelRenderer.domElement.style.left = '0px';
// //设置.pointerEvents=none,以免模型标签HTML元素遮挡鼠标选择场景模型
labelRenderer.domElement.style.pointerEvents = 'none';
container.appendChild(labelRenderer.domElement);
return labelRenderer;
export tag3D, tag3DSprite, labelRenderer
Box.ts【创建模型+标签】
import * as THREE from "three"
import initRenderer from "./core/renderer";
import model from "./core/model";
import initScene from "./core/scene";
import labelRenderer as labelRenderer2D, tag as tag2D from "./core/tag2D";
import labelRenderer as labelRenderer3D, tag3D, tag3DSprite from "./core/tag3D";
class Box
private scene;
private camera;
private renderer;
private container;
constructor(container)
this.container = container;
this.scene = new THREE.Scene();
this.init();
init()
// 初始化渲染器和相机
let renderer, camera, render = initRenderer( scene: this.scene, container: this.container, labelRenderer2D: labelRenderer2D(this.container), labelRenderer3D: labelRenderer3D(this.container) );
this.renderer = renderer;
this.camera = camera;
this.renderer.setClearColor("black");
// 初始化场景
initScene( scene: this.scene, container: this.container, renderer: this.renderer, camera: this.camera );
//初始化模型
this.initObjects();
// 开始渲染
render();
//绘制
initObjects()
const box = new THREE.BoxGeometry(30, 30, 30);
const material = new THREE.MeshLambertMaterial(
color: 0x0000ff
)
// --------------------模型1
const mesh1 = new THREE.Mesh(box, material);
mesh1.position.z = 30;
mesh1.position.x = 30;
box.translate(0, 15, 0)
this.scene.add(mesh1);
// 添加CSS 2DObject标签
var label2D = tag2D("CSS 2DObject 标签");//设置标签名称
var pos1 = new THREE.Vector3();
mesh1.getWorldPosition(pos1);//获取obj世界坐标、
pos1.y += 30;
label2D.position.copy(pos1);//标签标注在obj世界坐标
this.scene.add(label2D);//标签插入场景
// --------------------模型2
const mesh2 = mesh1.clone();
mesh2.position.x = 100;
this.scene.add(mesh2);
// 添加CSS 3DObject标签
var label3D = tag3D("CSS 3DObject 标签");//设置标签名称
var pos2 = new THREE.Vector3();
mesh2.getWorldPosition(pos2);//获取obj世界坐标、
pos2.y += 30;
label3D.position.copy(pos2);//标签标注在obj世界坐标
this.scene.add(label3D);//标签插入场景
// --------------------模型3
const mesh3 = mesh1.clone();
mesh3.position.z = 100;
this.scene.add(mesh3);
// 添加CSS 3DSprite标签
var label3DSprite = tag3DSprite("CSS 3DSprite 标签");//设置标签名称
var pos3 = new THREE.Vector3();
mesh3.getWorldPosition(pos3);//获取obj世界坐标、
pos3.y += 30;
label3DSprite.position.copy(pos3);//标签标注在obj世界坐标
this.scene.add(label3DSprite);//标签插入场景
export default Box;
render.ts【设置渲染器】
import * as THREE from "three";
import createCamera from "./camera";
const initRenderer = function (context)
let scene, labelRenderer2D, labelRenderer3D = context;
let camera, renderer = createCamera(context);
// 渲染
const render = () =>
renderer.render(scene, camera);
labelRenderer2D.render(scene, camera); //渲染HTML标签对象 CSS2DObject 标签
labelRenderer3D.render(scene, camera); //渲染HTML标签对象 CSS3DObject 标签
//监听鼠标、键盘事件
requestAnimationFrame(render);
return camera, renderer, render ;
export default initRenderer;
四、源码
前往标签demo源码
以上是关于ThreeJs如何给模型打上文字标签?的主要内容,如果未能解决你的问题,请参考以下文章