关于three.js中添加文字的方式[转]
https://blog.csdn.net/qq563969790/article/details/76584976
网上资料大部分是通过引入外部font库进行文字效果的载入,但是在实际运行的时候发现非常占用资源。于是不得不想另一种方法。
于是想到了three.js中的粒子系统。这当中有个很gay的骚操作是下面这个函数。
var particleMaterial = new THREE.SpriteCanvasMaterial( {
color: 0x000000,
program: function ( context ) {
context.beginPath();
context.font="bold 20px Arial";
context.fillStyle="#058";
context.transform(-1,0,0,1,0,0);
context.rotate(Math.PI);
context.fillText( wordFont , 0, 0 );
}
上面的函数当中,可以传入一个canvas对象。恩,对。如果你想载入文字,写到canvas里就够啦,你还可以画小h图哦。
附上源代码:
ps:代码中最后的注释部分是外部加载字体的方式。有知道的大神请告诉我这么loader为啥贼卡。还有为什么context中文字fillText初始是镜像倒转的?又费了一点劲给它倒腾回来。可能涉及到坐标的原因,同样希望大神告知。
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js measute_length</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Arial;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/Projector.js"></script>
<script src="js/CanvasRenderer.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/stats.min.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var particleMaterial;
var raycaster;
var mouse;
var objects = [];
var points = [];
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 400, 700 );
scene = new THREE.Scene();
var geometry = new THREE.BoxGeometry( 100, 100, 100 );
for ( var i = 0; i < 10; i ++ ) {
var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
object.position.x = Math.random() * 800 - 400;
object.position.y = Math.random() * 800 - 400;
object.position.z = Math.random() * 800 - 400;
object.scale.x = Math.random() * 2 + 1;
object.scale.y = Math.random() * 2 + 1;
object.scale.z = Math.random() * 2 + 1;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
scene.add( object );
objects.push( object );
}
var PI2 = Math.PI * 2;
particleMaterial = new THREE.SpriteCanvasMaterial( {
color: 0x000000,
program: function ( context ) {
context.beginPath();
context.arc( 0, 0, 0.5, 0, PI2, true );
context.fill();
}
} );
raycaster = new THREE.Raycaster();
mouse = new THREE.Vector2();
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
window.addEventListener( 'resize', onWindowResize, false );
var controls = new THREE.OrbitControls(camera); //camera control
controls.addEventListener('change', render);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentTouchStart( event ) {
event.preventDefault();
event.clientX = event.touches[0].clientX;
event.clientY = event.touches[0].clientY;
onDocumentMouseDown( event );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
//射线原理拾取目标
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
//创建粒子,便于标识点击位置
var particle = new THREE.Sprite( particleMaterial );
particle.position.copy( intersects[ 0 ].point );
particle.scale.x = particle.scale.y = 1;
scene.add( particle );
//保存选中点
points.push( intersects[ 0 ].point );
if( points.length >1 ) {
var p2 = points[points.length-1];
var p1 = points[points.length-2];
//动画的形式画线
drawLine( p1, p2);
}
}
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
renderer.render( scene, camera );
}
function drawLine( p1, p2) {
var directionVector = new THREE.Vector3();
var p3 = new THREE.Vector3();
directionVector.x = p2.x - p1.x;
directionVector.y = p2.y - p1.y;
directionVector.z = p2.z - p1.z;
var length = Math.sqrt( directionVector.x * directionVector.x
+ directionVector.y * directionVector.y
+ directionVector.z * directionVector.z);
var text = Math.round( length ) + "m";
var flag = 1;
var id = setInterval(function () {
if (flag == 11) {
clearInterval(id);
flag = 1;
} else {
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { opacity:1,color:0x000000 } );
geometry.vertices.push(p1);
p3.x = p1.x + (directionVector.x/10) * flag;
p3.y = p1.y + (directionVector.y/10) * flag;
p3.z = p1.z + (directionVector.z/10) * flag;
geometry.vertices.push(p1);
geometry.vertices.push(p3);
var geo = new THREE.Line(geometry, material);
scene.add(geo);
flag++;
}
}, 10);
initText( text, p2 );
}
// var font;
// var loader = new THREE.FontLoader();
// loader.load('js/optimer_bold.typeface.json',function(response) {
// font = response;
// });
function initText( wordFont, p1){
var particleMaterial = new THREE.SpriteCanvasMaterial( {
color: 0x000000,
program: function ( context ) {
context.beginPath();
context.font="bold 20px Arial";
context.fillStyle="#058";
context.transform(-1,0,0,1,0,0);
context.rotate(Math.PI);
context.fillText( wordFont , 0, 0 );
}
} );
var particle = new THREE.Sprite( particleMaterial );
particle.position.copy( p1 );
particle.rotation.x = Math.PI/2;
// particle.lookAt( camera );
scene.add( particle );
// var textGeometry = new THREE.TextGeometry(wordFont,{
// "font": font,
// "size" : 10,
// "height" : 0,
// "color" : 0x000000
// })
//
// var text = new THREE.Mesh( textGeometry, new THREE.MeshBasicMaterial( { color: 0x000000 } ) );
//
//
// text.position.x = p1.x + 2;
// text.position.y = p1.y + 2;
// text.position.z = p1.z + 2;
// text.lookAt(camera.position);
// scene.add(text);
}
</script>
</body>
</html>
效果如下:
用到threejs的 精灵材料(SpriteMaterial)
https://threejs.org/docs/index.html#api/zh/materials/SpriteMaterial
下面的属性可以帮助我们实现文字在屏幕上大小不随像机位置变化而放缩!
.sizeAttenuation : Boolean ----标识文字是否自动放缩(false为屏幕尺寸自动放缩)
精灵的大小是否会被相机深度衰减。(仅限透视摄像头。)默认为true。
关于three.js中添加文字的方式[转]的更多相关文章
- html css <input> javaScript .数据类型 JS中的函数编写方式 BOM总结 DOM总结
Day27 html css div 块标签. 特点: 独占一行,有高度和宽度 span 行元素. 特点:在同一行显示,当前行满了自动去下一行显示. 不识别高度和宽度 1.1.1.1 2.输入域标签 ...
- 基础篇:1.JavaScript运行在html中,引用有几种方式?—— 6.js中常用的输出方式?
书接上文,上文提到若干条JavaScript的基础性知识,大部分都是一些概念性的东西,本着认真严谨的态度,我们要认真对待,有些条目的问题是某个知识点的周边延伸,为节约篇幅,就一起整理了,如有描述不对的 ...
- WPF 在绘图控件(Shape)中添加文字 [2018.7.15]
原文:WPF 在绘图控件(Shape)中添加文字 [2018.7.15] Q:使用Shape的子类Ellipse画一个圆,如何在圆中添加文字? A:Shape类中不包含Text属性.可使用Shape类 ...
- OSG项目经验2<在场景中添加文字面版>
添加文字版需要用到osg的三个名字空间: osgText::Text,这个类用来添加文字和设置文字的一些属性: ...
- FFmpeg 向视频中添加文字
原文地址:http://www.cnblogs.com/wanggang123/p/6707985.html FFmpeg支持添加文字功能,具体如何将文字叠加到视频中的每一张图片,FFmpeg调用了文 ...
- Ffmpeg 视频教程 向视频中添加文字
Ffmpeg支持添加文字功能,具体如何将文字叠加到视频中的每一张图片,FFmpeg调用了文字库FreeSerif.ttf.当我们 用到ffmpeg 添加文字功能时 我们需要先下载改文字库,下载地址是h ...
- C# Excel 中设置文字对齐方式、方向和换行
在Excel表格中输入文字时,我们常常需要调整文字对齐方式或者对文字进行换行.本文将介绍如何通过编程的方式设置文字对齐方式,改变文字方向以及对文字进行换行. //创建Workbook对象 Workbo ...
- 一道面试题关于js中添加动态属性
js中数据类型包含基本数据类型和引用类型,基本类型包括:string.null.undefined.number.boolean.引用类型即是对象比如:array .function以及自定义对象等 ...
- bootstrap table 生成的表格里动态添加HTML元素按钮,JS中添加点击事件,点击没反应---解决办法
bootstraptable中onExpandRow属性---js 方法添加的 html代码,然后给这代码里面的 元素 添加 事件,却获取不该元素.(称之为未来元素),由于是未来的 所以现在没有这个 ...
随机推荐
- input text 去掉标签下拉提示
autocomplete 属性 autocomplete 属性规定输入字段是否应该启用自动完成功能. 自动完成允许浏览器预测对字段的输入.当用户在字段开始键入时,浏览器基于之前键入过的值,应该显示出在 ...
- Java String str = new String(value)和String str = value区别
示例代码: public class StringDemo2 { public static void main(String[] args) { String s1 = new String(&qu ...
- oracle中主键自增
oracle中主键自增 下面用一个例子来说明自增主键的创建: 1.建用户数据表 drop table dectuser; create table dectuser( userid integer p ...
- 【C++ Primer 第7章】定义抽象数据类型
参考资料 1. C++Primer #7 类 Sales_data类 Sales_data.h #include<iostream> #include<string> clas ...
- 使用SqlSugar 4.X的T4生成实体类
<#@ template debug="false" hostspecific="true" language="C#" #> ...
- springbank 开发日志 springbank是如何执行一个handler的requestMapping对应的方法的
占位 从dispatcher说起,方法doDispatch(Map request)的参数request是一个通过解析来报报文新城的map //获取HandlerExecutionChain,其中封装 ...
- POJ 2718【permutation】
POJ 2718 问题描述: 给一串数,求划分后一个子集以某种排列构成一个数,余下数以某种排列构成另一个数,求这两个数最小的差,注意0开头的处理. 超时问题:一开始是得到一个数列的组合之后再从中间进行 ...
- 【UER #1】DZY Loves Graph(待卡常数)
题解: 正解是可持久化并查集 但这个显然是lct可以维护的 但这常数是个问题啊??? #include <bits/stdc++.h> using namespace std; struc ...
- tomcat启动慢解决方案
一.环境 centos6.7 tomcat8 jdk1.8 二.现象 启动tomcat会花费10多分钟,正常情况下几秒就可以了. 三.解决办法 度娘了一下是因为jdk在生成随机数上耗时,找到j ...
- php中$this->是什么意思
$this 的含义是表示 实例化后的 具体对象! 我们一般是先声明一个类,然后用这个类去实例化对象! 但是,当我们在声明这个类的时候,想在类本身内部使用本类的属性或者方法.应该怎么表示呢? 例如 ...