资讯专栏INFORMATION COLUMN

three.js 实现立体几何的文本标签

Hancock_Xu / 2013人阅读

摘要:最近在做一个基于实现立体几何的项目,碰到一个问题,如何给球体加上文字标签,探索了几种实现方法。

最近在做一个基于three.js实现立体几何的项目,碰到一个问题,如何给球体加上文字标签,探索了几种实现方法。

二维文字标签

1.通过CSS2DObject创建二维对象

var earthDiv = document.createElement( "div" );
earthDiv.className = "label";
earthDiv.textContent = "Earth";
earthDiv.style.marginTop = "-1em";
var earthLabel = new CSS2DObject( earthDiv );
earthLabel.position.set( 0, EARTH_RADIUS, 0 );
earth.add( earthLabel );
var moonDiv = document.createElement( "div" );
moonDiv.className = "label";
moonDiv.textContent = "Moon";
moonDiv.style.marginTop = "-1em";
var moonLabel = new CSS2DObject( moonDiv );
moonLabel.position.set( 0, MOON_RADIUS, 0 );
moon.add( moonLabel );

2.利用CSS2DRenderer将二维对象append到dom节点中,CSS2DRenderer会将所有的CSS2DObject(HTMLELEMENT)包裹在一个div容器,append到dom节点中

labelRenderer = new CSS2DRenderer();
labelRenderer.setSize( window.innerWidth, window.innerHeight );
labelRenderer.domElement.style.position = "absolute";
labelRenderer.domElement.style.top = 0;
document.body.appendChild( labelRenderer.domElement );

3.效果图(来源于官网demo, 其中moom和earth为文字标签)

4.使用场景及局限

用于标记整个立体几何,不适用于标记立体几何的局部位置

三维文字标签

基于三维空间中物体的灵活性,三维文字标签满足了标记立体几何局部位置的需求。
实现思路:

由于Sprite是一个总是面朝着摄像机的平面,很贴合标签的使用场景,选择其作为标签的原形;

文字的实现有两种方式: textGeometry和canvasTexture贴图,textGeometry实际上渲染出立体的文字,成本较高;而canvas的方式较轻量,本文采用了后者。

文字和Sprite组合起来则成为三维文字标签,通过position即可定位到标记的地方

1.离屏canvas测量文本的width(用于确定实际canvas的宽度)

const offScreenCanvas = document.createElement("canvas");
const offScreenCtx = offScreenCanvas.getContext("2d");
offScreenCtx.font = "14px 黑体";
const txt = "标签";
const textWidth = offScreenCtx.measureText(txt).width;

2.绘制文字到canvas中作为texture

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const txt = "标签";
if (ctx !== null) {
canvas.width = (textWidth + padding 2) pixelRatio;
canvas.height = 18 * pixelRatio;
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
ctx.font = "14px 黑体";
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, textWidth + padding * 2, 18);
ctx.fillStyle = "#000";
ctx.fillText(txt, padding, 14);
}
const texture = new THREE.CanvasTexture(canvas);

3.渲染Sprite

const spriteMaterial = new THREE.SpriteMaterial( { map: texture, sizeAttenuation: false } );
const label = new THREE.Sprite( spriteMaterial );
const scaleY = 0.1;
const scaleX = scaleY * canvas.width / canvas.height;
label.position.copy(vertice);
// sprite默认会令canvas变形 需要通过scale调整比例
label.scale.set(scaleX, scaleY, 1);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105591.html

相关文章

  • three.js 入门详解(一)

    摘要:一般说来,对于制图建模软通常使正交投影,这样不会因为投影而改变物体比例而对于其他大多数应用,通常使用透视投影,因为这更接近人眼的观察效果。 showImg(https://segmentfault.com/img/remote/1460000012581680?w=1920&h=1080); 1. 概述 1.1 什么是WebGL? WebGL是在浏览器中实现三维效果的一套规范 想要使用...

    468122151 评论0 收藏0
  • three.js 入门详解(一)

    摘要:一般说来,对于制图建模软通常使正交投影,这样不会因为投影而改变物体比例而对于其他大多数应用,通常使用透视投影,因为这更接近人眼的观察效果。 showImg(https://segmentfault.com/img/remote/1460000012581680?w=1920&h=1080); 1. 概述 1.1 什么是WebGL? WebGL是在浏览器中实现三维效果的一套规范 想要使用...

    Jacendfeng 评论0 收藏0
  • 【连载】前端个人文章整理-从基础到入门

    摘要:个人前端文章整理从最开始萌生写文章的想法,到着手开始写,再到现在已经一年的时间了,由于工作比较忙,更新缓慢,后面还是会继更新,现将已经写好的文章整理一个目录,方便更多的小伙伴去学习。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 个人前端文章整理 从最开始萌生写文章的想法,到着手...

    madthumb 评论0 收藏0
  • 【连载】前端个人文章整理-从基础到入门

    摘要:个人前端文章整理从最开始萌生写文章的想法,到着手开始写,再到现在已经一年的时间了,由于工作比较忙,更新缓慢,后面还是会继更新,现将已经写好的文章整理一个目录,方便更多的小伙伴去学习。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 个人前端文章整理 从最开始萌生写文章的想法,到着手...

    Labradors 评论0 收藏0
  • three.js中文文档 1.创建场景

    摘要:创建场景标签本节目标是为做简介。我们从使用旋转立方体来搭建场景开始。我们现在创建了场景,摄像机和渲染器。我们需要来创建立方体。这会导致摄像机和立方体内部重叠。这会创建一个让渲染器每秒绘制一帧的循环。结果恭喜你现在创建好了第一个应用。 1.创建场景 标签: three.js 本节目标是为 three.js 做简介。我们从使用旋转立方体来搭建场景开始。如果遇到困难需要帮助,页面底部有可参考...

    Michael_Lin 评论0 收藏0

发表评论

0条评论

Hancock_Xu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<